2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.structures.JalviewStructureDisplayI;
24 import jalview.bin.Cache;
25 import jalview.datamodel.Alignment;
26 import jalview.datamodel.AlignmentAnnotation;
27 import jalview.datamodel.AlignmentI;
28 import jalview.datamodel.PDBEntry;
29 import jalview.datamodel.SequenceI;
30 import jalview.datamodel.StructureViewerModel;
31 import jalview.datamodel.StructureViewerModel.StructureData;
32 import jalview.schemabinding.version2.AlcodMap;
33 import jalview.schemabinding.version2.Alcodon;
34 import jalview.schemabinding.version2.AlcodonFrame;
35 import jalview.schemabinding.version2.Annotation;
36 import jalview.schemabinding.version2.AnnotationColours;
37 import jalview.schemabinding.version2.AnnotationElement;
38 import jalview.schemabinding.version2.CalcIdParam;
39 import jalview.schemabinding.version2.DBRef;
40 import jalview.schemabinding.version2.Features;
41 import jalview.schemabinding.version2.Group;
42 import jalview.schemabinding.version2.HiddenColumns;
43 import jalview.schemabinding.version2.JGroup;
44 import jalview.schemabinding.version2.JSeq;
45 import jalview.schemabinding.version2.JalviewModel;
46 import jalview.schemabinding.version2.JalviewModelSequence;
47 import jalview.schemabinding.version2.MapListFrom;
48 import jalview.schemabinding.version2.MapListTo;
49 import jalview.schemabinding.version2.Mapping;
50 import jalview.schemabinding.version2.MappingChoice;
51 import jalview.schemabinding.version2.OtherData;
52 import jalview.schemabinding.version2.PdbentryItem;
53 import jalview.schemabinding.version2.Pdbids;
54 import jalview.schemabinding.version2.Property;
55 import jalview.schemabinding.version2.Sequence;
56 import jalview.schemabinding.version2.SequenceSet;
57 import jalview.schemabinding.version2.SequenceSetProperties;
58 import jalview.schemabinding.version2.Setting;
59 import jalview.schemabinding.version2.StructureState;
60 import jalview.schemabinding.version2.ThresholdLine;
61 import jalview.schemabinding.version2.Tree;
62 import jalview.schemabinding.version2.UserColours;
63 import jalview.schemabinding.version2.Viewport;
64 import jalview.schemes.AnnotationColourGradient;
65 import jalview.schemes.ColourSchemeI;
66 import jalview.schemes.ColourSchemeProperty;
67 import jalview.schemes.GraduatedColor;
68 import jalview.schemes.ResidueColourScheme;
69 import jalview.schemes.ResidueProperties;
70 import jalview.schemes.UserColourScheme;
71 import jalview.structure.StructureSelectionManager;
72 import jalview.structures.models.AAStructureBindingModel;
73 import jalview.util.MessageManager;
74 import jalview.util.Platform;
75 import jalview.util.jarInputStreamProvider;
76 import jalview.viewmodel.AlignmentViewport;
77 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
78 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
79 import jalview.ws.jws2.Jws2Discoverer;
80 import jalview.ws.jws2.dm.AAConSettings;
81 import jalview.ws.jws2.jabaws2.Jws2Instance;
82 import jalview.ws.params.ArgumentI;
83 import jalview.ws.params.AutoCalcSetting;
84 import jalview.ws.params.WsParamSetI;
86 import java.awt.Rectangle;
87 import java.io.BufferedReader;
88 import java.io.DataInputStream;
89 import java.io.DataOutputStream;
91 import java.io.FileInputStream;
92 import java.io.FileOutputStream;
93 import java.io.IOException;
94 import java.io.InputStreamReader;
95 import java.io.OutputStreamWriter;
96 import java.io.PrintWriter;
97 import java.lang.reflect.InvocationTargetException;
98 import java.net.MalformedURLException;
100 import java.util.ArrayList;
101 import java.util.Enumeration;
102 import java.util.HashMap;
103 import java.util.HashSet;
104 import java.util.Hashtable;
105 import java.util.IdentityHashMap;
106 import java.util.Iterator;
107 import java.util.LinkedHashMap;
108 import java.util.List;
109 import java.util.Map;
110 import java.util.Map.Entry;
111 import java.util.Set;
112 import java.util.StringTokenizer;
113 import java.util.Vector;
114 import java.util.jar.JarEntry;
115 import java.util.jar.JarInputStream;
116 import java.util.jar.JarOutputStream;
118 import javax.swing.JInternalFrame;
119 import javax.swing.JOptionPane;
120 import javax.swing.SwingUtilities;
122 import org.exolab.castor.xml.Unmarshaller;
125 * Write out the current jalview desktop state as a Jalview XML stream.
127 * Note: the vamsas objects referred to here are primitive versions of the
128 * VAMSAS project schema elements - they are not the same and most likely never
132 * @version $Revision: 1.134 $
134 public class Jalview2XML
137 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
138 * of sequence objects are created.
140 IdentityHashMap<SequenceI, String> seqsToIds = null;
143 * jalview XML Sequence ID to jalview sequence object reference (both dataset
144 * and alignment sequences. Populated as XML reps of sequence objects are
147 Map<String, SequenceI> seqRefIds = null;
149 Vector frefedSequence = null;
151 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
154 * create/return unique hash string for sq
157 * @return new or existing unique string for sq
159 String seqHash(SequenceI sq)
161 if (seqsToIds == null)
165 if (seqsToIds.containsKey(sq))
167 return seqsToIds.get(sq);
171 // create sequential key
172 String key = "sq" + (seqsToIds.size() + 1);
173 key = makeHashCode(sq, key); // check we don't have an external reference
175 seqsToIds.put(sq, key);
184 if (seqRefIds != null)
188 if (seqsToIds != null)
198 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
199 // seqRefIds = new Hashtable();
200 // seqsToIds = new IdentityHashMap();
206 if (seqsToIds == null)
208 seqsToIds = new IdentityHashMap<SequenceI, String>();
210 if (seqRefIds == null)
212 seqRefIds = new HashMap<String, SequenceI>();
220 public Jalview2XML(boolean raiseGUI)
222 this.raiseGUI = raiseGUI;
225 public void resolveFrefedSequences()
227 if (frefedSequence.size() > 0)
229 int r = 0, rSize = frefedSequence.size();
232 Object[] ref = (Object[]) frefedSequence.elementAt(r);
235 String sref = (String) ref[0];
236 if (seqRefIds.containsKey(sref))
238 if (ref[1] instanceof jalview.datamodel.Mapping)
240 SequenceI seq = seqRefIds.get(sref);
241 while (seq.getDatasetSequence() != null)
243 seq = seq.getDatasetSequence();
245 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
249 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
251 SequenceI seq = seqRefIds.get(sref);
252 while (seq.getDatasetSequence() != null)
254 seq = seq.getDatasetSequence();
257 && ref[2] instanceof jalview.datamodel.Mapping)
259 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
260 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
261 seq, mp.getTo(), mp.getMap());
266 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
267 + ref[2].getClass() + " type objects.");
273 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
274 + ref[1].getClass() + " type objects.");
277 frefedSequence.remove(r);
283 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
285 + " with objecttype "
286 + ref[1].getClass());
293 frefedSequence.remove(r);
301 * This maintains a list of viewports, the key being the seqSetId. Important
302 * to set historyItem and redoList for multiple views
304 Hashtable viewportsAdded;
306 Hashtable annotationIds = new Hashtable();
308 String uniqueSetSuffix = "";
311 * List of pdbfiles added to Jar
313 List<String> pdbfiles = null;
315 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
316 public void saveState(File statefile)
318 FileOutputStream fos = null;
321 fos = new FileOutputStream(statefile);
322 JarOutputStream jout = new JarOutputStream(fos);
325 } catch (Exception e)
327 // TODO: inform user of the problem - they need to know if their data was
329 if (errorMessage == null)
331 errorMessage = "Couldn't write Jalview Archive to output file '"
332 + statefile + "' - See console error log for details";
336 errorMessage += "(output file was '" + statefile + "')";
346 } catch (IOException e)
356 * Writes a jalview project archive to the given Jar output stream.
360 public void saveState(JarOutputStream jout)
362 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
369 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
374 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
375 // //////////////////////////////////////////////////
377 Vector shortNames = new Vector();
380 for (int i = frames.length - 1; i > -1; i--)
382 if (frames[i] instanceof AlignFrame)
384 AlignFrame af = (AlignFrame) frames[i];
387 && skipList.containsKey(af.getViewport()
388 .getSequenceSetId()))
393 String shortName = af.getTitle();
395 if (shortName.indexOf(File.separatorChar) > -1)
397 shortName = shortName.substring(shortName
398 .lastIndexOf(File.separatorChar) + 1);
403 while (shortNames.contains(shortName))
405 if (shortName.endsWith("_" + (count - 1)))
407 shortName = shortName
408 .substring(0, shortName.lastIndexOf("_"));
411 shortName = shortName.concat("_" + count);
415 shortNames.addElement(shortName);
417 if (!shortName.endsWith(".xml"))
419 shortName = shortName + ".xml";
422 int ap, apSize = af.alignPanels.size();
424 for (ap = 0; ap < apSize; ap++)
426 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
428 String fileName = apSize == 1 ? shortName : ap + shortName;
429 if (!fileName.endsWith(".xml"))
431 fileName = fileName + ".xml";
434 saveState(apanel, fileName, jout);
436 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
438 if (!dsses.containsKey(dssid))
440 dsses.put(dssid, af);
447 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
453 } catch (Exception foo)
458 } catch (Exception ex)
460 // TODO: inform user of the problem - they need to know if their data was
462 if (errorMessage == null)
464 errorMessage = "Couldn't write Jalview Archive - see error output for details";
466 ex.printStackTrace();
470 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
471 public boolean saveAlignment(AlignFrame af, String jarFile,
476 int ap, apSize = af.alignPanels.size();
477 FileOutputStream fos = new FileOutputStream(jarFile);
478 JarOutputStream jout = new JarOutputStream(fos);
479 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
480 for (ap = 0; ap < apSize; ap++)
482 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
484 String jfileName = apSize == 1 ? fileName : fileName + ap;
485 if (!jfileName.endsWith(".xml"))
487 jfileName = jfileName + ".xml";
489 saveState(apanel, jfileName, jout);
490 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
492 if (!dsses.containsKey(dssid))
494 dsses.put(dssid, af);
497 writeDatasetFor(dsses, fileName, jout);
501 } catch (Exception foo)
507 } catch (Exception ex)
509 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
510 ex.printStackTrace();
515 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
516 String fileName, JarOutputStream jout)
519 for (String dssids : dsses.keySet())
521 AlignFrame _af = dsses.get(dssids);
522 String jfileName = fileName + " Dataset for " + _af.getTitle();
523 if (!jfileName.endsWith(".xml"))
525 jfileName = jfileName + ".xml";
527 saveState(_af.alignPanel, jfileName, true, jout);
532 * create a JalviewModel from an alignment view and marshall it to a
536 * panel to create jalview model for
538 * name of alignment panel written to output stream
544 public JalviewModel saveState(AlignmentPanel ap, String fileName,
545 JarOutputStream jout)
547 return saveState(ap, fileName, false, jout);
551 * create a JalviewModel from an alignment view and marshall it to a
555 * panel to create jalview model for
557 * name of alignment panel written to output stream
559 * when true, only write the dataset for the alignment, not the data
560 * associated with the view.
566 public JalviewModel saveState(AlignmentPanel ap, String fileName,
567 boolean storeDS, JarOutputStream jout)
570 List<String> viewIds = new ArrayList<String>();
571 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
573 AlignViewport av = ap.av;
575 JalviewModel object = new JalviewModel();
576 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
578 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
579 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
580 "Development Build"));
582 jalview.datamodel.AlignmentI jal = av.getAlignment();
584 if (av.hasHiddenRows())
586 jal = jal.getHiddenSequences().getFullAlignment();
589 SequenceSet vamsasSet = new SequenceSet();
591 JalviewModelSequence jms = new JalviewModelSequence();
593 vamsasSet.setGapChar(jal.getGapCharacter() + "");
595 if (jal.getDataset() != null)
597 // dataset id is the dataset's hashcode
598 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
601 // switch jal and the dataset
602 jal = jal.getDataset();
605 if (jal.getProperties() != null)
607 Enumeration en = jal.getProperties().keys();
608 while (en.hasMoreElements())
610 String key = en.nextElement().toString();
611 SequenceSetProperties ssp = new SequenceSetProperties();
613 ssp.setValue(jal.getProperties().get(key).toString());
614 vamsasSet.addSequenceSetProperties(ssp);
619 Set<String> calcIdSet = new HashSet<String>();
623 jalview.datamodel.SequenceI jds, jdatasq;
624 for (int i = 0; i < jal.getHeight(); i++)
626 jds = jal.getSequenceAt(i);
627 jdatasq = jds.getDatasetSequence() == null ? jds : jds
628 .getDatasetSequence();
631 if (seqRefIds.get(id) != null)
633 // This happens for two reasons: 1. multiple views are being serialised.
634 // 2. the hashCode has collided with another sequence's code. This DOES
635 // HAPPEN! (PF00072.15.stk does this)
636 // JBPNote: Uncomment to debug writing out of files that do not read
637 // back in due to ArrayOutOfBoundExceptions.
638 // System.err.println("vamsasSeq backref: "+id+"");
639 // System.err.println(jds.getName()+"
640 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
641 // System.err.println("Hashcode: "+seqHash(jds));
642 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
643 // System.err.println(rsq.getName()+"
644 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
645 // System.err.println("Hashcode: "+seqHash(rsq));
649 vamsasSeq = createVamsasSequence(id, jds);
650 vamsasSet.addSequence(vamsasSeq);
651 seqRefIds.put(id, jds);
655 jseq.setStart(jds.getStart());
656 jseq.setEnd(jds.getEnd());
657 jseq.setColour(av.getSequenceColour(jds).getRGB());
659 jseq.setId(id); // jseq id should be a string not a number
662 // Store any sequences this sequence represents
663 if (av.hasHiddenRows())
665 jseq.setHidden(av.getAlignment().getHiddenSequences()
668 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
670 jalview.datamodel.SequenceI[] reps = av
671 .getRepresentedSequences(jal.getSequenceAt(i))
672 .getSequencesInOrder(jal);
674 for (int h = 0; h < reps.length; h++)
676 if (reps[h] != jal.getSequenceAt(i))
678 jseq.addHiddenSequences(jal.findIndex(reps[h]));
685 if (jds.getSequenceFeatures() != null)
687 jalview.datamodel.SequenceFeature[] sf = jds
688 .getSequenceFeatures();
690 while (index < sf.length)
692 Features features = new Features();
694 features.setBegin(sf[index].getBegin());
695 features.setEnd(sf[index].getEnd());
696 features.setDescription(sf[index].getDescription());
697 features.setType(sf[index].getType());
698 features.setFeatureGroup(sf[index].getFeatureGroup());
699 features.setScore(sf[index].getScore());
700 if (sf[index].links != null)
702 for (int l = 0; l < sf[index].links.size(); l++)
704 OtherData keyValue = new OtherData();
705 keyValue.setKey("LINK_" + l);
706 keyValue.setValue(sf[index].links.elementAt(l).toString());
707 features.addOtherData(keyValue);
710 if (sf[index].otherDetails != null)
713 Enumeration keys = sf[index].otherDetails.keys();
714 while (keys.hasMoreElements())
716 key = keys.nextElement().toString();
717 OtherData keyValue = new OtherData();
718 keyValue.setKey(key);
719 keyValue.setValue(sf[index].otherDetails.get(key).toString());
720 features.addOtherData(keyValue);
724 jseq.addFeatures(features);
729 if (jdatasq.getPDBId() != null)
731 Enumeration en = jdatasq.getPDBId().elements();
732 while (en.hasMoreElements())
734 Pdbids pdb = new Pdbids();
735 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
738 pdb.setId(entry.getId());
739 pdb.setType(entry.getType());
742 * Store any structure views associated with this sequence. This
743 * section copes with duplicate entries in the project, so a dataset
744 * only view *should* be coped with sensibly.
746 // This must have been loaded, is it still visible?
747 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
748 String matchedFile = null;
749 for (int f = frames.length - 1; f > -1; f--)
751 if (frames[f] instanceof StructureViewerBase)
753 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
754 matchedFile = saveStructureState(ap, jds, pdb, entry,
755 viewIds, matchedFile, viewFrame);
759 if (matchedFile != null || entry.getFile() != null)
761 if (entry.getFile() != null)
764 matchedFile = entry.getFile();
766 pdb.setFile(matchedFile); // entry.getFile());
767 if (pdbfiles == null)
769 pdbfiles = new ArrayList<String>();
772 if (!pdbfiles.contains(entry.getId()))
774 pdbfiles.add(entry.getId());
775 DataInputStream dis = null;
778 File file = new File(matchedFile);
779 if (file.exists() && jout != null)
781 byte[] data = new byte[(int) file.length()];
782 jout.putNextEntry(new JarEntry(entry.getId()));
783 dis = new DataInputStream(
784 new FileInputStream(file));
787 DataOutputStream dout = new DataOutputStream(jout);
788 dout.write(data, 0, data.length);
792 } catch (Exception ex)
794 ex.printStackTrace();
802 } catch (IOException e)
812 if (entry.getProperty() != null)
814 PdbentryItem item = new PdbentryItem();
815 Hashtable properties = entry.getProperty();
816 Enumeration en2 = properties.keys();
817 while (en2.hasMoreElements())
819 Property prop = new Property();
820 String key = en2.nextElement().toString();
822 prop.setValue(properties.get(key).toString());
823 item.addProperty(prop);
825 pdb.addPdbentryItem(item);
835 if (!storeDS && av.hasHiddenRows())
837 jal = av.getAlignment();
840 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
842 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
843 for (int i = 0; i < jac.length; i++)
845 AlcodonFrame alc = new AlcodonFrame();
846 vamsasSet.addAlcodonFrame(alc);
847 for (int p = 0; p < jac[i].aaWidth; p++)
849 Alcodon cmap = new Alcodon();
850 if (jac[i].codons[p] != null)
852 // Null codons indicate a gapped column in the translated peptide
854 cmap.setPos1(jac[i].codons[p][0]);
855 cmap.setPos2(jac[i].codons[p][1]);
856 cmap.setPos3(jac[i].codons[p][2]);
858 alc.addAlcodon(cmap);
860 if (jac[i].getProtMappings() != null
861 && jac[i].getProtMappings().length > 0)
863 SequenceI[] dnas = jac[i].getdnaSeqs();
864 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
865 for (int m = 0; m < pmaps.length; m++)
867 AlcodMap alcmap = new AlcodMap();
868 alcmap.setDnasq(seqHash(dnas[m]));
869 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
871 alc.addAlcodMap(alcmap);
878 // /////////////////////////////////
879 if (!storeDS && av.currentTree != null)
881 // FIND ANY ASSOCIATED TREES
882 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
883 if (Desktop.desktop != null)
885 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
887 for (int t = 0; t < frames.length; t++)
889 if (frames[t] instanceof TreePanel)
891 TreePanel tp = (TreePanel) frames[t];
893 if (tp.treeCanvas.av.getAlignment() == jal)
895 Tree tree = new Tree();
896 tree.setTitle(tp.getTitle());
897 tree.setCurrentTree((av.currentTree == tp.getTree()));
898 tree.setNewick(tp.getTree().toString());
899 tree.setThreshold(tp.treeCanvas.threshold);
901 tree.setFitToWindow(tp.fitToWindow.getState());
902 tree.setFontName(tp.getTreeFont().getName());
903 tree.setFontSize(tp.getTreeFont().getSize());
904 tree.setFontStyle(tp.getTreeFont().getStyle());
905 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
907 tree.setShowBootstrap(tp.bootstrapMenu.getState());
908 tree.setShowDistances(tp.distanceMenu.getState());
910 tree.setHeight(tp.getHeight());
911 tree.setWidth(tp.getWidth());
912 tree.setXpos(tp.getX());
913 tree.setYpos(tp.getY());
914 tree.setId(makeHashCode(tp, null));
923 * store forward refs from an annotationRow to any groups
925 IdentityHashMap groupRefs = new IdentityHashMap();
928 for (SequenceI sq : jal.getSequences())
930 // Store annotation on dataset sequences only
931 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
932 if (aa != null && aa.length > 0)
934 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
941 if (jal.getAlignmentAnnotation() != null)
943 // Store the annotation shown on the alignment.
944 jalview.datamodel.AlignmentAnnotation[] aa = jal
945 .getAlignmentAnnotation();
946 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
951 if (jal.getGroups() != null)
953 JGroup[] groups = new JGroup[jal.getGroups().size()];
955 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
957 groups[++i] = new JGroup();
959 groups[i].setStart(sg.getStartRes());
960 groups[i].setEnd(sg.getEndRes());
961 groups[i].setName(sg.getName());
962 if (groupRefs.containsKey(sg))
964 // group has references so set it's ID field
965 groups[i].setId(groupRefs.get(sg).toString());
969 if (sg.cs.conservationApplied())
971 groups[i].setConsThreshold(sg.cs.getConservationInc());
973 if (sg.cs instanceof jalview.schemes.UserColourScheme)
975 groups[i].setColour(setUserColourScheme(sg.cs, userColours,
981 .setColour(ColourSchemeProperty.getColourName(sg.cs));
984 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
986 groups[i].setColour("AnnotationColourGradient");
987 groups[i].setAnnotationColours(constructAnnotationColours(
988 (jalview.schemes.AnnotationColourGradient) sg.cs,
991 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
994 .setColour(setUserColourScheme(sg.cs, userColours, jms));
998 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1001 groups[i].setPidThreshold(sg.cs.getThreshold());
1004 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1005 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1006 groups[i].setDisplayText(sg.getDisplayText());
1007 groups[i].setColourText(sg.getColourText());
1008 groups[i].setTextCol1(sg.textColour.getRGB());
1009 groups[i].setTextCol2(sg.textColour2.getRGB());
1010 groups[i].setTextColThreshold(sg.thresholdTextColour);
1011 groups[i].setShowUnconserved(sg.getShowNonconserved());
1012 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1013 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1014 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1015 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1016 for (int s = 0; s < sg.getSize(); s++)
1018 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1020 groups[i].addSeq(seqHash(seq));
1024 jms.setJGroup(groups);
1028 // /////////SAVE VIEWPORT
1029 Viewport view = new Viewport();
1030 view.setTitle(ap.alignFrame.getTitle());
1031 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1032 av.getSequenceSetId()));
1033 view.setId(av.getViewId());
1034 view.setViewName(av.viewName);
1035 view.setGatheredViews(av.gatherViewsHere);
1037 if (ap.av.explodedPosition != null)
1039 view.setXpos(av.explodedPosition.x);
1040 view.setYpos(av.explodedPosition.y);
1041 view.setWidth(av.explodedPosition.width);
1042 view.setHeight(av.explodedPosition.height);
1046 view.setXpos(ap.alignFrame.getBounds().x);
1047 view.setYpos(ap.alignFrame.getBounds().y);
1048 view.setWidth(ap.alignFrame.getBounds().width);
1049 view.setHeight(ap.alignFrame.getBounds().height);
1052 view.setStartRes(av.startRes);
1053 view.setStartSeq(av.startSeq);
1055 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1057 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1060 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1062 AnnotationColours ac = constructAnnotationColours(
1063 (jalview.schemes.AnnotationColourGradient) av
1064 .getGlobalColourScheme(),
1067 view.setAnnotationColours(ac);
1068 view.setBgColour("AnnotationColourGradient");
1072 view.setBgColour(ColourSchemeProperty.getColourName(av
1073 .getGlobalColourScheme()));
1076 ColourSchemeI cs = av.getGlobalColourScheme();
1080 if (cs.conservationApplied())
1082 view.setConsThreshold(cs.getConservationInc());
1083 if (cs instanceof jalview.schemes.UserColourScheme)
1085 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1089 if (cs instanceof ResidueColourScheme)
1091 view.setPidThreshold(cs.getThreshold());
1095 view.setConservationSelected(av.getConservationSelected());
1096 view.setPidSelected(av.getAbovePIDThreshold());
1097 view.setFontName(av.font.getName());
1098 view.setFontSize(av.font.getSize());
1099 view.setFontStyle(av.font.getStyle());
1100 view.setRenderGaps(av.renderGaps);
1101 view.setShowAnnotation(av.isShowAnnotation());
1102 view.setShowBoxes(av.getShowBoxes());
1103 view.setShowColourText(av.getColourText());
1104 view.setShowFullId(av.getShowJVSuffix());
1105 view.setRightAlignIds(av.isRightAlignIds());
1106 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1107 view.setShowText(av.getShowText());
1108 view.setShowUnconserved(av.getShowUnconserved());
1109 view.setWrapAlignment(av.getWrapAlignment());
1110 view.setTextCol1(av.textColour.getRGB());
1111 view.setTextCol2(av.textColour2.getRGB());
1112 view.setTextColThreshold(av.thresholdTextColour);
1113 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1114 view.setShowSequenceLogo(av.isShowSequenceLogo());
1115 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1116 view.setShowGroupConsensus(av.isShowGroupConsensus());
1117 view.setShowGroupConservation(av.isShowGroupConservation());
1118 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1119 view.setShowDbRefTooltip(av.isShowDbRefs());
1120 view.setFollowHighlight(av.followHighlight);
1121 view.setFollowSelection(av.followSelection);
1122 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1123 if (av.getFeaturesDisplayed() != null)
1125 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1127 String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1128 .getRenderOrder().toArray(new String[0]);
1130 Vector settingsAdded = new Vector();
1131 Object gstyle = null;
1132 GraduatedColor gcol = null;
1133 if (renderOrder != null)
1135 for (int ro = 0; ro < renderOrder.length; ro++)
1137 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1138 .getFeatureStyle(renderOrder[ro]);
1139 Setting setting = new Setting();
1140 setting.setType(renderOrder[ro]);
1141 if (gstyle instanceof GraduatedColor)
1143 gcol = (GraduatedColor) gstyle;
1144 setting.setColour(gcol.getMaxColor().getRGB());
1145 setting.setMincolour(gcol.getMinColor().getRGB());
1146 setting.setMin(gcol.getMin());
1147 setting.setMax(gcol.getMax());
1148 setting.setColourByLabel(gcol.isColourByLabel());
1149 setting.setAutoScale(gcol.isAutoScale());
1150 setting.setThreshold(gcol.getThresh());
1151 setting.setThreshstate(gcol.getThreshType());
1155 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1156 .getColour(renderOrder[ro]).getRGB());
1159 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1161 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1162 .getOrder(renderOrder[ro]);
1165 setting.setOrder(rorder);
1167 fs.addSetting(setting);
1168 settingsAdded.addElement(renderOrder[ro]);
1172 // Make sure we save none displayed feature settings
1173 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1174 .getFeatureColours().keySet().iterator();
1175 while (en.hasNext())
1177 String key = en.next().toString();
1178 if (settingsAdded.contains(key))
1183 Setting setting = new Setting();
1184 setting.setType(key);
1185 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1186 .getColour(key).getRGB());
1188 setting.setDisplay(false);
1189 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1193 setting.setOrder(rorder);
1195 fs.addSetting(setting);
1196 settingsAdded.addElement(key);
1198 // is groups actually supposed to be a map here ?
1199 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().getFeatureGroups()
1201 Vector groupsAdded = new Vector();
1202 while (en.hasNext())
1204 String grp = en.next().toString();
1205 if (groupsAdded.contains(grp))
1209 Group g = new Group();
1211 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1212 .getFeatureRenderer().checkGroupVisibility(grp, false))
1215 groupsAdded.addElement(grp);
1217 jms.setFeatureSettings(fs);
1221 if (av.hasHiddenColumns())
1223 if (av.getColumnSelection() == null
1224 || av.getColumnSelection().getHiddenColumns() == null)
1226 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1230 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1233 int[] region = av.getColumnSelection()
1234 .getHiddenColumns().get(c);
1235 HiddenColumns hc = new HiddenColumns();
1236 hc.setStart(region[0]);
1237 hc.setEnd(region[1]);
1238 view.addHiddenColumns(hc);
1242 if (calcIdSet.size() > 0)
1244 for (String calcId : calcIdSet)
1246 if (calcId.trim().length() > 0)
1248 CalcIdParam cidp = createCalcIdParam(calcId, av);
1249 // Some calcIds have no parameters.
1252 view.addCalcIdParam(cidp);
1258 jms.addViewport(view);
1260 object.setJalviewModelSequence(jms);
1261 object.getVamsasModel().addSequenceSet(vamsasSet);
1263 if (jout != null && fileName != null)
1265 // We may not want to write the object to disk,
1266 // eg we can copy the alignViewport to a new view object
1267 // using save and then load
1270 JarEntry entry = new JarEntry(fileName);
1271 jout.putNextEntry(entry);
1272 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1274 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1276 marshaller.marshal(object);
1279 } catch (Exception ex)
1281 // TODO: raise error in GUI if marshalling failed.
1282 ex.printStackTrace();
1289 * Save the state of a structure viewer
1294 * the archive XML element under which to save the state
1297 * @param matchedFile
1301 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1302 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1303 String matchedFile, StructureViewerBase viewFrame)
1305 final AAStructureBindingModel bindingModel = viewFrame
1307 for (int peid = 0; peid < bindingModel
1308 .getPdbCount(); peid++)
1310 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1311 final String pdbId = pdbentry.getId();
1312 if (!pdbId.equals(entry.getId())
1313 && !(entry.getId().length() > 4 && entry.getId()
1315 .startsWith(pdbId.toLowerCase())))
1319 if (matchedFile == null)
1321 matchedFile = pdbentry.getFile();
1323 else if (!matchedFile.equals(pdbentry
1327 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1328 + pdbentry.getFile());
1332 // can get at it if the ID
1333 // match is ambiguous (e.g.
1335 String statestring = viewFrame.getStateInfo();
1337 for (int smap = 0; smap < viewFrame.getBinding()
1338 .getSequence()[peid].length; smap++)
1340 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1341 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1343 StructureState state = new StructureState();
1344 state.setVisible(true);
1345 state.setXpos(viewFrame.getX());
1346 state.setYpos(viewFrame.getY());
1347 state.setWidth(viewFrame.getWidth());
1348 state.setHeight(viewFrame.getHeight());
1349 final String viewId = viewFrame.getViewId();
1350 state.setViewId(viewId);
1351 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1352 state.setColourwithAlignPanel(viewFrame
1353 .isUsedforcolourby(ap));
1354 state.setColourByJmol(viewFrame.isColouredByViewer());
1356 * Only store each structure viewer's state once in each XML document.
1358 if (!viewIds.contains(viewId))
1360 viewIds.add(viewId);
1361 state.setContent(statestring.replaceAll("\n", ""));
1365 state.setContent("# duplicate state");
1367 pdb.addStructureState(state);
1374 private AnnotationColours constructAnnotationColours(
1375 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1376 JalviewModelSequence jms)
1378 AnnotationColours ac = new AnnotationColours();
1379 ac.setAboveThreshold(acg.getAboveThreshold());
1380 ac.setThreshold(acg.getAnnotationThreshold());
1381 ac.setAnnotation(acg.getAnnotation());
1382 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1384 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1389 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1393 ac.setMaxColour(acg.getMaxColour().getRGB());
1394 ac.setMinColour(acg.getMinColour().getRGB());
1395 ac.setPerSequence(acg.isSeqAssociated());
1396 ac.setPredefinedColours(acg.isPredefinedColours());
1400 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1401 IdentityHashMap groupRefs, AlignmentViewport av,
1402 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1405 for (int i = 0; i < aa.length; i++)
1407 Annotation an = new Annotation();
1409 if (aa[i].annotationId != null)
1411 annotationIds.put(aa[i].annotationId, aa[i]);
1414 an.setId(aa[i].annotationId);
1416 an.setVisible(aa[i].visible);
1418 an.setDescription(aa[i].description);
1420 if (aa[i].sequenceRef != null)
1422 // TODO later annotation sequenceRef should be the XML ID of the
1423 // sequence rather than its display name
1424 an.setSequenceRef(aa[i].sequenceRef.getName());
1426 if (aa[i].groupRef != null)
1428 Object groupIdr = groupRefs.get(aa[i].groupRef);
1429 if (groupIdr == null)
1431 // make a locally unique String
1432 groupRefs.put(aa[i].groupRef,
1433 groupIdr = ("" + System.currentTimeMillis()
1434 + aa[i].groupRef.getName() + groupRefs.size()));
1436 an.setGroupRef(groupIdr.toString());
1439 // store all visualization attributes for annotation
1440 an.setGraphHeight(aa[i].graphHeight);
1441 an.setCentreColLabels(aa[i].centreColLabels);
1442 an.setScaleColLabels(aa[i].scaleColLabel);
1443 an.setShowAllColLabels(aa[i].showAllColLabels);
1444 an.setBelowAlignment(aa[i].belowAlignment);
1446 if (aa[i].graph > 0)
1449 an.setGraphType(aa[i].graph);
1450 an.setGraphGroup(aa[i].graphGroup);
1451 if (aa[i].getThreshold() != null)
1453 ThresholdLine line = new ThresholdLine();
1454 line.setLabel(aa[i].getThreshold().label);
1455 line.setValue(aa[i].getThreshold().value);
1456 line.setColour(aa[i].getThreshold().colour.getRGB());
1457 an.setThresholdLine(line);
1465 an.setLabel(aa[i].label);
1467 if (aa[i] == av.getAlignmentQualityAnnot()
1468 || aa[i] == av.getAlignmentConservationAnnotation()
1469 || aa[i] == av.getAlignmentConsensusAnnotation()
1470 || aa[i].autoCalculated)
1472 // new way of indicating autocalculated annotation -
1473 an.setAutoCalculated(aa[i].autoCalculated);
1475 if (aa[i].hasScore())
1477 an.setScore(aa[i].getScore());
1480 if (aa[i].getCalcId() != null)
1482 calcIdSet.add(aa[i].getCalcId());
1483 an.setCalcId(aa[i].getCalcId());
1485 if (aa[i].hasProperties())
1487 for (String pr : aa[i].getProperties())
1489 Property prop = new Property();
1491 prop.setValue(aa[i].getProperty(pr));
1492 an.addProperty(prop);
1496 AnnotationElement ae;
1497 if (aa[i].annotations != null)
1499 an.setScoreOnly(false);
1500 for (int a = 0; a < aa[i].annotations.length; a++)
1502 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1507 ae = new AnnotationElement();
1508 if (aa[i].annotations[a].description != null)
1510 ae.setDescription(aa[i].annotations[a].description);
1512 if (aa[i].annotations[a].displayCharacter != null)
1514 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1517 if (!Float.isNaN(aa[i].annotations[a].value))
1519 ae.setValue(aa[i].annotations[a].value);
1523 if (aa[i].annotations[a].secondaryStructure > ' ')
1525 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1529 if (aa[i].annotations[a].colour != null
1530 && aa[i].annotations[a].colour != java.awt.Color.black)
1532 ae.setColour(aa[i].annotations[a].colour.getRGB());
1535 an.addAnnotationElement(ae);
1536 if (aa[i].autoCalculated)
1538 // only write one non-null entry into the annotation row -
1539 // sufficient to get the visualization attributes necessary to
1547 an.setScoreOnly(true);
1549 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1551 // skip autocalculated annotation - these are only provided for
1553 vamsasSet.addAnnotation(an);
1559 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1561 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1562 if (settings != null)
1564 CalcIdParam vCalcIdParam = new CalcIdParam();
1565 vCalcIdParam.setCalcId(calcId);
1566 vCalcIdParam.addServiceURL(settings.getServiceURI());
1567 // generic URI allowing a third party to resolve another instance of the
1568 // service used for this calculation
1569 for (String urls : settings.getServiceURLs())
1571 vCalcIdParam.addServiceURL(urls);
1573 vCalcIdParam.setVersion("1.0");
1574 if (settings.getPreset() != null)
1576 WsParamSetI setting = settings.getPreset();
1577 vCalcIdParam.setName(setting.getName());
1578 vCalcIdParam.setDescription(setting.getDescription());
1582 vCalcIdParam.setName("");
1583 vCalcIdParam.setDescription("Last used parameters");
1585 // need to be able to recover 1) settings 2) user-defined presets or
1586 // recreate settings from preset 3) predefined settings provided by
1587 // service - or settings that can be transferred (or discarded)
1588 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1590 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1591 // todo - decide if updateImmediately is needed for any projects.
1593 return vCalcIdParam;
1598 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1601 if (calcIdParam.getVersion().equals("1.0"))
1603 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1604 .getPreferredServiceFor(calcIdParam.getServiceURL());
1605 if (service != null)
1607 WsParamSetI parmSet = null;
1610 parmSet = service.getParamStore().parseServiceParameterFile(
1611 calcIdParam.getName(), calcIdParam.getDescription(),
1612 calcIdParam.getServiceURL(),
1613 calcIdParam.getParameters().replace("|\\n|", "\n"));
1614 } catch (IOException x)
1616 warn("Couldn't parse parameter data for "
1617 + calcIdParam.getCalcId(), x);
1620 List<ArgumentI> argList = null;
1621 if (calcIdParam.getName().length() > 0)
1623 parmSet = service.getParamStore()
1624 .getPreset(calcIdParam.getName());
1625 if (parmSet != null)
1627 // TODO : check we have a good match with settings in AACon -
1628 // otherwise we'll need to create a new preset
1633 argList = parmSet.getArguments();
1636 AAConSettings settings = new AAConSettings(
1637 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1638 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1639 calcIdParam.isNeedsUpdate());
1644 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1648 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1652 * External mapping between jalview objects and objects yielding a valid and
1653 * unique object ID string. This is null for normal Jalview project IO, but
1654 * non-null when a jalview project is being read or written as part of a
1657 IdentityHashMap jv2vobj = null;
1660 * Construct a unique ID for jvobj using either existing bindings or if none
1661 * exist, the result of the hashcode call for the object.
1664 * jalview data object
1665 * @return unique ID for referring to jvobj
1667 private String makeHashCode(Object jvobj, String altCode)
1669 if (jv2vobj != null)
1671 Object id = jv2vobj.get(jvobj);
1674 return id.toString();
1676 // check string ID mappings
1677 if (jvids2vobj != null && jvobj instanceof String)
1679 id = jvids2vobj.get(jvobj);
1683 return id.toString();
1685 // give up and warn that something has gone wrong
1686 warn("Cannot find ID for object in external mapping : " + jvobj);
1692 * return local jalview object mapped to ID, if it exists
1696 * @return null or object bound to idcode
1698 private Object retrieveExistingObj(String idcode)
1700 if (idcode != null && vobj2jv != null)
1702 return vobj2jv.get(idcode);
1708 * binding from ID strings from external mapping table to jalview data model
1711 private Hashtable vobj2jv;
1713 private Sequence createVamsasSequence(String id, SequenceI jds)
1715 return createVamsasSequence(true, id, jds, null);
1718 private Sequence createVamsasSequence(boolean recurse, String id,
1719 SequenceI jds, SequenceI parentseq)
1721 Sequence vamsasSeq = new Sequence();
1722 vamsasSeq.setId(id);
1723 vamsasSeq.setName(jds.getName());
1724 vamsasSeq.setSequence(jds.getSequenceAsString());
1725 vamsasSeq.setDescription(jds.getDescription());
1726 jalview.datamodel.DBRefEntry[] dbrefs = null;
1727 if (jds.getDatasetSequence() != null)
1729 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1730 if (jds.getDatasetSequence().getDBRef() != null)
1732 dbrefs = jds.getDatasetSequence().getDBRef();
1737 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1738 // dataset sequences only
1739 dbrefs = jds.getDBRef();
1743 for (int d = 0; d < dbrefs.length; d++)
1745 DBRef dbref = new DBRef();
1746 dbref.setSource(dbrefs[d].getSource());
1747 dbref.setVersion(dbrefs[d].getVersion());
1748 dbref.setAccessionId(dbrefs[d].getAccessionId());
1749 if (dbrefs[d].hasMap())
1751 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1753 dbref.setMapping(mp);
1755 vamsasSeq.addDBRef(dbref);
1761 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1762 SequenceI parentseq, SequenceI jds, boolean recurse)
1765 if (jmp.getMap() != null)
1769 jalview.util.MapList mlst = jmp.getMap();
1770 int r[] = mlst.getFromRanges();
1771 for (int s = 0; s < r.length; s += 2)
1773 MapListFrom mfrom = new MapListFrom();
1774 mfrom.setStart(r[s]);
1775 mfrom.setEnd(r[s + 1]);
1776 mp.addMapListFrom(mfrom);
1778 r = mlst.getToRanges();
1779 for (int s = 0; s < r.length; s += 2)
1781 MapListTo mto = new MapListTo();
1783 mto.setEnd(r[s + 1]);
1784 mp.addMapListTo(mto);
1786 mp.setMapFromUnit(mlst.getFromRatio());
1787 mp.setMapToUnit(mlst.getToRatio());
1788 if (jmp.getTo() != null)
1790 MappingChoice mpc = new MappingChoice();
1792 && (parentseq != jmp.getTo() || parentseq
1793 .getDatasetSequence() != jmp.getTo()))
1795 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1801 SequenceI ps = null;
1802 if (parentseq != jmp.getTo()
1803 && parentseq.getDatasetSequence() != jmp.getTo())
1805 // chaining dbref rather than a handshaking one
1806 jmpid = seqHash(ps = jmp.getTo());
1810 jmpid = seqHash(ps = parentseq);
1812 mpc.setDseqFor(jmpid);
1813 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1815 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1816 seqRefIds.put(mpc.getDseqFor(), ps);
1820 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1823 mp.setMappingChoice(mpc);
1829 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
1830 List<UserColourScheme> userColours, JalviewModelSequence jms)
1833 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1834 boolean newucs = false;
1835 if (!userColours.contains(ucs))
1837 userColours.add(ucs);
1840 id = "ucs" + userColours.indexOf(ucs);
1843 // actually create the scheme's entry in the XML model
1844 java.awt.Color[] colours = ucs.getColours();
1845 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1846 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1848 for (int i = 0; i < colours.length; i++)
1850 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1851 col.setName(ResidueProperties.aa[i]);
1852 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1853 jbucs.addColour(col);
1855 if (ucs.getLowerCaseColours() != null)
1857 colours = ucs.getLowerCaseColours();
1858 for (int i = 0; i < colours.length; i++)
1860 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1861 col.setName(ResidueProperties.aa[i].toLowerCase());
1862 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1863 jbucs.addColour(col);
1868 uc.setUserColourScheme(jbucs);
1869 jms.addUserColours(uc);
1875 jalview.schemes.UserColourScheme getUserColourScheme(
1876 JalviewModelSequence jms, String id)
1878 UserColours[] uc = jms.getUserColours();
1879 UserColours colours = null;
1881 for (int i = 0; i < uc.length; i++)
1883 if (uc[i].getId().equals(id))
1891 java.awt.Color[] newColours = new java.awt.Color[24];
1893 for (int i = 0; i < 24; i++)
1895 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1896 .getUserColourScheme().getColour(i).getRGB(), 16));
1899 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1902 if (colours.getUserColourScheme().getColourCount() > 24)
1904 newColours = new java.awt.Color[23];
1905 for (int i = 0; i < 23; i++)
1907 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1908 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1910 ucs.setLowerCaseColours(newColours);
1917 * contains last error message (if any) encountered by XML loader.
1919 String errorMessage = null;
1922 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1923 * exceptions are raised during project XML parsing
1925 public boolean attemptversion1parse = true;
1928 * Load a jalview project archive from a jar file
1931 * - HTTP URL or filename
1933 public AlignFrame loadJalviewAlign(final String file)
1936 jalview.gui.AlignFrame af = null;
1940 // create list to store references for any new Jmol viewers created
1941 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1942 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1943 // Workaround is to make sure caller implements the JarInputStreamProvider
1945 // so we can re-open the jar input stream for each entry.
1947 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1948 af = loadJalviewAlign(jprovider);
1950 } catch (MalformedURLException e)
1952 errorMessage = "Invalid URL format for '" + file + "'";
1958 SwingUtilities.invokeAndWait(new Runnable()
1962 setLoadingFinishedForNewStructureViewers();
1965 } catch (Exception x)
1973 private jarInputStreamProvider createjarInputStreamProvider(
1974 final String file) throws MalformedURLException
1977 errorMessage = null;
1978 uniqueSetSuffix = null;
1980 viewportsAdded = null;
1981 frefedSequence = null;
1983 if (file.startsWith("http://"))
1985 url = new URL(file);
1987 final URL _url = url;
1988 return new jarInputStreamProvider()
1992 public JarInputStream getJarInputStream() throws IOException
1996 return new JarInputStream(_url.openStream());
2000 return new JarInputStream(new FileInputStream(file));
2005 public String getFilename()
2013 * Recover jalview session from a jalview project archive. Caller may
2014 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2015 * themselves. Any null fields will be initialised with default values,
2016 * non-null fields are left alone.
2021 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2023 errorMessage = null;
2024 if (uniqueSetSuffix == null)
2026 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2028 if (seqRefIds == null)
2030 seqRefIds = new HashMap<String, SequenceI>();
2032 if (viewportsAdded == null)
2034 viewportsAdded = new Hashtable();
2036 if (frefedSequence == null)
2038 frefedSequence = new Vector();
2041 jalview.gui.AlignFrame af = null, _af = null;
2042 Hashtable gatherToThisFrame = new Hashtable();
2043 final String file = jprovider.getFilename();
2046 JarInputStream jin = null;
2047 JarEntry jarentry = null;
2052 jin = jprovider.getJarInputStream();
2053 for (int i = 0; i < entryCount; i++)
2055 jarentry = jin.getNextJarEntry();
2058 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2060 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2061 JalviewModel object = new JalviewModel();
2063 Unmarshaller unmar = new Unmarshaller(object);
2064 unmar.setValidation(false);
2065 object = (JalviewModel) unmar.unmarshal(in);
2066 if (true) // !skipViewport(object))
2068 _af = loadFromObject(object, file, true, jprovider);
2069 if (object.getJalviewModelSequence().getViewportCount() > 0)
2072 if (af.viewport.gatherViewsHere)
2074 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2080 else if (jarentry != null)
2082 // Some other file here.
2085 } while (jarentry != null);
2086 resolveFrefedSequences();
2087 } catch (java.io.FileNotFoundException ex)
2089 ex.printStackTrace();
2090 errorMessage = "Couldn't locate Jalview XML file : " + file;
2091 System.err.println("Exception whilst loading jalview XML file : "
2093 } catch (java.net.UnknownHostException ex)
2095 ex.printStackTrace();
2096 errorMessage = "Couldn't locate Jalview XML file : " + file;
2097 System.err.println("Exception whilst loading jalview XML file : "
2099 } catch (Exception ex)
2101 System.err.println("Parsing as Jalview Version 2 file failed.");
2102 ex.printStackTrace(System.err);
2103 if (attemptversion1parse)
2105 // Is Version 1 Jar file?
2108 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2109 } catch (Exception ex2)
2111 System.err.println("Exception whilst loading as jalviewXMLV1:");
2112 ex2.printStackTrace();
2116 if (Desktop.instance != null)
2118 Desktop.instance.stopLoading();
2122 System.out.println("Successfully loaded archive file");
2125 ex.printStackTrace();
2127 System.err.println("Exception whilst loading jalview XML file : "
2129 } catch (OutOfMemoryError e)
2131 // Don't use the OOM Window here
2132 errorMessage = "Out of memory loading jalview XML file";
2133 System.err.println("Out of memory whilst loading jalview XML file");
2134 e.printStackTrace();
2137 if (Desktop.instance != null)
2139 Desktop.instance.stopLoading();
2142 Enumeration en = gatherToThisFrame.elements();
2143 while (en.hasMoreElements())
2145 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2147 if (errorMessage != null)
2155 * check errorMessage for a valid error message and raise an error box in the
2156 * GUI or write the current errorMessage to stderr and then clear the error
2159 protected void reportErrors()
2161 reportErrors(false);
2164 protected void reportErrors(final boolean saving)
2166 if (errorMessage != null)
2168 final String finalErrorMessage = errorMessage;
2171 javax.swing.SwingUtilities.invokeLater(new Runnable()
2176 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2177 finalErrorMessage, "Error "
2178 + (saving ? "saving" : "loading")
2179 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2185 System.err.println("Problem loading Jalview file: " + errorMessage);
2188 errorMessage = null;
2191 Hashtable<String, String> alreadyLoadedPDB;
2194 * when set, local views will be updated from view stored in JalviewXML
2195 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2196 * sync if this is set to true.
2198 private final boolean updateLocalViews = false;
2200 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2202 if (alreadyLoadedPDB == null)
2204 alreadyLoadedPDB = new Hashtable();
2207 if (alreadyLoadedPDB.containsKey(pdbId))
2209 return alreadyLoadedPDB.get(pdbId).toString();
2214 JarInputStream jin = jprovider.getJarInputStream();
2216 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2217 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2218 * FileInputStream(jprovider)); }
2221 JarEntry entry = null;
2224 entry = jin.getNextJarEntry();
2225 } while (entry != null && !entry.getName().equals(pdbId));
2228 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2229 File outFile = File.createTempFile("jalview_pdb", ".txt");
2230 outFile.deleteOnExit();
2231 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2234 while ((data = in.readLine()) != null)
2241 } catch (Exception foo)
2246 String t = outFile.getAbsolutePath();
2247 alreadyLoadedPDB.put(pdbId, t);
2252 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2254 } catch (Exception ex)
2256 ex.printStackTrace();
2262 private class JvAnnotRow
2264 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2271 * persisted version of annotation row from which to take vis properties
2273 public jalview.datamodel.AlignmentAnnotation template;
2276 * original position of the annotation row in the alignment
2282 * Load alignment frame from jalview XML DOM object
2287 * filename source string
2288 * @param loadTreesAndStructures
2289 * when false only create Viewport
2291 * data source provider
2292 * @return alignment frame created from view stored in DOM
2294 AlignFrame loadFromObject(JalviewModel object, String file,
2295 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2297 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2298 Sequence[] vamsasSeq = vamsasSet.getSequence();
2300 JalviewModelSequence jms = object.getJalviewModelSequence();
2302 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2305 // ////////////////////////////////
2308 Vector hiddenSeqs = null;
2309 jalview.datamodel.Sequence jseq;
2311 ArrayList tmpseqs = new ArrayList();
2313 boolean multipleView = false;
2315 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2316 int vi = 0; // counter in vamsasSeq array
2317 for (int i = 0; i < jseqs.length; i++)
2319 String seqId = jseqs[i].getId();
2321 if (seqRefIds.get(seqId) != null)
2323 tmpseqs.add(seqRefIds.get(seqId));
2324 multipleView = true;
2328 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2329 vamsasSeq[vi].getSequence());
2330 jseq.setDescription(vamsasSeq[vi].getDescription());
2331 jseq.setStart(jseqs[i].getStart());
2332 jseq.setEnd(jseqs[i].getEnd());
2333 jseq.setVamsasId(uniqueSetSuffix + seqId);
2334 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2339 if (jseqs[i].getHidden())
2341 if (hiddenSeqs == null)
2343 hiddenSeqs = new Vector();
2346 hiddenSeqs.addElement(seqRefIds.get(seqId));
2352 // Create the alignment object from the sequence set
2353 // ///////////////////////////////
2354 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2357 tmpseqs.toArray(orderedSeqs);
2359 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2362 // / Add the alignment properties
2363 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2365 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2366 al.setProperty(ssp.getKey(), ssp.getValue());
2370 // SequenceFeatures are added to the DatasetSequence,
2371 // so we must create or recover the dataset before loading features
2372 // ///////////////////////////////
2373 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2375 // older jalview projects do not have a dataset id.
2376 al.setDataset(null);
2380 // recover dataset - passing on flag indicating if this a 'viewless'
2381 // sequence set (a.k.a. a stored dataset for the project)
2382 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2383 .getViewportCount() == 0);
2385 // ///////////////////////////////
2387 Hashtable pdbloaded = new Hashtable();
2390 // load sequence features, database references and any associated PDB
2391 // structures for the alignment
2392 for (int i = 0; i < vamsasSeq.length; i++)
2394 if (jseqs[i].getFeaturesCount() > 0)
2396 Features[] features = jseqs[i].getFeatures();
2397 for (int f = 0; f < features.length; f++)
2399 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2400 features[f].getType(), features[f].getDescription(),
2401 features[f].getStatus(), features[f].getBegin(),
2402 features[f].getEnd(), features[f].getFeatureGroup());
2404 sf.setScore(features[f].getScore());
2405 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2407 OtherData keyValue = features[f].getOtherData(od);
2408 if (keyValue.getKey().startsWith("LINK"))
2410 sf.addLink(keyValue.getValue());
2414 sf.setValue(keyValue.getKey(), keyValue.getValue());
2419 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2422 if (vamsasSeq[i].getDBRefCount() > 0)
2424 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2426 if (jseqs[i].getPdbidsCount() > 0)
2428 Pdbids[] ids = jseqs[i].getPdbids();
2429 for (int p = 0; p < ids.length; p++)
2431 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2432 entry.setId(ids[p].getId());
2433 entry.setType(ids[p].getType());
2434 if (ids[p].getFile() != null)
2436 if (!pdbloaded.containsKey(ids[p].getFile()))
2438 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2442 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2445 StructureSelectionManager.getStructureSelectionManager(
2447 .registerPDBEntry(entry);
2448 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2452 } // end !multipleview
2454 // ///////////////////////////////
2455 // LOAD SEQUENCE MAPPINGS
2457 if (vamsasSet.getAlcodonFrameCount() > 0)
2459 // TODO Potentially this should only be done once for all views of an
2461 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2462 for (int i = 0; i < alc.length; i++)
2464 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2465 alc[i].getAlcodonCount());
2466 if (alc[i].getAlcodonCount() > 0)
2468 Alcodon[] alcods = alc[i].getAlcodon();
2469 for (int p = 0; p < cf.codons.length; p++)
2471 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2472 && alcods[p].hasPos3())
2474 // translated codons require three valid positions
2475 cf.codons[p] = new int[3];
2476 cf.codons[p][0] = (int) alcods[p].getPos1();
2477 cf.codons[p][1] = (int) alcods[p].getPos2();
2478 cf.codons[p][2] = (int) alcods[p].getPos3();
2482 cf.codons[p] = null;
2486 if (alc[i].getAlcodMapCount() > 0)
2488 AlcodMap[] maps = alc[i].getAlcodMap();
2489 for (int m = 0; m < maps.length; m++)
2491 SequenceI dnaseq = seqRefIds
2492 .get(maps[m].getDnasq());
2494 jalview.datamodel.Mapping mapping = null;
2495 // attach to dna sequence reference.
2496 if (maps[m].getMapping() != null)
2498 mapping = addMapping(maps[m].getMapping());
2502 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2507 frefedSequence.add(new Object[]
2508 { maps[m].getDnasq(), cf, mapping });
2512 al.addCodonFrame(cf);
2517 // ////////////////////////////////
2519 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2521 * store any annotations which forward reference a group's ID
2523 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2525 if (vamsasSet.getAnnotationCount() > 0)
2527 Annotation[] an = vamsasSet.getAnnotation();
2529 for (int i = 0; i < an.length; i++)
2532 * test if annotation is automatically calculated for this view only
2534 boolean autoForView = false;
2535 if (an[i].getLabel().equals("Quality")
2536 || an[i].getLabel().equals("Conservation")
2537 || an[i].getLabel().equals("Consensus"))
2539 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2541 if (!an[i].hasAutoCalculated())
2543 an[i].setAutoCalculated(true);
2547 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2549 // remove ID - we don't recover annotation from other views for
2550 // view-specific annotation
2554 // set visiblity for other annotation in this view
2555 if (an[i].getId() != null
2556 && annotationIds.containsKey(an[i].getId()))
2558 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2559 .get(an[i].getId());
2560 // in principle Visible should always be true for annotation displayed
2561 // in multiple views
2562 if (an[i].hasVisible())
2564 jda.visible = an[i].getVisible();
2567 al.addAnnotation(jda);
2571 // Construct new annotation from model.
2572 AnnotationElement[] ae = an[i].getAnnotationElement();
2573 jalview.datamodel.Annotation[] anot = null;
2574 java.awt.Color firstColour = null;
2576 if (!an[i].getScoreOnly())
2578 anot = new jalview.datamodel.Annotation[al.getWidth()];
2579 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2581 anpos = ae[aa].getPosition();
2583 if (anpos >= anot.length)
2588 anot[anpos] = new jalview.datamodel.Annotation(
2590 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2591 (ae[aa].getSecondaryStructure() == null || ae[aa]
2592 .getSecondaryStructure().length() == 0) ? ' '
2593 : ae[aa].getSecondaryStructure().charAt(0),
2597 // JBPNote: Consider verifying dataflow for IO of secondary
2598 // structure annotation read from Stockholm files
2599 // this was added to try to ensure that
2600 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2602 // anot[ae[aa].getPosition()].displayCharacter = "";
2604 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2605 if (firstColour == null)
2607 firstColour = anot[anpos].colour;
2611 jalview.datamodel.AlignmentAnnotation jaa = null;
2613 if (an[i].getGraph())
2615 float llim = 0, hlim = 0;
2616 // if (autoForView || an[i].isAutoCalculated()) {
2619 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2620 an[i].getDescription(), anot, llim, hlim,
2621 an[i].getGraphType());
2623 jaa.graphGroup = an[i].getGraphGroup();
2624 jaa._linecolour = firstColour;
2625 if (an[i].getThresholdLine() != null)
2627 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2628 .getThresholdLine().getValue(), an[i]
2629 .getThresholdLine().getLabel(), new java.awt.Color(
2630 an[i].getThresholdLine().getColour())));
2633 if (autoForView || an[i].isAutoCalculated())
2635 // Hardwire the symbol display line to ensure that labels for
2636 // histograms are displayed
2642 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2643 an[i].getDescription(), anot);
2644 jaa._linecolour = firstColour;
2646 // register new annotation
2647 if (an[i].getId() != null)
2649 annotationIds.put(an[i].getId(), jaa);
2650 jaa.annotationId = an[i].getId();
2652 // recover sequence association
2653 if (an[i].getSequenceRef() != null)
2655 if (al.findName(an[i].getSequenceRef()) != null)
2657 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2659 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2662 // and make a note of any group association
2663 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2665 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2666 .get(an[i].getGroupRef());
2669 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2670 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2675 if (an[i].hasScore())
2677 jaa.setScore(an[i].getScore());
2679 if (an[i].hasVisible())
2681 jaa.visible = an[i].getVisible();
2684 if (an[i].hasCentreColLabels())
2686 jaa.centreColLabels = an[i].getCentreColLabels();
2689 if (an[i].hasScaleColLabels())
2691 jaa.scaleColLabel = an[i].getScaleColLabels();
2693 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2695 // newer files have an 'autoCalculated' flag and store calculation
2696 // state in viewport properties
2697 jaa.autoCalculated = true; // means annotation will be marked for
2698 // update at end of load.
2700 if (an[i].hasGraphHeight())
2702 jaa.graphHeight = an[i].getGraphHeight();
2704 if (an[i].hasBelowAlignment())
2706 jaa.belowAlignment = an[i].isBelowAlignment();
2708 jaa.setCalcId(an[i].getCalcId());
2709 if (an[i].getPropertyCount() > 0)
2711 for (jalview.schemabinding.version2.Property prop : an[i]
2714 jaa.setProperty(prop.getName(), prop.getValue());
2717 if (jaa.autoCalculated)
2719 autoAlan.add(new JvAnnotRow(i, jaa));
2722 // if (!autoForView)
2724 // add autocalculated group annotation and any user created annotation
2726 al.addAnnotation(jaa);
2730 // ///////////////////////
2732 // Create alignment markup and styles for this view
2733 if (jms.getJGroupCount() > 0)
2735 JGroup[] groups = jms.getJGroup();
2736 boolean addAnnotSchemeGroup = false;
2737 for (int i = 0; i < groups.length; i++)
2739 ColourSchemeI cs = null;
2741 if (groups[i].getColour() != null)
2743 if (groups[i].getColour().startsWith("ucs"))
2745 cs = getUserColourScheme(jms, groups[i].getColour());
2747 else if (groups[i].getColour().equals("AnnotationColourGradient")
2748 && groups[i].getAnnotationColours() != null)
2750 addAnnotSchemeGroup = true;
2755 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2760 cs.setThreshold(groups[i].getPidThreshold(), true);
2764 Vector seqs = new Vector();
2766 for (int s = 0; s < groups[i].getSeqCount(); s++)
2768 String seqId = groups[i].getSeq(s) + "";
2769 jalview.datamodel.SequenceI ts = seqRefIds
2774 seqs.addElement(ts);
2778 if (seqs.size() < 1)
2783 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2784 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2785 groups[i].getDisplayText(), groups[i].getColourText(),
2786 groups[i].getStart(), groups[i].getEnd());
2788 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2790 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2791 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2792 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2793 .isShowUnconserved() : false);
2794 sg.thresholdTextColour = groups[i].getTextColThreshold();
2795 if (groups[i].hasShowConsensusHistogram())
2797 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2800 if (groups[i].hasShowSequenceLogo())
2802 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2804 if (groups[i].hasNormaliseSequenceLogo())
2806 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2808 if (groups[i].hasIgnoreGapsinConsensus())
2810 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2812 if (groups[i].getConsThreshold() != 0)
2814 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2815 "All", ResidueProperties.propHash, 3,
2816 sg.getSequences(null), 0, sg.getWidth() - 1);
2818 c.verdict(false, 25);
2819 sg.cs.setConservation(c);
2822 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2824 // re-instate unique group/annotation row reference
2825 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2826 .get(groups[i].getId());
2829 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2832 if (jaa.autoCalculated)
2834 // match up and try to set group autocalc alignment row for this
2836 if (jaa.label.startsWith("Consensus for "))
2838 sg.setConsensus(jaa);
2840 // match up and try to set group autocalc alignment row for this
2842 if (jaa.label.startsWith("Conservation for "))
2844 sg.setConservationRow(jaa);
2851 if (addAnnotSchemeGroup)
2853 // reconstruct the annotation colourscheme
2854 sg.cs = constructAnnotationColour(
2855 groups[i].getAnnotationColours(), null, al, jms, false);
2861 // only dataset in this model, so just return.
2864 // ///////////////////////////////
2867 // If we just load in the same jar file again, the sequenceSetId
2868 // will be the same, and we end up with multiple references
2869 // to the same sequenceSet. We must modify this id on load
2870 // so that each load of the file gives a unique id
2871 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2872 String viewId = (view.getId() == null ? null : view.getId()
2874 AlignFrame af = null;
2875 AlignViewport av = null;
2876 // now check to see if we really need to create a new viewport.
2877 if (multipleView && viewportsAdded.size() == 0)
2879 // We recovered an alignment for which a viewport already exists.
2880 // TODO: fix up any settings necessary for overlaying stored state onto
2881 // state recovered from another document. (may not be necessary).
2882 // we may need a binding from a viewport in memory to one recovered from
2884 // and then recover its containing af to allow the settings to be applied.
2885 // TODO: fix for vamsas demo
2887 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2889 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2890 if (seqsetobj != null)
2892 if (seqsetobj instanceof String)
2894 uniqueSeqSetId = (String) seqsetobj;
2896 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2902 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2908 * indicate that annotation colours are applied across all groups (pre
2909 * Jalview 2.8.1 behaviour)
2911 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2912 object.getVersion());
2914 AlignmentPanel ap = null;
2915 boolean isnewview = true;
2918 // Check to see if this alignment already has a view id == viewId
2919 jalview.gui.AlignmentPanel views[] = Desktop
2920 .getAlignmentPanels(uniqueSeqSetId);
2921 if (views != null && views.length > 0)
2923 for (int v = 0; v < views.length; v++)
2925 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2927 // recover the existing alignpanel, alignframe, viewport
2928 af = views[v].alignFrame;
2931 // TODO: could even skip resetting view settings if we don't want to
2932 // change the local settings from other jalview processes
2941 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
2942 uniqueSeqSetId, viewId, autoAlan);
2947 // /////////////////////////////////////
2948 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2952 for (int t = 0; t < jms.getTreeCount(); t++)
2955 Tree tree = jms.getTree(t);
2957 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2960 tp = af.ShowNewickTree(
2961 new jalview.io.NewickFile(tree.getNewick()),
2962 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2963 tree.getXpos(), tree.getYpos());
2964 if (tree.getId() != null)
2966 // perhaps bind the tree id to something ?
2971 // update local tree attributes ?
2972 // TODO: should check if tp has been manipulated by user - if so its
2973 // settings shouldn't be modified
2974 tp.setTitle(tree.getTitle());
2975 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2976 .getWidth(), tree.getHeight()));
2977 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2980 tp.treeCanvas.av = av; // af.viewport;
2981 tp.treeCanvas.ap = ap; // af.alignPanel;
2986 warn("There was a problem recovering stored Newick tree: \n"
2987 + tree.getNewick());
2991 tp.fitToWindow.setState(tree.getFitToWindow());
2992 tp.fitToWindow_actionPerformed(null);
2994 if (tree.getFontName() != null)
2996 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2997 .getFontStyle(), tree.getFontSize()));
3001 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3002 .getFontStyle(), tree.getFontSize()));
3005 tp.showPlaceholders(tree.getMarkUnlinked());
3006 tp.showBootstrap(tree.getShowBootstrap());
3007 tp.showDistances(tree.getShowDistances());
3009 tp.treeCanvas.threshold = tree.getThreshold();
3011 if (tree.getCurrentTree())
3013 af.viewport.setCurrentTree(tp.getTree());
3017 } catch (Exception ex)
3019 ex.printStackTrace();
3023 // //LOAD STRUCTURES
3024 if (loadTreesAndStructures)
3026 loadStructures(jprovider, jseqs, af, ap);
3028 // and finally return.
3033 * Load and link any saved structure viewers.
3040 protected void loadStructures(jarInputStreamProvider jprovider,
3041 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3044 * Run through all PDB ids on the alignment, and collect mappings between
3045 * distinct view ids and all sequences referring to that view.
3047 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3049 for (int i = 0; i < jseqs.length; i++)
3051 if (jseqs[i].getPdbidsCount() > 0)
3053 Pdbids[] ids = jseqs[i].getPdbids();
3054 for (int p = 0; p < ids.length; p++)
3056 final int structureStateCount = ids[p].getStructureStateCount();
3057 for (int s = 0; s < structureStateCount; s++)
3059 // check to see if we haven't already created this structure view
3060 final StructureState structureState = ids[p].getStructureState(s);
3061 String sviewid = (structureState.getViewId() == null) ? null
3062 : structureState.getViewId()
3064 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3065 // Originally : ids[p].getFile()
3066 // : TODO: verify external PDB file recovery still works in normal
3067 // jalview project load
3068 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3069 jpdb.setId(ids[p].getId());
3071 int x = structureState.getXpos();
3072 int y = structureState.getYpos();
3073 int width = structureState.getWidth();
3074 int height = structureState.getHeight();
3076 // Probably don't need to do this anymore...
3077 // Desktop.desktop.getComponentAt(x, y);
3078 // TODO: NOW: check that this recovers the PDB file correctly.
3079 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3080 jalview.datamodel.SequenceI seq = seqRefIds
3081 .get(jseqs[i].getId() + "");
3082 if (sviewid == null)
3084 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3087 if (!structureViewers.containsKey(sviewid))
3089 structureViewers.put(sviewid, new StructureViewerModel(x, y, width, height,
3090 false, false, true));
3091 // Legacy pre-2.7 conversion JAL-823 :
3092 // do not assume any view has to be linked for colour by
3096 // assemble String[] { pdb files }, String[] { id for each
3097 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3098 // seqs_file 2}, boolean[] {
3099 // linkAlignPanel,superposeWithAlignpanel}} from hash
3100 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3101 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3102 | (structureState.hasAlignwithAlignPanel() ? structureState
3103 .getAlignwithAlignPanel() : false));
3106 * Default colour by linked panel to false if not specified (e.g.
3107 * for pre-2.7 projects)
3109 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3110 colourWithAlignPanel |= (structureState
3111 .hasColourwithAlignPanel() ? structureState
3112 .getColourwithAlignPanel() : false);
3113 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3116 * Default colour by viewer to true if not specified (e.g. for
3119 boolean colourByViewer = jmoldat.isColourByViewer();
3120 colourByViewer &= structureState
3121 .hasColourByJmol() ? structureState
3122 .getColourByJmol() : true;
3123 jmoldat.setColourByViewer(colourByViewer);
3125 if (jmoldat.getStateData().length() < structureState
3126 .getContent().length())
3129 jmoldat.setStateData(structureState.getContent());
3132 if (ids[p].getFile() != null)
3134 File mapkey = new File(ids[p].getFile());
3135 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3136 if (seqstrmaps == null)
3138 jmoldat.getFileData().put(
3140 seqstrmaps = jmoldat.new StructureData(pdbFile,
3143 if (!seqstrmaps.getSeqList().contains(seq))
3145 seqstrmaps.getSeqList().add(seq);
3151 errorMessage = ("The Jmol views in this project were imported\nfrom an older version of Jalview.\nPlease review the sequence colour associations\nin the Colour by section of the Jmol View menu.\n\nIn the case of problems, see note at\nhttp://issues.jalview.org/browse/JAL-747");
3158 // Instantiate the associated structure views
3159 for (Entry<String, StructureViewerModel> entry : structureViewers.entrySet())
3161 createOrLinkStructureViewer(entry, af, ap);
3171 protected void createOrLinkStructureViewer(
3172 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3175 final StructureViewerModel svattrib = viewerData.getValue();
3178 * Search for any viewer windows already open from other alignment views
3179 * that exactly match the stored structure state
3181 StructureViewerBase comp = findMatchingViewer(viewerData);
3185 linkStructureViewer(ap, comp, svattrib);
3190 * Pending an XML element for ViewerType, just check if stateData contains
3191 * "chimera" (part of the chimera session filename).
3193 if (svattrib.getStateData().indexOf("chimera") > -1)
3195 createChimeraViewer(viewerData, af);
3199 createJmolViewer(viewerData, af);
3204 * Create a new Chimera viewer.
3209 protected void createChimeraViewer(Entry<String, StructureViewerModel> viewerData,
3212 final StructureViewerModel data = viewerData.getValue();
3213 String chimeraSession = data.getStateData();
3215 if (new File(chimeraSession).exists())
3217 Set<Entry<File, StructureData>> fileData = data.getFileData()
3219 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3220 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3221 for (Entry<File, StructureData> pdb : fileData)
3223 String filePath = pdb.getValue().getFilePath();
3224 String pdbId = pdb.getValue().getPdbId();
3225 pdbs.add(new PDBEntry(filePath, pdbId));
3226 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3227 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3231 boolean colourByChimera = data.isColourByViewer();
3232 boolean colourBySequence = data.isColourWithAlignPanel();
3234 // TODO can/should this be done via StructureViewer (like Jmol)?
3235 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs
3237 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs.size()][]);
3238 new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray,
3240 colourByChimera, colourBySequence);
3244 Cache.log.error("Chimera session file " + chimeraSession
3250 * Create a new Jmol window. First parse the Jmol state to translate filenames
3251 * loaded into the view, and record the order in which files are shown in the
3252 * Jmol view, so we can add the sequence mappings in same order.
3257 protected void createJmolViewer(
3258 final Entry<String, StructureViewerModel> viewerData, AlignFrame af)
3260 final StructureViewerModel svattrib = viewerData.getValue();
3261 String state = svattrib.getStateData();
3262 List<String> pdbfilenames = new ArrayList<String>();
3263 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3264 List<String> pdbids = new ArrayList<String>();
3265 StringBuilder newFileLoc = new StringBuilder(64);
3266 int cp = 0, ncp, ecp;
3267 Map<File, StructureData> oldFiles = svattrib.getFileData();
3268 while ((ncp = state.indexOf("load ", cp)) > -1)
3272 // look for next filename in load statement
3273 newFileLoc.append(state.substring(cp,
3274 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3275 String oldfilenam = state.substring(ncp,
3276 ecp = state.indexOf("\"", ncp));
3277 // recover the new mapping data for this old filename
3278 // have to normalize filename - since Jmol and jalview do
3280 // translation differently.
3281 StructureData filedat = oldFiles.get(new File(oldfilenam));
3282 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3283 pdbfilenames.add(filedat.getFilePath());
3284 pdbids.add(filedat.getPdbId());
3285 seqmaps.add(filedat.getSeqList()
3286 .toArray(new SequenceI[0]));
3287 newFileLoc.append("\"");
3288 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3289 // look for next file statement.
3290 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3294 // just append rest of state
3295 newFileLoc.append(state.substring(cp));
3299 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3300 newFileLoc = new StringBuilder(state);
3301 newFileLoc.append("; load append ");
3302 for (File id : oldFiles.keySet())
3304 // add this and any other pdb files that should be present in
3306 StructureData filedat = oldFiles.get(id);
3307 newFileLoc.append(filedat.getFilePath());
3308 pdbfilenames.add(filedat.getFilePath());
3309 pdbids.add(filedat.getPdbId());
3310 seqmaps.add(filedat.getSeqList()
3311 .toArray(new SequenceI[0]));
3312 newFileLoc.append(" \"");
3313 newFileLoc.append(filedat.getFilePath());
3314 newFileLoc.append("\"");
3317 newFileLoc.append(";");
3320 if (newFileLoc.length() > 0)
3322 int histbug = newFileLoc.indexOf("history = ");
3324 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3325 String val = (diff == -1) ? null : newFileLoc
3326 .substring(histbug, diff);
3327 if (val != null && val.length() >= 4)
3329 if (val.contains("e"))
3331 if (val.trim().equals("true"))
3339 newFileLoc.replace(histbug, diff, val);
3343 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3345 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3346 final SequenceI[][] sq = seqmaps
3347 .toArray(new SequenceI[seqmaps.size()][]);
3348 final String fileloc = newFileLoc.toString();
3349 final String sviewid = viewerData.getKey();
3350 final AlignFrame alf = af;
3351 final Rectangle rect = new Rectangle(svattrib.getX(),
3352 svattrib.getY(), svattrib.getWidth(), svattrib.getHeight());
3355 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3360 JalviewStructureDisplayI sview = null;
3363 // JAL-1333 note - we probably can't migrate Jmol views to UCSF
3365 sview = new StructureViewer(alf.alignPanel
3366 .getStructureSelectionManager()).createView(
3367 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3368 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3369 addNewStructureViewer(sview);
3370 } catch (OutOfMemoryError ex)
3372 new OOMWarning("restoring structure view for PDB id " + id,
3373 (OutOfMemoryError) ex.getCause());
3374 if (sview != null && sview.isVisible())
3376 sview.closeViewer();
3377 sview.setVisible(false);
3383 } catch (InvocationTargetException ex)
3385 warn("Unexpected error when opening Jmol view.", ex);
3387 } catch (InterruptedException e)
3389 // e.printStackTrace();
3395 * Returns any open frame that matches given structure viewer data. The match
3396 * is based on the unique viewId, or (for older project versions) the frame's
3402 protected StructureViewerBase findMatchingViewer(
3403 Entry<String, StructureViewerModel> viewerData)
3405 final String sviewid = viewerData.getKey();
3406 final StructureViewerModel svattrib = viewerData.getValue();
3407 StructureViewerBase comp = null;
3408 JInternalFrame[] frames = getAllFrames();
3409 for (JInternalFrame frame : frames)
3411 if (frame instanceof StructureViewerBase)
3414 * Post jalview 2.4 schema includes structure view id
3417 && ((StructureViewerBase) frame).getViewId().equals(
3420 comp = (AppJmol) frame;
3424 * Otherwise test for matching position and size of viewer frame
3426 else if (frame.getX() == svattrib.getX()
3427 && frame.getY() == svattrib.getY()
3428 && frame.getHeight() == svattrib.getHeight()
3429 && frame.getWidth() == svattrib.getWidth())
3431 comp = (AppJmol) frame;
3440 * Link an AlignmentPanel to an existing structure viewer.
3445 * @param useinViewerSuperpos
3446 * @param usetoColourbyseq
3447 * @param viewerColouring
3449 protected void linkStructureViewer(AlignmentPanel ap,
3450 StructureViewerBase viewer, StructureViewerModel svattrib)
3452 // NOTE: if the jalview project is part of a shared session then
3453 // view synchronization should/could be done here.
3455 final boolean useinViewerSuperpos = svattrib.isAlignWithPanel();
3456 final boolean usetoColourbyseq = svattrib.isColourWithAlignPanel();
3457 final boolean viewerColouring = svattrib.isColourByViewer();
3458 Map<File, StructureData> oldFiles = svattrib.getFileData();
3461 * Add mapping for sequences in this view to an already open viewer
3463 final AAStructureBindingModel binding = viewer.getBinding();
3464 for (File id : oldFiles.keySet())
3466 // add this and any other pdb files that should be present in the
3468 StructureData filedat = oldFiles.get(id);
3469 String pdbFile = filedat.getFilePath();
3470 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3471 binding.getSsm().setMapping(seq, null, pdbFile,
3472 jalview.io.AppletFormatAdapter.FILE);
3473 binding.addSequenceForStructFile(pdbFile, seq);
3475 // and add the AlignmentPanel's reference to the view panel
3476 viewer.addAlignmentPanel(ap);
3477 if (useinViewerSuperpos)
3479 viewer.useAlignmentPanelForSuperposition(ap);
3483 viewer.excludeAlignmentPanelForSuperposition(ap);
3485 if (usetoColourbyseq)
3487 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3491 viewer.excludeAlignmentPanelForColourbyseq(ap);
3496 * Get all frames within the Desktop.
3500 protected JInternalFrame[] getAllFrames()
3502 JInternalFrame[] frames = null;
3503 // TODO is this necessary - is it safe - risk of hanging?
3508 frames = Desktop.desktop.getAllFrames();
3509 } catch (ArrayIndexOutOfBoundsException e)
3511 // occasional No such child exceptions are thrown here...
3515 } catch (InterruptedException f)
3519 } while (frames == null);
3526 * - minimum version we are comparing against
3528 * - version of data being processsed.
3529 * @return true if version is development/null or evaluates to the same or
3530 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3532 private boolean isVersionStringLaterThan(String supported, String version)
3534 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3535 || version.equalsIgnoreCase("Test")
3536 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3538 System.err.println("Assuming project file with "
3539 + (version == null ? "null" : version)
3540 + " is compatible with Jalview version " + supported);
3545 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3547 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3549 // convert b to decimal to catch bugfix releases within a series
3550 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3551 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3554 if (Float.valueOf(curT) > Float.valueOf(fileT))
3556 // current version is newer than the version that wrote the file
3559 } catch (NumberFormatException nfe)
3562 .println("** WARNING: Version comparison failed for tokens ("
3566 + ")\n** Current: '"
3567 + supported + "' and Version: '" + version + "'");
3570 if (currentV.hasMoreElements())
3572 // fileV has no minor version but identical series to current
3579 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3581 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3583 if (newStructureViewers != null)
3585 sview.getBinding().setFinishedLoadingFromArchive(false);
3586 newStructureViewers.add(sview);
3590 protected void setLoadingFinishedForNewStructureViewers()
3592 if (newStructureViewers != null)
3594 for (JalviewStructureDisplayI sview : newStructureViewers)
3596 sview.getBinding().setFinishedLoadingFromArchive(true);
3598 newStructureViewers.clear();
3599 newStructureViewers = null;
3603 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3604 Alignment al, JalviewModelSequence jms, Viewport view,
3605 String uniqueSeqSetId, String viewId,
3606 ArrayList<JvAnnotRow> autoAlan)
3608 AlignFrame af = null;
3609 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3610 uniqueSeqSetId, viewId);
3612 af.setFileName(file, "Jalview");
3614 for (int i = 0; i < JSEQ.length; i++)
3616 af.viewport.setSequenceColour(af.viewport.getAlignment()
3617 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3620 af.viewport.gatherViewsHere = view.getGatheredViews();
3622 if (view.getSequenceSetId() != null)
3624 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3625 .get(uniqueSeqSetId);
3627 af.viewport.setSequenceSetId(uniqueSeqSetId);
3630 // propagate shared settings to this new view
3631 af.viewport.historyList = av.historyList;
3632 af.viewport.redoList = av.redoList;
3636 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3638 // TODO: check if this method can be called repeatedly without
3639 // side-effects if alignpanel already registered.
3640 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3642 // apply Hidden regions to view.
3643 if (hiddenSeqs != null)
3645 for (int s = 0; s < JSEQ.length; s++)
3647 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3649 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3652 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3654 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3657 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3660 for (int s = 0; s < hiddenSeqs.size(); s++)
3662 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3665 af.viewport.hideSequence(hseqs);
3668 // recover view properties and display parameters
3669 if (view.getViewName() != null)
3671 af.viewport.viewName = view.getViewName();
3672 af.setInitialTabVisible();
3674 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3677 af.viewport.setShowAnnotation(view.getShowAnnotation());
3678 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3680 af.viewport.setColourText(view.getShowColourText());
3682 af.viewport.setConservationSelected(view.getConservationSelected());
3683 af.viewport.setShowJVSuffix(view.getShowFullId());
3684 af.viewport.setRightAlignIds(view.getRightAlignIds());
3685 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3686 .getFontStyle(), view.getFontSize()));
3687 af.alignPanel.fontChanged();
3688 af.viewport.setRenderGaps(view.getRenderGaps());
3689 af.viewport.setWrapAlignment(view.getWrapAlignment());
3690 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3691 af.viewport.setShowAnnotation(view.getShowAnnotation());
3692 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3694 af.viewport.setShowBoxes(view.getShowBoxes());
3696 af.viewport.setShowText(view.getShowText());
3698 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3699 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3700 af.viewport.thresholdTextColour = view.getTextColThreshold();
3701 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3702 .isShowUnconserved() : false);
3703 af.viewport.setStartRes(view.getStartRes());
3704 af.viewport.setStartSeq(view.getStartSeq());
3706 ColourSchemeI cs = null;
3707 // apply colourschemes
3708 if (view.getBgColour() != null)
3710 if (view.getBgColour().startsWith("ucs"))
3712 cs = getUserColourScheme(jms, view.getBgColour());
3714 else if (view.getBgColour().startsWith("Annotation"))
3716 AnnotationColours viewAnnColour = view.getAnnotationColours();
3717 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3724 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3729 cs.setThreshold(view.getPidThreshold(), true);
3730 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3734 af.viewport.setGlobalColourScheme(cs);
3735 af.viewport.setColourAppliesToAllGroups(false);
3737 if (view.getConservationSelected() && cs != null)
3739 cs.setConservationInc(view.getConsThreshold());
3742 af.changeColour(cs);
3744 af.viewport.setColourAppliesToAllGroups(true);
3746 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
3748 if (view.hasCentreColumnLabels())
3750 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3752 if (view.hasIgnoreGapsinConsensus())
3754 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3757 if (view.hasFollowHighlight())
3759 af.viewport.followHighlight = view.getFollowHighlight();
3761 if (view.hasFollowSelection())
3763 af.viewport.followSelection = view.getFollowSelection();
3765 if (view.hasShowConsensusHistogram())
3767 af.viewport.setShowConsensusHistogram(view
3768 .getShowConsensusHistogram());
3772 af.viewport.setShowConsensusHistogram(true);
3774 if (view.hasShowSequenceLogo())
3776 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3780 af.viewport.setShowSequenceLogo(false);
3782 if (view.hasNormaliseSequenceLogo())
3784 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3786 if (view.hasShowDbRefTooltip())
3788 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3790 if (view.hasShowNPfeatureTooltip())
3792 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3794 if (view.hasShowGroupConsensus())
3796 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3800 af.viewport.setShowGroupConsensus(false);
3802 if (view.hasShowGroupConservation())
3804 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3808 af.viewport.setShowGroupConservation(false);
3811 // recover featre settings
3812 if (jms.getFeatureSettings() != null)
3814 FeaturesDisplayed fdi;
3815 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
3816 String[] renderOrder = new String[jms.getFeatureSettings()
3817 .getSettingCount()];
3818 Hashtable featureGroups = new Hashtable();
3819 Hashtable featureColours = new Hashtable();
3820 Hashtable featureOrder = new Hashtable();
3822 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3824 Setting setting = jms.getFeatureSettings().getSetting(fs);
3825 if (setting.hasMincolour())
3827 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3828 new java.awt.Color(setting.getMincolour()),
3829 new java.awt.Color(setting.getColour()),
3830 setting.getMin(), setting.getMax()) : new GraduatedColor(
3831 new java.awt.Color(setting.getMincolour()),
3832 new java.awt.Color(setting.getColour()), 0, 1);
3833 if (setting.hasThreshold())
3835 gc.setThresh(setting.getThreshold());
3836 gc.setThreshType(setting.getThreshstate());
3838 gc.setAutoScaled(true); // default
3839 if (setting.hasAutoScale())
3841 gc.setAutoScaled(setting.getAutoScale());
3843 if (setting.hasColourByLabel())
3845 gc.setColourByLabel(setting.getColourByLabel());
3847 // and put in the feature colour table.
3848 featureColours.put(setting.getType(), gc);
3852 featureColours.put(setting.getType(),
3853 new java.awt.Color(setting.getColour()));
3855 renderOrder[fs] = setting.getType();
3856 if (setting.hasOrder())
3858 featureOrder.put(setting.getType(), setting.getOrder());
3862 featureOrder.put(setting.getType(), new Float(fs
3863 / jms.getFeatureSettings().getSettingCount()));
3865 if (setting.getDisplay())
3867 fdi.setVisible(setting.getType());
3870 Hashtable fgtable = new Hashtable();
3871 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3873 Group grp = jms.getFeatureSettings().getGroup(gs);
3874 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3876 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
3877 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
3878 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
3879 FeatureRendererSettings frs = new FeatureRendererSettings(
3880 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
3881 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
3882 .transferSettings(frs);
3886 if (view.getHiddenColumnsCount() > 0)
3888 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3890 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3891 .getHiddenColumns(c).getEnd() // +1
3895 if (view.getCalcIdParam() != null)
3897 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3899 if (calcIdParam != null)
3901 if (recoverCalcIdParam(calcIdParam, af.viewport))
3906 warn("Couldn't recover parameters for "
3907 + calcIdParam.getCalcId());
3912 af.setMenusFromViewport(af.viewport);
3913 // TODO: we don't need to do this if the viewport is aready visible.
3914 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3916 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3917 reorderAutoannotation(af, al, autoAlan);
3918 af.alignPanel.alignmentChanged();
3922 private ColourSchemeI constructAnnotationColour(
3923 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3924 JalviewModelSequence jms, boolean checkGroupAnnColour)
3926 boolean propagateAnnColour = false;
3927 ColourSchemeI cs = null;
3928 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3929 if (checkGroupAnnColour && al.getGroups() != null
3930 && al.getGroups().size() > 0)
3932 // pre 2.8.1 behaviour
3933 // check to see if we should transfer annotation colours
3934 propagateAnnColour = true;
3935 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3937 if (sg.cs instanceof AnnotationColourGradient)
3939 propagateAnnColour = false;
3943 // int find annotation
3944 if (annAlignment.getAlignmentAnnotation() != null)
3946 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3948 if (annAlignment.getAlignmentAnnotation()[i].label
3949 .equals(viewAnnColour.getAnnotation()))
3951 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3953 annAlignment.getAlignmentAnnotation()[i]
3954 .setThreshold(new jalview.datamodel.GraphLine(
3955 viewAnnColour.getThreshold(), "Threshold",
3956 java.awt.Color.black)
3961 if (viewAnnColour.getColourScheme().equals("None"))
3963 cs = new AnnotationColourGradient(
3964 annAlignment.getAlignmentAnnotation()[i],
3965 new java.awt.Color(viewAnnColour.getMinColour()),
3966 new java.awt.Color(viewAnnColour.getMaxColour()),
3967 viewAnnColour.getAboveThreshold());
3969 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3971 cs = new AnnotationColourGradient(
3972 annAlignment.getAlignmentAnnotation()[i],
3973 getUserColourScheme(jms,
3974 viewAnnColour.getColourScheme()),
3975 viewAnnColour.getAboveThreshold());
3979 cs = new AnnotationColourGradient(
3980 annAlignment.getAlignmentAnnotation()[i],
3981 ColourSchemeProperty.getColour(al,
3982 viewAnnColour.getColourScheme()),
3983 viewAnnColour.getAboveThreshold());
3985 if (viewAnnColour.hasPerSequence())
3987 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3990 if (viewAnnColour.hasPredefinedColours())
3992 ((AnnotationColourGradient) cs)
3993 .setPredefinedColours(viewAnnColour
3994 .isPredefinedColours());
3996 if (propagateAnnColour && al.getGroups() != null)
3998 // Also use these settings for all the groups
3999 for (int g = 0; g < al.getGroups().size(); g++)
4001 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4009 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4010 * new AnnotationColourGradient(
4011 * annAlignment.getAlignmentAnnotation()[i], new
4012 * java.awt.Color(viewAnnColour. getMinColour()), new
4013 * java.awt.Color(viewAnnColour. getMaxColour()),
4014 * viewAnnColour.getAboveThreshold()); } else
4017 sg.cs = new AnnotationColourGradient(
4018 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4019 viewAnnColour.getAboveThreshold());
4020 if (cs instanceof AnnotationColourGradient)
4022 if (viewAnnColour.hasPerSequence())
4024 ((AnnotationColourGradient) cs)
4025 .setSeqAssociated(viewAnnColour.isPerSequence());
4027 if (viewAnnColour.hasPredefinedColours())
4029 ((AnnotationColourGradient) cs)
4030 .setPredefinedColours(viewAnnColour
4031 .isPredefinedColours());
4047 private void reorderAutoannotation(AlignFrame af, Alignment al,
4048 ArrayList<JvAnnotRow> autoAlan)
4050 // copy over visualization settings for autocalculated annotation in the
4052 if (al.getAlignmentAnnotation() != null)
4055 * Kludge for magic autoannotation names (see JAL-811)
4057 String[] magicNames = new String[]
4058 { "Consensus", "Quality", "Conservation" };
4059 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4060 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4061 for (String nm : magicNames)
4063 visan.put(nm, nullAnnot);
4065 for (JvAnnotRow auan : autoAlan)
4067 visan.put(auan.template.label
4068 + (auan.template.getCalcId() == null ? "" : "\t"
4069 + auan.template.getCalcId()), auan);
4071 int hSize = al.getAlignmentAnnotation().length;
4072 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4073 // work through any autoCalculated annotation already on the view
4074 // removing it if it should be placed in a different location on the
4075 // annotation panel.
4076 List<String> remains = new ArrayList(visan.keySet());
4077 for (int h = 0; h < hSize; h++)
4079 jalview.datamodel.AlignmentAnnotation jalan = al
4080 .getAlignmentAnnotation()[h];
4081 if (jalan.autoCalculated)
4084 JvAnnotRow valan = visan.get(k = jalan.label);
4085 if (jalan.getCalcId() != null)
4087 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4092 // delete the auto calculated row from the alignment
4093 al.deleteAnnotation(jalan, false);
4097 if (valan != nullAnnot)
4099 if (jalan != valan.template)
4101 // newly created autoannotation row instance
4102 // so keep a reference to the visible annotation row
4103 // and copy over all relevant attributes
4104 if (valan.template.graphHeight >= 0)
4107 jalan.graphHeight = valan.template.graphHeight;
4109 jalan.visible = valan.template.visible;
4111 reorder.add(new JvAnnotRow(valan.order, jalan));
4116 // Add any (possibly stale) autocalculated rows that were not appended to
4117 // the view during construction
4118 for (String other : remains)
4120 JvAnnotRow othera = visan.get(other);
4121 if (othera != nullAnnot && othera.template.getCalcId() != null
4122 && othera.template.getCalcId().length() > 0)
4124 reorder.add(othera);
4127 // now put the automatic annotation in its correct place
4128 int s = 0, srt[] = new int[reorder.size()];
4129 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4130 for (JvAnnotRow jvar : reorder)
4133 srt[s++] = jvar.order;
4136 jalview.util.QuickSort.sort(srt, rws);
4137 // and re-insert the annotation at its correct position
4138 for (JvAnnotRow jvar : rws)
4140 al.addAnnotation(jvar.template, jvar.order);
4142 af.alignPanel.adjustAnnotationHeight();
4146 Hashtable skipList = null;
4149 * TODO remove this method
4152 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4153 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4154 * throw new Error("Implementation Error. No skipList defined for this
4155 * Jalview2XML instance."); } return (AlignFrame)
4156 * skipList.get(view.getSequenceSetId()); }
4160 * Check if the Jalview view contained in object should be skipped or not.
4163 * @return true if view's sequenceSetId is a key in skipList
4165 private boolean skipViewport(JalviewModel object)
4167 if (skipList == null)
4172 if (skipList.containsKey(id = object.getJalviewModelSequence()
4173 .getViewport()[0].getSequenceSetId()))
4175 if (Cache.log != null && Cache.log.isDebugEnabled())
4177 Cache.log.debug("Skipping seuqence set id " + id);
4184 public void addToSkipList(AlignFrame af)
4186 if (skipList == null)
4188 skipList = new Hashtable();
4190 skipList.put(af.getViewport().getSequenceSetId(), af);
4193 public void clearSkipList()
4195 if (skipList != null)
4202 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4203 boolean ignoreUnrefed)
4205 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4206 Vector dseqs = null;
4209 // create a list of new dataset sequences
4210 dseqs = new Vector();
4212 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4214 Sequence vamsasSeq = vamsasSet.getSequence(i);
4215 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4217 // create a new dataset
4220 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4221 dseqs.copyInto(dsseqs);
4222 ds = new jalview.datamodel.Alignment(dsseqs);
4223 debug("Created new dataset " + vamsasSet.getDatasetId()
4224 + " for alignment " + System.identityHashCode(al));
4225 addDatasetRef(vamsasSet.getDatasetId(), ds);
4227 // set the dataset for the newly imported alignment.
4228 if (al.getDataset() == null && !ignoreUnrefed)
4237 * sequence definition to create/merge dataset sequence for
4241 * vector to add new dataset sequence to
4243 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4244 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4246 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4248 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4249 .get(vamsasSeq.getId());
4250 jalview.datamodel.SequenceI dsq = null;
4251 if (sq != null && sq.getDatasetSequence() != null)
4253 dsq = sq.getDatasetSequence();
4255 if (sq == null && ignoreUnrefed)
4259 String sqid = vamsasSeq.getDsseqid();
4262 // need to create or add a new dataset sequence reference to this sequence
4265 dsq = seqRefIds.get(sqid);
4270 // make a new dataset sequence
4271 dsq = sq.createDatasetSequence();
4274 // make up a new dataset reference for this sequence
4275 sqid = seqHash(dsq);
4277 dsq.setVamsasId(uniqueSetSuffix + sqid);
4278 seqRefIds.put(sqid, dsq);
4283 dseqs.addElement(dsq);
4288 ds.addSequence(dsq);
4294 { // make this dataset sequence sq's dataset sequence
4295 sq.setDatasetSequence(dsq);
4296 // and update the current dataset alignment
4301 if (!dseqs.contains(dsq))
4308 if (ds.findIndex(dsq) < 0)
4310 ds.addSequence(dsq);
4317 // TODO: refactor this as a merge dataset sequence function
4318 // now check that sq (the dataset sequence) sequence really is the union of
4319 // all references to it
4320 // boolean pre = sq.getStart() < dsq.getStart();
4321 // boolean post = sq.getEnd() > dsq.getEnd();
4325 StringBuffer sb = new StringBuffer();
4326 String newres = jalview.analysis.AlignSeq.extractGaps(
4327 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4328 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4329 && newres.length() > dsq.getLength())
4331 // Update with the longer sequence.
4335 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4336 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4337 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4338 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4340 dsq.setSequence(newres);
4342 // TODO: merges will never happen if we 'know' we have the real dataset
4343 // sequence - this should be detected when id==dssid
4345 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4346 // + (pre ? "prepended" : "") + " "
4347 // + (post ? "appended" : ""));
4352 java.util.Hashtable datasetIds = null;
4354 java.util.IdentityHashMap dataset2Ids = null;
4356 private Alignment getDatasetFor(String datasetId)
4358 if (datasetIds == null)
4360 datasetIds = new Hashtable();
4363 if (datasetIds.containsKey(datasetId))
4365 return (Alignment) datasetIds.get(datasetId);
4370 private void addDatasetRef(String datasetId, Alignment dataset)
4372 if (datasetIds == null)
4374 datasetIds = new Hashtable();
4376 datasetIds.put(datasetId, dataset);
4380 * make a new dataset ID for this jalview dataset alignment
4385 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4387 if (dataset.getDataset() != null)
4389 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4391 String datasetId = makeHashCode(dataset, null);
4392 if (datasetId == null)
4394 // make a new datasetId and record it
4395 if (dataset2Ids == null)
4397 dataset2Ids = new IdentityHashMap();
4401 datasetId = (String) dataset2Ids.get(dataset);
4403 if (datasetId == null)
4405 datasetId = "ds" + dataset2Ids.size() + 1;
4406 dataset2Ids.put(dataset, datasetId);
4412 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4414 for (int d = 0; d < sequence.getDBRefCount(); d++)
4416 DBRef dr = sequence.getDBRef(d);
4417 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4418 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4419 .getVersion(), sequence.getDBRef(d).getAccessionId());
4420 if (dr.getMapping() != null)
4422 entry.setMap(addMapping(dr.getMapping()));
4424 datasetSequence.addDBRef(entry);
4428 private jalview.datamodel.Mapping addMapping(Mapping m)
4430 SequenceI dsto = null;
4431 // Mapping m = dr.getMapping();
4432 int fr[] = new int[m.getMapListFromCount() * 2];
4433 Enumeration f = m.enumerateMapListFrom();
4434 for (int _i = 0; f.hasMoreElements(); _i += 2)
4436 MapListFrom mf = (MapListFrom) f.nextElement();
4437 fr[_i] = mf.getStart();
4438 fr[_i + 1] = mf.getEnd();
4440 int fto[] = new int[m.getMapListToCount() * 2];
4441 f = m.enumerateMapListTo();
4442 for (int _i = 0; f.hasMoreElements(); _i += 2)
4444 MapListTo mf = (MapListTo) f.nextElement();
4445 fto[_i] = mf.getStart();
4446 fto[_i + 1] = mf.getEnd();
4448 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4449 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4450 if (m.getMappingChoice() != null)
4452 MappingChoice mc = m.getMappingChoice();
4453 if (mc.getDseqFor() != null)
4455 String dsfor = "" + mc.getDseqFor();
4456 if (seqRefIds.containsKey(dsfor))
4461 jmap.setTo(seqRefIds.get(dsfor));
4465 frefedSequence.add(new Object[]
4472 * local sequence definition
4474 Sequence ms = mc.getSequence();
4475 jalview.datamodel.Sequence djs = null;
4476 String sqid = ms.getDsseqid();
4477 if (sqid != null && sqid.length() > 0)
4480 * recover dataset sequence
4482 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4487 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4488 sqid = ((Object) ms).toString(); // make up a new hascode for
4489 // undefined dataset sequence hash
4490 // (unlikely to happen)
4496 * make a new dataset sequence and add it to refIds hash
4498 djs = new jalview.datamodel.Sequence(ms.getName(),
4500 djs.setStart(jmap.getMap().getToLowest());
4501 djs.setEnd(jmap.getMap().getToHighest());
4502 djs.setVamsasId(uniqueSetSuffix + sqid);
4504 seqRefIds.put(sqid, djs);
4507 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4516 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4517 boolean keepSeqRefs)
4520 jalview.schemabinding.version2.JalviewModel jm = saveState(ap, null,
4526 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4530 uniqueSetSuffix = "";
4531 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4536 if (this.frefedSequence == null)
4538 frefedSequence = new Vector();
4541 viewportsAdded = new Hashtable();
4543 AlignFrame af = loadFromObject(jm, null, false, null);
4544 af.alignPanels.clear();
4545 af.closeMenuItem_actionPerformed(true);
4548 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4549 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4550 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4551 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4552 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4555 return af.alignPanel;
4559 * flag indicating if hashtables should be cleared on finalization TODO this
4560 * flag may not be necessary
4562 private final boolean _cleartables = true;
4564 private Hashtable jvids2vobj;
4569 * @see java.lang.Object#finalize()
4572 protected void finalize() throws Throwable
4574 // really make sure we have no buried refs left.
4579 this.seqRefIds = null;
4580 this.seqsToIds = null;
4584 private void warn(String msg)
4589 private void warn(String msg, Exception e)
4591 if (Cache.log != null)
4595 Cache.log.warn(msg, e);
4599 Cache.log.warn(msg);
4604 System.err.println("Warning: " + msg);
4607 e.printStackTrace();
4612 private void debug(String string)
4614 debug(string, null);
4617 private void debug(String msg, Exception e)
4619 if (Cache.log != null)
4623 Cache.log.debug(msg, e);
4627 Cache.log.debug(msg);
4632 System.err.println("Warning: " + msg);
4635 e.printStackTrace();
4641 * set the object to ID mapping tables used to write/recover objects and XML
4642 * ID strings for the jalview project. If external tables are provided then
4643 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4644 * object goes out of scope. - also populates the datasetIds hashtable with
4645 * alignment objects containing dataset sequences
4648 * Map from ID strings to jalview datamodel
4650 * Map from jalview datamodel to ID strings
4654 public void setObjectMappingTables(Hashtable vobj2jv,
4655 IdentityHashMap jv2vobj)
4657 this.jv2vobj = jv2vobj;
4658 this.vobj2jv = vobj2jv;
4659 Iterator ds = jv2vobj.keySet().iterator();
4661 while (ds.hasNext())
4663 Object jvobj = ds.next();
4664 id = jv2vobj.get(jvobj).toString();
4665 if (jvobj instanceof jalview.datamodel.Alignment)
4667 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4669 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4672 else if (jvobj instanceof jalview.datamodel.Sequence)
4674 // register sequence object so the XML parser can recover it.
4675 if (seqRefIds == null)
4677 seqRefIds = new HashMap<String, SequenceI>();
4679 if (seqsToIds == null)
4681 seqsToIds = new IdentityHashMap<SequenceI, String>();
4683 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4684 seqsToIds.put((SequenceI) jvobj, id);
4686 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4688 if (annotationIds == null)
4690 annotationIds = new Hashtable();
4693 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4694 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4695 if (jvann.annotationId == null)
4697 jvann.annotationId = anid;
4699 if (!jvann.annotationId.equals(anid))
4701 // TODO verify that this is the correct behaviour
4702 this.warn("Overriding Annotation ID for " + anid
4703 + " from different id : " + jvann.annotationId);
4704 jvann.annotationId = anid;
4707 else if (jvobj instanceof String)
4709 if (jvids2vobj == null)
4711 jvids2vobj = new Hashtable();
4712 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4717 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4723 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4724 * objects created from the project archive. If string is null (default for
4725 * construction) then suffix will be set automatically.
4729 public void setUniqueSetSuffix(String string)
4731 uniqueSetSuffix = string;
4736 * uses skipList2 as the skipList for skipping views on sequence sets
4737 * associated with keys in the skipList
4741 public void setSkipList(Hashtable skipList2)
4743 skipList = skipList2;