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.AlignedCodonFrame;
26 import jalview.datamodel.Alignment;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.PDBEntry;
30 import jalview.datamodel.SequenceI;
31 import jalview.datamodel.StructureViewerModel;
32 import jalview.datamodel.StructureViewerModel.StructureData;
33 import jalview.schemabinding.version2.AlcodMap;
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 AlignFrame[] frames = Desktop.getAlignFrames(); // 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 AlignFrame af = frames[i];
386 .containsKey(af.getViewport().getSequenceSetId()))
391 String shortName = af.getTitle();
393 if (shortName.indexOf(File.separatorChar) > -1)
395 shortName = shortName.substring(shortName
396 .lastIndexOf(File.separatorChar) + 1);
401 while (shortNames.contains(shortName))
403 if (shortName.endsWith("_" + (count - 1)))
405 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
408 shortName = shortName.concat("_" + count);
412 shortNames.addElement(shortName);
414 if (!shortName.endsWith(".xml"))
416 shortName = shortName + ".xml";
419 int ap, apSize = af.alignPanels.size();
421 for (ap = 0; ap < apSize; ap++)
423 AlignmentPanel apanel = af.alignPanels.get(ap);
424 String fileName = apSize == 1 ? shortName : ap + shortName;
425 if (!fileName.endsWith(".xml"))
427 fileName = fileName + ".xml";
430 saveState(apanel, fileName, jout);
432 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
434 if (!dsses.containsKey(dssid))
436 dsses.put(dssid, af);
441 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
447 } catch (Exception foo)
452 } catch (Exception ex)
454 // TODO: inform user of the problem - they need to know if their data was
456 if (errorMessage == null)
458 errorMessage = "Couldn't write Jalview Archive - see error output for details";
460 ex.printStackTrace();
464 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
465 public boolean saveAlignment(AlignFrame af, String jarFile,
471 int apSize = af.alignPanels.size();
472 FileOutputStream fos = new FileOutputStream(jarFile);
473 JarOutputStream jout = new JarOutputStream(fos);
474 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
475 for (AlignmentPanel apanel : af.alignPanels)
477 String jfileName = apSize == 1 ? fileName : fileName + ap;
479 if (!jfileName.endsWith(".xml"))
481 jfileName = jfileName + ".xml";
483 saveState(apanel, jfileName, jout);
484 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
486 if (!dsses.containsKey(dssid))
488 dsses.put(dssid, af);
491 writeDatasetFor(dsses, fileName, jout);
495 } catch (Exception foo)
501 } catch (Exception ex)
503 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
504 ex.printStackTrace();
509 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
510 String fileName, JarOutputStream jout)
513 for (String dssids : dsses.keySet())
515 AlignFrame _af = dsses.get(dssids);
516 String jfileName = fileName + " Dataset for " + _af.getTitle();
517 if (!jfileName.endsWith(".xml"))
519 jfileName = jfileName + ".xml";
521 saveState(_af.alignPanel, jfileName, true, jout);
526 * create a JalviewModel from an alignment view and marshall it to a
530 * panel to create jalview model for
532 * name of alignment panel written to output stream
538 public JalviewModel saveState(AlignmentPanel ap, String fileName,
539 JarOutputStream jout)
541 return saveState(ap, fileName, false, jout);
545 * create a JalviewModel from an alignment view and marshall it to a
549 * panel to create jalview model for
551 * name of alignment panel written to output stream
553 * when true, only write the dataset for the alignment, not the data
554 * associated with the view.
560 public JalviewModel saveState(AlignmentPanel ap, String fileName,
561 boolean storeDS, JarOutputStream jout)
564 List<String> viewIds = new ArrayList<String>();
565 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
567 AlignViewport av = ap.av;
569 JalviewModel object = new JalviewModel();
570 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
572 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
573 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
574 "Development Build"));
576 jalview.datamodel.AlignmentI jal = av.getAlignment();
578 if (av.hasHiddenRows())
580 jal = jal.getHiddenSequences().getFullAlignment();
583 SequenceSet vamsasSet = new SequenceSet();
585 JalviewModelSequence jms = new JalviewModelSequence();
587 vamsasSet.setGapChar(jal.getGapCharacter() + "");
589 if (jal.getDataset() != null)
591 // dataset id is the dataset's hashcode
592 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
595 // switch jal and the dataset
596 jal = jal.getDataset();
599 if (jal.getProperties() != null)
601 Enumeration en = jal.getProperties().keys();
602 while (en.hasMoreElements())
604 String key = en.nextElement().toString();
605 SequenceSetProperties ssp = new SequenceSetProperties();
607 ssp.setValue(jal.getProperties().get(key).toString());
608 vamsasSet.addSequenceSetProperties(ssp);
613 Set<String> calcIdSet = new HashSet<String>();
617 jalview.datamodel.SequenceI jds, jdatasq;
618 for (int i = 0; i < jal.getHeight(); i++)
620 jds = jal.getSequenceAt(i);
621 jdatasq = jds.getDatasetSequence() == null ? jds : jds
622 .getDatasetSequence();
625 if (seqRefIds.get(id) != null)
627 // This happens for two reasons: 1. multiple views are being serialised.
628 // 2. the hashCode has collided with another sequence's code. This DOES
629 // HAPPEN! (PF00072.15.stk does this)
630 // JBPNote: Uncomment to debug writing out of files that do not read
631 // back in due to ArrayOutOfBoundExceptions.
632 // System.err.println("vamsasSeq backref: "+id+"");
633 // System.err.println(jds.getName()+"
634 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
635 // System.err.println("Hashcode: "+seqHash(jds));
636 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
637 // System.err.println(rsq.getName()+"
638 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
639 // System.err.println("Hashcode: "+seqHash(rsq));
643 vamsasSeq = createVamsasSequence(id, jds);
644 vamsasSet.addSequence(vamsasSeq);
645 seqRefIds.put(id, jds);
649 jseq.setStart(jds.getStart());
650 jseq.setEnd(jds.getEnd());
651 jseq.setColour(av.getSequenceColour(jds).getRGB());
653 jseq.setId(id); // jseq id should be a string not a number
656 // Store any sequences this sequence represents
657 if (av.hasHiddenRows())
659 jseq.setHidden(av.getAlignment().getHiddenSequences()
662 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
664 jalview.datamodel.SequenceI[] reps = av
665 .getRepresentedSequences(jal.getSequenceAt(i))
666 .getSequencesInOrder(jal);
668 for (int h = 0; h < reps.length; h++)
670 if (reps[h] != jal.getSequenceAt(i))
672 jseq.addHiddenSequences(jal.findIndex(reps[h]));
679 if (jdatasq.getSequenceFeatures() != null)
681 jalview.datamodel.SequenceFeature[] sf = jdatasq
682 .getSequenceFeatures();
684 while (index < sf.length)
686 Features features = new Features();
688 features.setBegin(sf[index].getBegin());
689 features.setEnd(sf[index].getEnd());
690 features.setDescription(sf[index].getDescription());
691 features.setType(sf[index].getType());
692 features.setFeatureGroup(sf[index].getFeatureGroup());
693 features.setScore(sf[index].getScore());
694 if (sf[index].links != null)
696 for (int l = 0; l < sf[index].links.size(); l++)
698 OtherData keyValue = new OtherData();
699 keyValue.setKey("LINK_" + l);
700 keyValue.setValue(sf[index].links.elementAt(l).toString());
701 features.addOtherData(keyValue);
704 if (sf[index].otherDetails != null)
707 Enumeration keys = sf[index].otherDetails.keys();
708 while (keys.hasMoreElements())
710 key = keys.nextElement().toString();
711 OtherData keyValue = new OtherData();
712 keyValue.setKey(key);
713 keyValue.setValue(sf[index].otherDetails.get(key).toString());
714 features.addOtherData(keyValue);
718 jseq.addFeatures(features);
723 if (jdatasq.getPDBId() != null)
725 Enumeration en = jdatasq.getPDBId().elements();
726 while (en.hasMoreElements())
728 Pdbids pdb = new Pdbids();
729 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
732 pdb.setId(entry.getId());
733 pdb.setType(entry.getType());
736 * Store any structure views associated with this sequence. This
737 * section copes with duplicate entries in the project, so a dataset
738 * only view *should* be coped with sensibly.
740 // This must have been loaded, is it still visible?
741 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
742 String matchedFile = null;
743 for (int f = frames.length - 1; f > -1; f--)
745 if (frames[f] instanceof StructureViewerBase)
747 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
748 matchedFile = saveStructureState(ap, jds, pdb, entry,
749 viewIds, matchedFile, viewFrame);
753 if (matchedFile != null || entry.getFile() != null)
755 if (entry.getFile() != null)
758 matchedFile = entry.getFile();
760 pdb.setFile(matchedFile); // entry.getFile());
761 if (pdbfiles == null)
763 pdbfiles = new ArrayList<String>();
766 if (!pdbfiles.contains(entry.getId()))
768 pdbfiles.add(entry.getId());
769 DataInputStream dis = null;
772 File file = new File(matchedFile);
773 if (file.exists() && jout != null)
775 byte[] data = new byte[(int) file.length()];
776 jout.putNextEntry(new JarEntry(entry.getId()));
777 dis = new DataInputStream(new FileInputStream(file));
780 DataOutputStream dout = new DataOutputStream(jout);
781 dout.write(data, 0, data.length);
785 } catch (Exception ex)
787 ex.printStackTrace();
795 } catch (IOException e)
805 if (entry.getProperty() != null)
807 PdbentryItem item = new PdbentryItem();
808 Hashtable properties = entry.getProperty();
809 Enumeration en2 = properties.keys();
810 while (en2.hasMoreElements())
812 Property prop = new Property();
813 String key = en2.nextElement().toString();
815 prop.setValue(properties.get(key).toString());
816 item.addProperty(prop);
818 pdb.addPdbentryItem(item);
828 if (!storeDS && av.hasHiddenRows())
830 jal = av.getAlignment();
833 if (jal.getCodonFrames() != null)
835 Set<AlignedCodonFrame> jac = jal.getCodonFrames();
836 for (AlignedCodonFrame acf : jac)
838 AlcodonFrame alc = new AlcodonFrame();
839 vamsasSet.addAlcodonFrame(alc);
840 if (acf.getProtMappings() != null
841 && acf.getProtMappings().length > 0)
843 SequenceI[] dnas = acf.getdnaSeqs();
844 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
845 for (int m = 0; m < pmaps.length; m++)
847 AlcodMap alcmap = new AlcodMap();
848 alcmap.setDnasq(seqHash(dnas[m]));
849 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
851 alc.addAlcodMap(alcmap);
856 // AlcodonFrame alc = new AlcodonFrame();
857 // vamsasSet.addAlcodonFrame(alc);
858 // for (int p = 0; p < acf.aaWidth; p++)
860 // Alcodon cmap = new Alcodon();
861 // if (acf.codons[p] != null)
863 // // Null codons indicate a gapped column in the translated peptide
865 // cmap.setPos1(acf.codons[p][0]);
866 // cmap.setPos2(acf.codons[p][1]);
867 // cmap.setPos3(acf.codons[p][2]);
869 // alc.addAlcodon(cmap);
871 // if (acf.getProtMappings() != null
872 // && acf.getProtMappings().length > 0)
874 // SequenceI[] dnas = acf.getdnaSeqs();
875 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
876 // for (int m = 0; m < pmaps.length; m++)
878 // AlcodMap alcmap = new AlcodMap();
879 // alcmap.setDnasq(seqHash(dnas[m]));
880 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
882 // alc.addAlcodMap(alcmap);
889 // /////////////////////////////////
890 if (!storeDS && av.currentTree != null)
892 // FIND ANY ASSOCIATED TREES
893 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
894 if (Desktop.desktop != null)
896 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
898 for (int t = 0; t < frames.length; t++)
900 if (frames[t] instanceof TreePanel)
902 TreePanel tp = (TreePanel) frames[t];
904 if (tp.treeCanvas.av.getAlignment() == jal)
906 Tree tree = new Tree();
907 tree.setTitle(tp.getTitle());
908 tree.setCurrentTree((av.currentTree == tp.getTree()));
909 tree.setNewick(tp.getTree().toString());
910 tree.setThreshold(tp.treeCanvas.threshold);
912 tree.setFitToWindow(tp.fitToWindow.getState());
913 tree.setFontName(tp.getTreeFont().getName());
914 tree.setFontSize(tp.getTreeFont().getSize());
915 tree.setFontStyle(tp.getTreeFont().getStyle());
916 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
918 tree.setShowBootstrap(tp.bootstrapMenu.getState());
919 tree.setShowDistances(tp.distanceMenu.getState());
921 tree.setHeight(tp.getHeight());
922 tree.setWidth(tp.getWidth());
923 tree.setXpos(tp.getX());
924 tree.setYpos(tp.getY());
925 tree.setId(makeHashCode(tp, null));
934 * store forward refs from an annotationRow to any groups
936 IdentityHashMap groupRefs = new IdentityHashMap();
939 for (SequenceI sq : jal.getSequences())
941 // Store annotation on dataset sequences only
942 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
943 if (aa != null && aa.length > 0)
945 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
952 if (jal.getAlignmentAnnotation() != null)
954 // Store the annotation shown on the alignment.
955 jalview.datamodel.AlignmentAnnotation[] aa = jal
956 .getAlignmentAnnotation();
957 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
962 if (jal.getGroups() != null)
964 JGroup[] groups = new JGroup[jal.getGroups().size()];
966 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
968 groups[++i] = new JGroup();
970 groups[i].setStart(sg.getStartRes());
971 groups[i].setEnd(sg.getEndRes());
972 groups[i].setName(sg.getName());
973 if (groupRefs.containsKey(sg))
975 // group has references so set it's ID field
976 groups[i].setId(groupRefs.get(sg).toString());
980 if (sg.cs.conservationApplied())
982 groups[i].setConsThreshold(sg.cs.getConservationInc());
984 if (sg.cs instanceof jalview.schemes.UserColourScheme)
986 groups[i].setColour(setUserColourScheme(sg.cs, userColours,
992 .setColour(ColourSchemeProperty.getColourName(sg.cs));
995 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
997 groups[i].setColour("AnnotationColourGradient");
998 groups[i].setAnnotationColours(constructAnnotationColours(
999 (jalview.schemes.AnnotationColourGradient) sg.cs,
1002 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1005 .setColour(setUserColourScheme(sg.cs, userColours, jms));
1009 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1012 groups[i].setPidThreshold(sg.cs.getThreshold());
1015 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1016 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1017 groups[i].setDisplayText(sg.getDisplayText());
1018 groups[i].setColourText(sg.getColourText());
1019 groups[i].setTextCol1(sg.textColour.getRGB());
1020 groups[i].setTextCol2(sg.textColour2.getRGB());
1021 groups[i].setTextColThreshold(sg.thresholdTextColour);
1022 groups[i].setShowUnconserved(sg.getShowNonconserved());
1023 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1024 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1025 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1026 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1027 for (int s = 0; s < sg.getSize(); s++)
1029 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1031 groups[i].addSeq(seqHash(seq));
1035 jms.setJGroup(groups);
1039 // /////////SAVE VIEWPORT
1040 Viewport view = new Viewport();
1041 view.setTitle(ap.alignFrame.getTitle());
1042 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1043 av.getSequenceSetId()));
1044 view.setId(av.getViewId());
1045 view.setViewName(av.viewName);
1046 view.setGatheredViews(av.gatherViewsHere);
1048 if (ap.av.explodedPosition != null)
1050 view.setXpos(av.explodedPosition.x);
1051 view.setYpos(av.explodedPosition.y);
1052 view.setWidth(av.explodedPosition.width);
1053 view.setHeight(av.explodedPosition.height);
1057 view.setXpos(ap.alignFrame.getBounds().x);
1058 view.setYpos(ap.alignFrame.getBounds().y);
1059 view.setWidth(ap.alignFrame.getBounds().width);
1060 view.setHeight(ap.alignFrame.getBounds().height);
1063 view.setStartRes(av.startRes);
1064 view.setStartSeq(av.startSeq);
1066 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1068 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1071 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1073 AnnotationColours ac = constructAnnotationColours(
1074 (jalview.schemes.AnnotationColourGradient) av
1075 .getGlobalColourScheme(),
1078 view.setAnnotationColours(ac);
1079 view.setBgColour("AnnotationColourGradient");
1083 view.setBgColour(ColourSchemeProperty.getColourName(av
1084 .getGlobalColourScheme()));
1087 ColourSchemeI cs = av.getGlobalColourScheme();
1091 if (cs.conservationApplied())
1093 view.setConsThreshold(cs.getConservationInc());
1094 if (cs instanceof jalview.schemes.UserColourScheme)
1096 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1100 if (cs instanceof ResidueColourScheme)
1102 view.setPidThreshold(cs.getThreshold());
1106 view.setConservationSelected(av.getConservationSelected());
1107 view.setPidSelected(av.getAbovePIDThreshold());
1108 view.setFontName(av.font.getName());
1109 view.setFontSize(av.font.getSize());
1110 view.setFontStyle(av.font.getStyle());
1111 view.setRenderGaps(av.renderGaps);
1112 view.setShowAnnotation(av.isShowAnnotation());
1113 view.setShowBoxes(av.getShowBoxes());
1114 view.setShowColourText(av.getColourText());
1115 view.setShowFullId(av.getShowJVSuffix());
1116 view.setRightAlignIds(av.isRightAlignIds());
1117 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1118 view.setShowText(av.getShowText());
1119 view.setShowUnconserved(av.getShowUnconserved());
1120 view.setWrapAlignment(av.getWrapAlignment());
1121 view.setTextCol1(av.textColour.getRGB());
1122 view.setTextCol2(av.textColour2.getRGB());
1123 view.setTextColThreshold(av.thresholdTextColour);
1124 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1125 view.setShowSequenceLogo(av.isShowSequenceLogo());
1126 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1127 view.setShowGroupConsensus(av.isShowGroupConsensus());
1128 view.setShowGroupConservation(av.isShowGroupConservation());
1129 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1130 view.setShowDbRefTooltip(av.isShowDbRefs());
1131 view.setFollowHighlight(av.followHighlight);
1132 view.setFollowSelection(av.followSelection);
1133 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1134 if (av.getFeaturesDisplayed() != null)
1136 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1138 String[] renderOrder = ap.getSeqPanel().seqCanvas
1139 .getFeatureRenderer().getRenderOrder()
1140 .toArray(new String[0]);
1142 Vector settingsAdded = new Vector();
1143 Object gstyle = null;
1144 GraduatedColor gcol = null;
1145 if (renderOrder != null)
1147 for (int ro = 0; ro < renderOrder.length; ro++)
1149 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1150 .getFeatureStyle(renderOrder[ro]);
1151 Setting setting = new Setting();
1152 setting.setType(renderOrder[ro]);
1153 if (gstyle instanceof GraduatedColor)
1155 gcol = (GraduatedColor) gstyle;
1156 setting.setColour(gcol.getMaxColor().getRGB());
1157 setting.setMincolour(gcol.getMinColor().getRGB());
1158 setting.setMin(gcol.getMin());
1159 setting.setMax(gcol.getMax());
1160 setting.setColourByLabel(gcol.isColourByLabel());
1161 setting.setAutoScale(gcol.isAutoScale());
1162 setting.setThreshold(gcol.getThresh());
1163 setting.setThreshstate(gcol.getThreshType());
1167 setting.setColour(ap.getSeqPanel().seqCanvas
1168 .getFeatureRenderer()
1169 .getColour(renderOrder[ro]).getRGB());
1172 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1174 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1175 .getOrder(renderOrder[ro]);
1178 setting.setOrder(rorder);
1180 fs.addSetting(setting);
1181 settingsAdded.addElement(renderOrder[ro]);
1185 // Make sure we save none displayed feature settings
1186 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1187 .getFeatureColours().keySet().iterator();
1188 while (en.hasNext())
1190 String key = en.next().toString();
1191 if (settingsAdded.contains(key))
1196 Setting setting = new Setting();
1197 setting.setType(key);
1198 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1199 .getColour(key).getRGB());
1201 setting.setDisplay(false);
1202 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1206 setting.setOrder(rorder);
1208 fs.addSetting(setting);
1209 settingsAdded.addElement(key);
1211 // is groups actually supposed to be a map here ?
1212 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1213 .getFeatureGroups().iterator();
1214 Vector groupsAdded = new Vector();
1215 while (en.hasNext())
1217 String grp = en.next().toString();
1218 if (groupsAdded.contains(grp))
1222 Group g = new Group();
1224 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1225 .getFeatureRenderer().checkGroupVisibility(grp, false))
1228 groupsAdded.addElement(grp);
1230 jms.setFeatureSettings(fs);
1234 if (av.hasHiddenColumns())
1236 if (av.getColumnSelection() == null
1237 || av.getColumnSelection().getHiddenColumns() == null)
1239 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1243 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1246 int[] region = av.getColumnSelection().getHiddenColumns()
1248 HiddenColumns hc = new HiddenColumns();
1249 hc.setStart(region[0]);
1250 hc.setEnd(region[1]);
1251 view.addHiddenColumns(hc);
1255 if (calcIdSet.size() > 0)
1257 for (String calcId : calcIdSet)
1259 if (calcId.trim().length() > 0)
1261 CalcIdParam cidp = createCalcIdParam(calcId, av);
1262 // Some calcIds have no parameters.
1265 view.addCalcIdParam(cidp);
1271 jms.addViewport(view);
1273 object.setJalviewModelSequence(jms);
1274 object.getVamsasModel().addSequenceSet(vamsasSet);
1276 if (jout != null && fileName != null)
1278 // We may not want to write the object to disk,
1279 // eg we can copy the alignViewport to a new view object
1280 // using save and then load
1283 JarEntry entry = new JarEntry(fileName);
1284 jout.putNextEntry(entry);
1285 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1287 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1289 marshaller.marshal(object);
1292 } catch (Exception ex)
1294 // TODO: raise error in GUI if marshalling failed.
1295 ex.printStackTrace();
1302 * Save the state of a structure viewer
1307 * the archive XML element under which to save the state
1310 * @param matchedFile
1314 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1315 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1316 String matchedFile, StructureViewerBase viewFrame)
1318 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1319 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1321 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1322 final String pdbId = pdbentry.getId();
1323 if (!pdbId.equals(entry.getId())
1324 && !(entry.getId().length() > 4 && entry.getId()
1325 .toLowerCase().startsWith(pdbId.toLowerCase())))
1329 if (matchedFile == null)
1331 matchedFile = pdbentry.getFile();
1333 else if (!matchedFile.equals(pdbentry.getFile()))
1336 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1337 + pdbentry.getFile());
1341 // can get at it if the ID
1342 // match is ambiguous (e.g.
1344 String statestring = viewFrame.getStateInfo();
1346 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1348 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1349 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1351 StructureState state = new StructureState();
1352 state.setVisible(true);
1353 state.setXpos(viewFrame.getX());
1354 state.setYpos(viewFrame.getY());
1355 state.setWidth(viewFrame.getWidth());
1356 state.setHeight(viewFrame.getHeight());
1357 final String viewId = viewFrame.getViewId();
1358 state.setViewId(viewId);
1359 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1360 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1361 state.setColourByJmol(viewFrame.isColouredByViewer());
1363 * Only store each structure viewer's state once in each XML document.
1365 if (!viewIds.contains(viewId))
1367 viewIds.add(viewId);
1368 state.setContent(statestring.replaceAll("\n", ""));
1372 state.setContent("# duplicate state");
1374 pdb.addStructureState(state);
1381 private AnnotationColours constructAnnotationColours(
1382 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1383 JalviewModelSequence jms)
1385 AnnotationColours ac = new AnnotationColours();
1386 ac.setAboveThreshold(acg.getAboveThreshold());
1387 ac.setThreshold(acg.getAnnotationThreshold());
1388 ac.setAnnotation(acg.getAnnotation());
1389 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1391 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1396 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1400 ac.setMaxColour(acg.getMaxColour().getRGB());
1401 ac.setMinColour(acg.getMinColour().getRGB());
1402 ac.setPerSequence(acg.isSeqAssociated());
1403 ac.setPredefinedColours(acg.isPredefinedColours());
1407 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1408 IdentityHashMap groupRefs, AlignmentViewport av,
1409 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1412 for (int i = 0; i < aa.length; i++)
1414 Annotation an = new Annotation();
1416 if (aa[i].annotationId != null)
1418 annotationIds.put(aa[i].annotationId, aa[i]);
1421 an.setId(aa[i].annotationId);
1423 an.setVisible(aa[i].visible);
1425 an.setDescription(aa[i].description);
1427 if (aa[i].sequenceRef != null)
1429 // TODO later annotation sequenceRef should be the XML ID of the
1430 // sequence rather than its display name
1431 an.setSequenceRef(aa[i].sequenceRef.getName());
1433 if (aa[i].groupRef != null)
1435 Object groupIdr = groupRefs.get(aa[i].groupRef);
1436 if (groupIdr == null)
1438 // make a locally unique String
1439 groupRefs.put(aa[i].groupRef,
1440 groupIdr = ("" + System.currentTimeMillis()
1441 + aa[i].groupRef.getName() + groupRefs.size()));
1443 an.setGroupRef(groupIdr.toString());
1446 // store all visualization attributes for annotation
1447 an.setGraphHeight(aa[i].graphHeight);
1448 an.setCentreColLabels(aa[i].centreColLabels);
1449 an.setScaleColLabels(aa[i].scaleColLabel);
1450 an.setShowAllColLabels(aa[i].showAllColLabels);
1451 an.setBelowAlignment(aa[i].belowAlignment);
1453 if (aa[i].graph > 0)
1456 an.setGraphType(aa[i].graph);
1457 an.setGraphGroup(aa[i].graphGroup);
1458 if (aa[i].getThreshold() != null)
1460 ThresholdLine line = new ThresholdLine();
1461 line.setLabel(aa[i].getThreshold().label);
1462 line.setValue(aa[i].getThreshold().value);
1463 line.setColour(aa[i].getThreshold().colour.getRGB());
1464 an.setThresholdLine(line);
1472 an.setLabel(aa[i].label);
1474 if (aa[i] == av.getAlignmentQualityAnnot()
1475 || aa[i] == av.getAlignmentConservationAnnotation()
1476 || aa[i] == av.getAlignmentConsensusAnnotation()
1477 || aa[i].autoCalculated)
1479 // new way of indicating autocalculated annotation -
1480 an.setAutoCalculated(aa[i].autoCalculated);
1482 if (aa[i].hasScore())
1484 an.setScore(aa[i].getScore());
1487 if (aa[i].getCalcId() != null)
1489 calcIdSet.add(aa[i].getCalcId());
1490 an.setCalcId(aa[i].getCalcId());
1492 if (aa[i].hasProperties())
1494 for (String pr : aa[i].getProperties())
1496 Property prop = new Property();
1498 prop.setValue(aa[i].getProperty(pr));
1499 an.addProperty(prop);
1503 AnnotationElement ae;
1504 if (aa[i].annotations != null)
1506 an.setScoreOnly(false);
1507 for (int a = 0; a < aa[i].annotations.length; a++)
1509 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1514 ae = new AnnotationElement();
1515 if (aa[i].annotations[a].description != null)
1517 ae.setDescription(aa[i].annotations[a].description);
1519 if (aa[i].annotations[a].displayCharacter != null)
1521 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1524 if (!Float.isNaN(aa[i].annotations[a].value))
1526 ae.setValue(aa[i].annotations[a].value);
1530 if (aa[i].annotations[a].secondaryStructure > ' ')
1532 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1536 if (aa[i].annotations[a].colour != null
1537 && aa[i].annotations[a].colour != java.awt.Color.black)
1539 ae.setColour(aa[i].annotations[a].colour.getRGB());
1542 an.addAnnotationElement(ae);
1543 if (aa[i].autoCalculated)
1545 // only write one non-null entry into the annotation row -
1546 // sufficient to get the visualization attributes necessary to
1554 an.setScoreOnly(true);
1556 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1558 // skip autocalculated annotation - these are only provided for
1560 vamsasSet.addAnnotation(an);
1566 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1568 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1569 if (settings != null)
1571 CalcIdParam vCalcIdParam = new CalcIdParam();
1572 vCalcIdParam.setCalcId(calcId);
1573 vCalcIdParam.addServiceURL(settings.getServiceURI());
1574 // generic URI allowing a third party to resolve another instance of the
1575 // service used for this calculation
1576 for (String urls : settings.getServiceURLs())
1578 vCalcIdParam.addServiceURL(urls);
1580 vCalcIdParam.setVersion("1.0");
1581 if (settings.getPreset() != null)
1583 WsParamSetI setting = settings.getPreset();
1584 vCalcIdParam.setName(setting.getName());
1585 vCalcIdParam.setDescription(setting.getDescription());
1589 vCalcIdParam.setName("");
1590 vCalcIdParam.setDescription("Last used parameters");
1592 // need to be able to recover 1) settings 2) user-defined presets or
1593 // recreate settings from preset 3) predefined settings provided by
1594 // service - or settings that can be transferred (or discarded)
1595 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1597 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1598 // todo - decide if updateImmediately is needed for any projects.
1600 return vCalcIdParam;
1605 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1608 if (calcIdParam.getVersion().equals("1.0"))
1610 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1611 .getPreferredServiceFor(calcIdParam.getServiceURL());
1612 if (service != null)
1614 WsParamSetI parmSet = null;
1617 parmSet = service.getParamStore().parseServiceParameterFile(
1618 calcIdParam.getName(), calcIdParam.getDescription(),
1619 calcIdParam.getServiceURL(),
1620 calcIdParam.getParameters().replace("|\\n|", "\n"));
1621 } catch (IOException x)
1623 warn("Couldn't parse parameter data for "
1624 + calcIdParam.getCalcId(), x);
1627 List<ArgumentI> argList = null;
1628 if (calcIdParam.getName().length() > 0)
1630 parmSet = service.getParamStore()
1631 .getPreset(calcIdParam.getName());
1632 if (parmSet != null)
1634 // TODO : check we have a good match with settings in AACon -
1635 // otherwise we'll need to create a new preset
1640 argList = parmSet.getArguments();
1643 AAConSettings settings = new AAConSettings(
1644 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1645 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1646 calcIdParam.isNeedsUpdate());
1651 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1655 throw new Error(MessageManager.formatMessage(
1656 "error.unsupported_version_calcIdparam", new String[]
1657 { calcIdParam.toString() }));
1661 * External mapping between jalview objects and objects yielding a valid and
1662 * unique object ID string. This is null for normal Jalview project IO, but
1663 * non-null when a jalview project is being read or written as part of a
1666 IdentityHashMap jv2vobj = null;
1669 * Construct a unique ID for jvobj using either existing bindings or if none
1670 * exist, the result of the hashcode call for the object.
1673 * jalview data object
1674 * @return unique ID for referring to jvobj
1676 private String makeHashCode(Object jvobj, String altCode)
1678 if (jv2vobj != null)
1680 Object id = jv2vobj.get(jvobj);
1683 return id.toString();
1685 // check string ID mappings
1686 if (jvids2vobj != null && jvobj instanceof String)
1688 id = jvids2vobj.get(jvobj);
1692 return id.toString();
1694 // give up and warn that something has gone wrong
1695 warn("Cannot find ID for object in external mapping : " + jvobj);
1701 * return local jalview object mapped to ID, if it exists
1705 * @return null or object bound to idcode
1707 private Object retrieveExistingObj(String idcode)
1709 if (idcode != null && vobj2jv != null)
1711 return vobj2jv.get(idcode);
1717 * binding from ID strings from external mapping table to jalview data model
1720 private Hashtable vobj2jv;
1722 private Sequence createVamsasSequence(String id, SequenceI jds)
1724 return createVamsasSequence(true, id, jds, null);
1727 private Sequence createVamsasSequence(boolean recurse, String id,
1728 SequenceI jds, SequenceI parentseq)
1730 Sequence vamsasSeq = new Sequence();
1731 vamsasSeq.setId(id);
1732 vamsasSeq.setName(jds.getName());
1733 vamsasSeq.setSequence(jds.getSequenceAsString());
1734 vamsasSeq.setDescription(jds.getDescription());
1735 jalview.datamodel.DBRefEntry[] dbrefs = null;
1736 if (jds.getDatasetSequence() != null)
1738 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1739 if (jds.getDatasetSequence().getDBRef() != null)
1741 dbrefs = jds.getDatasetSequence().getDBRef();
1746 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1747 // dataset sequences only
1748 dbrefs = jds.getDBRef();
1752 for (int d = 0; d < dbrefs.length; d++)
1754 DBRef dbref = new DBRef();
1755 dbref.setSource(dbrefs[d].getSource());
1756 dbref.setVersion(dbrefs[d].getVersion());
1757 dbref.setAccessionId(dbrefs[d].getAccessionId());
1758 if (dbrefs[d].hasMap())
1760 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1762 dbref.setMapping(mp);
1764 vamsasSeq.addDBRef(dbref);
1770 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1771 SequenceI parentseq, SequenceI jds, boolean recurse)
1774 if (jmp.getMap() != null)
1778 jalview.util.MapList mlst = jmp.getMap();
1779 int r[] = mlst.getFromRanges();
1780 for (int s = 0; s < r.length; s += 2)
1782 MapListFrom mfrom = new MapListFrom();
1783 mfrom.setStart(r[s]);
1784 mfrom.setEnd(r[s + 1]);
1785 mp.addMapListFrom(mfrom);
1787 r = mlst.getToRanges();
1788 for (int s = 0; s < r.length; s += 2)
1790 MapListTo mto = new MapListTo();
1792 mto.setEnd(r[s + 1]);
1793 mp.addMapListTo(mto);
1795 mp.setMapFromUnit(mlst.getFromRatio());
1796 mp.setMapToUnit(mlst.getToRatio());
1797 if (jmp.getTo() != null)
1799 MappingChoice mpc = new MappingChoice();
1801 && (parentseq != jmp.getTo() || parentseq
1802 .getDatasetSequence() != jmp.getTo()))
1804 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1810 SequenceI ps = null;
1811 if (parentseq != jmp.getTo()
1812 && parentseq.getDatasetSequence() != jmp.getTo())
1814 // chaining dbref rather than a handshaking one
1815 jmpid = seqHash(ps = jmp.getTo());
1819 jmpid = seqHash(ps = parentseq);
1821 mpc.setDseqFor(jmpid);
1822 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1824 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1825 seqRefIds.put(mpc.getDseqFor(), ps);
1829 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1832 mp.setMappingChoice(mpc);
1838 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
1839 List<UserColourScheme> userColours, JalviewModelSequence jms)
1842 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1843 boolean newucs = false;
1844 if (!userColours.contains(ucs))
1846 userColours.add(ucs);
1849 id = "ucs" + userColours.indexOf(ucs);
1852 // actually create the scheme's entry in the XML model
1853 java.awt.Color[] colours = ucs.getColours();
1854 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1855 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1857 for (int i = 0; i < colours.length; i++)
1859 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1860 col.setName(ResidueProperties.aa[i]);
1861 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1862 jbucs.addColour(col);
1864 if (ucs.getLowerCaseColours() != null)
1866 colours = ucs.getLowerCaseColours();
1867 for (int i = 0; i < colours.length; i++)
1869 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1870 col.setName(ResidueProperties.aa[i].toLowerCase());
1871 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1872 jbucs.addColour(col);
1877 uc.setUserColourScheme(jbucs);
1878 jms.addUserColours(uc);
1884 jalview.schemes.UserColourScheme getUserColourScheme(
1885 JalviewModelSequence jms, String id)
1887 UserColours[] uc = jms.getUserColours();
1888 UserColours colours = null;
1890 for (int i = 0; i < uc.length; i++)
1892 if (uc[i].getId().equals(id))
1900 java.awt.Color[] newColours = new java.awt.Color[24];
1902 for (int i = 0; i < 24; i++)
1904 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1905 .getUserColourScheme().getColour(i).getRGB(), 16));
1908 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1911 if (colours.getUserColourScheme().getColourCount() > 24)
1913 newColours = new java.awt.Color[23];
1914 for (int i = 0; i < 23; i++)
1916 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1917 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1919 ucs.setLowerCaseColours(newColours);
1926 * contains last error message (if any) encountered by XML loader.
1928 String errorMessage = null;
1931 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1932 * exceptions are raised during project XML parsing
1934 public boolean attemptversion1parse = true;
1937 * Load a jalview project archive from a jar file
1940 * - HTTP URL or filename
1942 public AlignFrame loadJalviewAlign(final String file)
1945 jalview.gui.AlignFrame af = null;
1949 // create list to store references for any new Jmol viewers created
1950 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1951 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1952 // Workaround is to make sure caller implements the JarInputStreamProvider
1954 // so we can re-open the jar input stream for each entry.
1956 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1957 af = loadJalviewAlign(jprovider);
1959 } catch (MalformedURLException e)
1961 errorMessage = "Invalid URL format for '" + file + "'";
1967 SwingUtilities.invokeAndWait(new Runnable()
1971 setLoadingFinishedForNewStructureViewers();
1974 } catch (Exception x)
1982 private jarInputStreamProvider createjarInputStreamProvider(
1983 final String file) throws MalformedURLException
1986 errorMessage = null;
1987 uniqueSetSuffix = null;
1989 viewportsAdded = null;
1990 frefedSequence = null;
1992 if (file.startsWith("http://"))
1994 url = new URL(file);
1996 final URL _url = url;
1997 return new jarInputStreamProvider()
2001 public JarInputStream getJarInputStream() throws IOException
2005 return new JarInputStream(_url.openStream());
2009 return new JarInputStream(new FileInputStream(file));
2014 public String getFilename()
2022 * Recover jalview session from a jalview project archive. Caller may
2023 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2024 * themselves. Any null fields will be initialised with default values,
2025 * non-null fields are left alone.
2030 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2032 errorMessage = null;
2033 if (uniqueSetSuffix == null)
2035 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2037 if (seqRefIds == null)
2039 seqRefIds = new HashMap<String, SequenceI>();
2041 if (viewportsAdded == null)
2043 viewportsAdded = new Hashtable();
2045 if (frefedSequence == null)
2047 frefedSequence = new Vector();
2050 jalview.gui.AlignFrame af = null, _af = null;
2051 Hashtable gatherToThisFrame = new Hashtable();
2052 final String file = jprovider.getFilename();
2055 JarInputStream jin = null;
2056 JarEntry jarentry = null;
2061 jin = jprovider.getJarInputStream();
2062 for (int i = 0; i < entryCount; i++)
2064 jarentry = jin.getNextJarEntry();
2067 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2069 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2070 JalviewModel object = new JalviewModel();
2072 Unmarshaller unmar = new Unmarshaller(object);
2073 unmar.setValidation(false);
2074 object = (JalviewModel) unmar.unmarshal(in);
2075 if (true) // !skipViewport(object))
2077 _af = loadFromObject(object, file, true, jprovider);
2078 if (object.getJalviewModelSequence().getViewportCount() > 0)
2081 if (af.viewport.gatherViewsHere)
2083 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2089 else if (jarentry != null)
2091 // Some other file here.
2094 } while (jarentry != null);
2095 resolveFrefedSequences();
2096 } catch (java.io.FileNotFoundException ex)
2098 ex.printStackTrace();
2099 errorMessage = "Couldn't locate Jalview XML file : " + file;
2100 System.err.println("Exception whilst loading jalview XML file : "
2102 } catch (java.net.UnknownHostException ex)
2104 ex.printStackTrace();
2105 errorMessage = "Couldn't locate Jalview XML file : " + file;
2106 System.err.println("Exception whilst loading jalview XML file : "
2108 } catch (Exception ex)
2110 System.err.println("Parsing as Jalview Version 2 file failed.");
2111 ex.printStackTrace(System.err);
2112 if (attemptversion1parse)
2114 // Is Version 1 Jar file?
2117 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2118 } catch (Exception ex2)
2120 System.err.println("Exception whilst loading as jalviewXMLV1:");
2121 ex2.printStackTrace();
2125 if (Desktop.instance != null)
2127 Desktop.instance.stopLoading();
2131 System.out.println("Successfully loaded archive file");
2134 ex.printStackTrace();
2136 System.err.println("Exception whilst loading jalview XML file : "
2138 } catch (OutOfMemoryError e)
2140 // Don't use the OOM Window here
2141 errorMessage = "Out of memory loading jalview XML file";
2142 System.err.println("Out of memory whilst loading jalview XML file");
2143 e.printStackTrace();
2146 if (Desktop.instance != null)
2148 Desktop.instance.stopLoading();
2151 Enumeration en = gatherToThisFrame.elements();
2152 while (en.hasMoreElements())
2154 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2156 if (errorMessage != null)
2164 * check errorMessage for a valid error message and raise an error box in the
2165 * GUI or write the current errorMessage to stderr and then clear the error
2168 protected void reportErrors()
2170 reportErrors(false);
2173 protected void reportErrors(final boolean saving)
2175 if (errorMessage != null)
2177 final String finalErrorMessage = errorMessage;
2180 javax.swing.SwingUtilities.invokeLater(new Runnable()
2185 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2186 finalErrorMessage, "Error "
2187 + (saving ? "saving" : "loading")
2188 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2194 System.err.println("Problem loading Jalview file: " + errorMessage);
2197 errorMessage = null;
2200 Hashtable<String, String> alreadyLoadedPDB;
2203 * when set, local views will be updated from view stored in JalviewXML
2204 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2205 * sync if this is set to true.
2207 private final boolean updateLocalViews = false;
2209 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2211 if (alreadyLoadedPDB == null)
2213 alreadyLoadedPDB = new Hashtable();
2216 if (alreadyLoadedPDB.containsKey(pdbId))
2218 return alreadyLoadedPDB.get(pdbId).toString();
2223 JarInputStream jin = jprovider.getJarInputStream();
2225 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2226 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2227 * FileInputStream(jprovider)); }
2230 JarEntry entry = null;
2233 entry = jin.getNextJarEntry();
2234 } while (entry != null && !entry.getName().equals(pdbId));
2237 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2238 File outFile = File.createTempFile("jalview_pdb", ".txt");
2239 outFile.deleteOnExit();
2240 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2243 while ((data = in.readLine()) != null)
2250 } catch (Exception foo)
2255 String t = outFile.getAbsolutePath();
2256 alreadyLoadedPDB.put(pdbId, t);
2261 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2263 } catch (Exception ex)
2265 ex.printStackTrace();
2271 private class JvAnnotRow
2273 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2280 * persisted version of annotation row from which to take vis properties
2282 public jalview.datamodel.AlignmentAnnotation template;
2285 * original position of the annotation row in the alignment
2291 * Load alignment frame from jalview XML DOM object
2296 * filename source string
2297 * @param loadTreesAndStructures
2298 * when false only create Viewport
2300 * data source provider
2301 * @return alignment frame created from view stored in DOM
2303 AlignFrame loadFromObject(JalviewModel object, String file,
2304 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2306 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2307 Sequence[] vamsasSeq = vamsasSet.getSequence();
2309 JalviewModelSequence jms = object.getJalviewModelSequence();
2311 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2314 // ////////////////////////////////
2317 Vector hiddenSeqs = null;
2318 jalview.datamodel.Sequence jseq;
2320 ArrayList tmpseqs = new ArrayList();
2322 boolean multipleView = false;
2324 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2325 int vi = 0; // counter in vamsasSeq array
2326 for (int i = 0; i < jseqs.length; i++)
2328 String seqId = jseqs[i].getId();
2330 if (seqRefIds.get(seqId) != null)
2332 tmpseqs.add(seqRefIds.get(seqId));
2333 multipleView = true;
2337 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2338 vamsasSeq[vi].getSequence());
2339 jseq.setDescription(vamsasSeq[vi].getDescription());
2340 jseq.setStart(jseqs[i].getStart());
2341 jseq.setEnd(jseqs[i].getEnd());
2342 jseq.setVamsasId(uniqueSetSuffix + seqId);
2343 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2348 if (jseqs[i].getHidden())
2350 if (hiddenSeqs == null)
2352 hiddenSeqs = new Vector();
2355 hiddenSeqs.addElement(seqRefIds.get(seqId));
2361 // Create the alignment object from the sequence set
2362 // ///////////////////////////////
2363 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2366 tmpseqs.toArray(orderedSeqs);
2368 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2371 // / Add the alignment properties
2372 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2374 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2375 al.setProperty(ssp.getKey(), ssp.getValue());
2379 // SequenceFeatures are added to the DatasetSequence,
2380 // so we must create or recover the dataset before loading features
2381 // ///////////////////////////////
2382 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2384 // older jalview projects do not have a dataset id.
2385 al.setDataset(null);
2389 // recover dataset - passing on flag indicating if this a 'viewless'
2390 // sequence set (a.k.a. a stored dataset for the project)
2391 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2392 .getViewportCount() == 0);
2394 // ///////////////////////////////
2396 Hashtable pdbloaded = new Hashtable();
2399 // load sequence features, database references and any associated PDB
2400 // structures for the alignment
2401 for (int i = 0; i < vamsasSeq.length; i++)
2403 if (jseqs[i].getFeaturesCount() > 0)
2405 Features[] features = jseqs[i].getFeatures();
2406 for (int f = 0; f < features.length; f++)
2408 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2409 features[f].getType(), features[f].getDescription(),
2410 features[f].getStatus(), features[f].getBegin(),
2411 features[f].getEnd(), features[f].getFeatureGroup());
2413 sf.setScore(features[f].getScore());
2414 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2416 OtherData keyValue = features[f].getOtherData(od);
2417 if (keyValue.getKey().startsWith("LINK"))
2419 sf.addLink(keyValue.getValue());
2423 sf.setValue(keyValue.getKey(), keyValue.getValue());
2428 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2431 if (vamsasSeq[i].getDBRefCount() > 0)
2433 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2435 if (jseqs[i].getPdbidsCount() > 0)
2437 Pdbids[] ids = jseqs[i].getPdbids();
2438 for (int p = 0; p < ids.length; p++)
2440 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2441 entry.setId(ids[p].getId());
2442 entry.setType(ids[p].getType());
2443 if (ids[p].getFile() != null)
2445 if (!pdbloaded.containsKey(ids[p].getFile()))
2447 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2451 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2454 StructureSelectionManager.getStructureSelectionManager(
2455 Desktop.instance).registerPDBEntry(entry);
2456 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2460 } // end !multipleview
2462 // ///////////////////////////////
2463 // LOAD SEQUENCE MAPPINGS
2465 if (vamsasSet.getAlcodonFrameCount() > 0)
2467 // TODO Potentially this should only be done once for all views of an
2469 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2470 for (int i = 0; i < alc.length; i++)
2472 AlignedCodonFrame cf = new AlignedCodonFrame();
2473 if (alc[i].getAlcodMapCount() > 0)
2475 AlcodMap[] maps = alc[i].getAlcodMap();
2476 for (int m = 0; m < maps.length; m++)
2478 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2480 jalview.datamodel.Mapping mapping = null;
2481 // attach to dna sequence reference.
2482 if (maps[m].getMapping() != null)
2484 mapping = addMapping(maps[m].getMapping());
2488 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2493 frefedSequence.add(new Object[]
2494 { maps[m].getDnasq(), cf, mapping });
2498 al.addCodonFrame(cf);
2502 // ////////////////////////////////
2504 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2506 * store any annotations which forward reference a group's ID
2508 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2510 if (vamsasSet.getAnnotationCount() > 0)
2512 Annotation[] an = vamsasSet.getAnnotation();
2514 for (int i = 0; i < an.length; i++)
2517 * test if annotation is automatically calculated for this view only
2519 boolean autoForView = false;
2520 if (an[i].getLabel().equals("Quality")
2521 || an[i].getLabel().equals("Conservation")
2522 || an[i].getLabel().equals("Consensus"))
2524 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2526 if (!an[i].hasAutoCalculated())
2528 an[i].setAutoCalculated(true);
2532 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2534 // remove ID - we don't recover annotation from other views for
2535 // view-specific annotation
2539 // set visiblity for other annotation in this view
2540 if (an[i].getId() != null
2541 && annotationIds.containsKey(an[i].getId()))
2543 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2544 .get(an[i].getId());
2545 // in principle Visible should always be true for annotation displayed
2546 // in multiple views
2547 if (an[i].hasVisible())
2549 jda.visible = an[i].getVisible();
2552 al.addAnnotation(jda);
2556 // Construct new annotation from model.
2557 AnnotationElement[] ae = an[i].getAnnotationElement();
2558 jalview.datamodel.Annotation[] anot = null;
2559 java.awt.Color firstColour = null;
2561 if (!an[i].getScoreOnly())
2563 anot = new jalview.datamodel.Annotation[al.getWidth()];
2564 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2566 anpos = ae[aa].getPosition();
2568 if (anpos >= anot.length)
2573 anot[anpos] = new jalview.datamodel.Annotation(
2575 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2576 (ae[aa].getSecondaryStructure() == null || ae[aa]
2577 .getSecondaryStructure().length() == 0) ? ' '
2578 : ae[aa].getSecondaryStructure().charAt(0),
2582 // JBPNote: Consider verifying dataflow for IO of secondary
2583 // structure annotation read from Stockholm files
2584 // this was added to try to ensure that
2585 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2587 // anot[ae[aa].getPosition()].displayCharacter = "";
2589 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2590 if (firstColour == null)
2592 firstColour = anot[anpos].colour;
2596 jalview.datamodel.AlignmentAnnotation jaa = null;
2598 if (an[i].getGraph())
2600 float llim = 0, hlim = 0;
2601 // if (autoForView || an[i].isAutoCalculated()) {
2604 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2605 an[i].getDescription(), anot, llim, hlim,
2606 an[i].getGraphType());
2608 jaa.graphGroup = an[i].getGraphGroup();
2609 jaa._linecolour = firstColour;
2610 if (an[i].getThresholdLine() != null)
2612 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2613 .getThresholdLine().getValue(), an[i]
2614 .getThresholdLine().getLabel(), new java.awt.Color(
2615 an[i].getThresholdLine().getColour())));
2618 if (autoForView || an[i].isAutoCalculated())
2620 // Hardwire the symbol display line to ensure that labels for
2621 // histograms are displayed
2627 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2628 an[i].getDescription(), anot);
2629 jaa._linecolour = firstColour;
2631 // register new annotation
2632 if (an[i].getId() != null)
2634 annotationIds.put(an[i].getId(), jaa);
2635 jaa.annotationId = an[i].getId();
2637 // recover sequence association
2638 if (an[i].getSequenceRef() != null)
2640 if (al.findName(an[i].getSequenceRef()) != null)
2642 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2644 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2647 // and make a note of any group association
2648 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2650 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2651 .get(an[i].getGroupRef());
2654 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2655 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2660 if (an[i].hasScore())
2662 jaa.setScore(an[i].getScore());
2664 if (an[i].hasVisible())
2666 jaa.visible = an[i].getVisible();
2669 if (an[i].hasCentreColLabels())
2671 jaa.centreColLabels = an[i].getCentreColLabels();
2674 if (an[i].hasScaleColLabels())
2676 jaa.scaleColLabel = an[i].getScaleColLabels();
2678 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2680 // newer files have an 'autoCalculated' flag and store calculation
2681 // state in viewport properties
2682 jaa.autoCalculated = true; // means annotation will be marked for
2683 // update at end of load.
2685 if (an[i].hasGraphHeight())
2687 jaa.graphHeight = an[i].getGraphHeight();
2689 if (an[i].hasBelowAlignment())
2691 jaa.belowAlignment = an[i].isBelowAlignment();
2693 jaa.setCalcId(an[i].getCalcId());
2694 if (an[i].getPropertyCount() > 0)
2696 for (jalview.schemabinding.version2.Property prop : an[i]
2699 jaa.setProperty(prop.getName(), prop.getValue());
2702 if (jaa.autoCalculated)
2704 autoAlan.add(new JvAnnotRow(i, jaa));
2707 // if (!autoForView)
2709 // add autocalculated group annotation and any user created annotation
2711 al.addAnnotation(jaa);
2715 // ///////////////////////
2717 // Create alignment markup and styles for this view
2718 if (jms.getJGroupCount() > 0)
2720 JGroup[] groups = jms.getJGroup();
2721 boolean addAnnotSchemeGroup = false;
2722 for (int i = 0; i < groups.length; i++)
2724 ColourSchemeI cs = null;
2726 if (groups[i].getColour() != null)
2728 if (groups[i].getColour().startsWith("ucs"))
2730 cs = getUserColourScheme(jms, groups[i].getColour());
2732 else if (groups[i].getColour().equals("AnnotationColourGradient")
2733 && groups[i].getAnnotationColours() != null)
2735 addAnnotSchemeGroup = true;
2740 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2745 cs.setThreshold(groups[i].getPidThreshold(), true);
2749 Vector seqs = new Vector();
2751 for (int s = 0; s < groups[i].getSeqCount(); s++)
2753 String seqId = groups[i].getSeq(s) + "";
2754 jalview.datamodel.SequenceI ts = seqRefIds.get(seqId);
2758 seqs.addElement(ts);
2762 if (seqs.size() < 1)
2767 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2768 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2769 groups[i].getDisplayText(), groups[i].getColourText(),
2770 groups[i].getStart(), groups[i].getEnd());
2772 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2774 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2775 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2776 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2777 .isShowUnconserved() : false);
2778 sg.thresholdTextColour = groups[i].getTextColThreshold();
2779 if (groups[i].hasShowConsensusHistogram())
2781 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2784 if (groups[i].hasShowSequenceLogo())
2786 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2788 if (groups[i].hasNormaliseSequenceLogo())
2790 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2792 if (groups[i].hasIgnoreGapsinConsensus())
2794 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2796 if (groups[i].getConsThreshold() != 0)
2798 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2799 "All", ResidueProperties.propHash, 3,
2800 sg.getSequences(null), 0, sg.getWidth() - 1);
2802 c.verdict(false, 25);
2803 sg.cs.setConservation(c);
2806 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2808 // re-instate unique group/annotation row reference
2809 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2810 .get(groups[i].getId());
2813 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2816 if (jaa.autoCalculated)
2818 // match up and try to set group autocalc alignment row for this
2820 if (jaa.label.startsWith("Consensus for "))
2822 sg.setConsensus(jaa);
2824 // match up and try to set group autocalc alignment row for this
2826 if (jaa.label.startsWith("Conservation for "))
2828 sg.setConservationRow(jaa);
2835 if (addAnnotSchemeGroup)
2837 // reconstruct the annotation colourscheme
2838 sg.cs = constructAnnotationColour(
2839 groups[i].getAnnotationColours(), null, al, jms, false);
2845 // only dataset in this model, so just return.
2848 // ///////////////////////////////
2851 // If we just load in the same jar file again, the sequenceSetId
2852 // will be the same, and we end up with multiple references
2853 // to the same sequenceSet. We must modify this id on load
2854 // so that each load of the file gives a unique id
2855 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2856 String viewId = (view.getId() == null ? null : view.getId()
2858 AlignFrame af = null;
2859 AlignViewport av = null;
2860 // now check to see if we really need to create a new viewport.
2861 if (multipleView && viewportsAdded.size() == 0)
2863 // We recovered an alignment for which a viewport already exists.
2864 // TODO: fix up any settings necessary for overlaying stored state onto
2865 // state recovered from another document. (may not be necessary).
2866 // we may need a binding from a viewport in memory to one recovered from
2868 // and then recover its containing af to allow the settings to be applied.
2869 // TODO: fix for vamsas demo
2871 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2873 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2874 if (seqsetobj != null)
2876 if (seqsetobj instanceof String)
2878 uniqueSeqSetId = (String) seqsetobj;
2880 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2886 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2892 * indicate that annotation colours are applied across all groups (pre
2893 * Jalview 2.8.1 behaviour)
2895 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2896 object.getVersion());
2898 AlignmentPanel ap = null;
2899 boolean isnewview = true;
2902 // Check to see if this alignment already has a view id == viewId
2903 jalview.gui.AlignmentPanel views[] = Desktop
2904 .getAlignmentPanels(uniqueSeqSetId);
2905 if (views != null && views.length > 0)
2907 for (int v = 0; v < views.length; v++)
2909 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2911 // recover the existing alignpanel, alignframe, viewport
2912 af = views[v].alignFrame;
2915 // TODO: could even skip resetting view settings if we don't want to
2916 // change the local settings from other jalview processes
2925 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
2926 uniqueSeqSetId, viewId, autoAlan);
2931 // /////////////////////////////////////
2932 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2936 for (int t = 0; t < jms.getTreeCount(); t++)
2939 Tree tree = jms.getTree(t);
2941 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2944 tp = af.ShowNewickTree(
2945 new jalview.io.NewickFile(tree.getNewick()),
2946 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2947 tree.getXpos(), tree.getYpos());
2948 if (tree.getId() != null)
2950 // perhaps bind the tree id to something ?
2955 // update local tree attributes ?
2956 // TODO: should check if tp has been manipulated by user - if so its
2957 // settings shouldn't be modified
2958 tp.setTitle(tree.getTitle());
2959 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2960 .getWidth(), tree.getHeight()));
2961 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2964 tp.treeCanvas.av = av; // af.viewport;
2965 tp.treeCanvas.ap = ap; // af.alignPanel;
2970 warn("There was a problem recovering stored Newick tree: \n"
2971 + tree.getNewick());
2975 tp.fitToWindow.setState(tree.getFitToWindow());
2976 tp.fitToWindow_actionPerformed(null);
2978 if (tree.getFontName() != null)
2980 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2981 .getFontStyle(), tree.getFontSize()));
2985 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2986 .getFontStyle(), tree.getFontSize()));
2989 tp.showPlaceholders(tree.getMarkUnlinked());
2990 tp.showBootstrap(tree.getShowBootstrap());
2991 tp.showDistances(tree.getShowDistances());
2993 tp.treeCanvas.threshold = tree.getThreshold();
2995 if (tree.getCurrentTree())
2997 af.viewport.setCurrentTree(tp.getTree());
3001 } catch (Exception ex)
3003 ex.printStackTrace();
3007 // //LOAD STRUCTURES
3008 if (loadTreesAndStructures)
3010 loadStructures(jprovider, jseqs, af, ap);
3012 // and finally return.
3017 * Load and link any saved structure viewers.
3024 protected void loadStructures(jarInputStreamProvider jprovider,
3025 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3028 * Run through all PDB ids on the alignment, and collect mappings between
3029 * distinct view ids and all sequences referring to that view.
3031 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3033 for (int i = 0; i < jseqs.length; i++)
3035 if (jseqs[i].getPdbidsCount() > 0)
3037 Pdbids[] ids = jseqs[i].getPdbids();
3038 for (int p = 0; p < ids.length; p++)
3040 final int structureStateCount = ids[p].getStructureStateCount();
3041 for (int s = 0; s < structureStateCount; s++)
3043 // check to see if we haven't already created this structure view
3044 final StructureState structureState = ids[p]
3045 .getStructureState(s);
3046 String sviewid = (structureState.getViewId() == null) ? null
3047 : structureState.getViewId() + uniqueSetSuffix;
3048 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3049 // Originally : ids[p].getFile()
3050 // : TODO: verify external PDB file recovery still works in normal
3051 // jalview project load
3052 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3053 jpdb.setId(ids[p].getId());
3055 int x = structureState.getXpos();
3056 int y = structureState.getYpos();
3057 int width = structureState.getWidth();
3058 int height = structureState.getHeight();
3060 // Probably don't need to do this anymore...
3061 // Desktop.desktop.getComponentAt(x, y);
3062 // TODO: NOW: check that this recovers the PDB file correctly.
3063 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3064 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3066 if (sviewid == null)
3068 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3071 if (!structureViewers.containsKey(sviewid))
3073 structureViewers.put(sviewid, new StructureViewerModel(x, y,
3074 width, height, false, false, true));
3075 // Legacy pre-2.7 conversion JAL-823 :
3076 // do not assume any view has to be linked for colour by
3080 // assemble String[] { pdb files }, String[] { id for each
3081 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3082 // seqs_file 2}, boolean[] {
3083 // linkAlignPanel,superposeWithAlignpanel}} from hash
3084 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3085 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3086 | (structureState.hasAlignwithAlignPanel() ? structureState
3087 .getAlignwithAlignPanel() : false));
3090 * Default colour by linked panel to false if not specified (e.g.
3091 * for pre-2.7 projects)
3093 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3094 colourWithAlignPanel |= (structureState
3095 .hasColourwithAlignPanel() ? structureState
3096 .getColourwithAlignPanel() : false);
3097 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3100 * Default colour by viewer to true if not specified (e.g. for
3103 boolean colourByViewer = jmoldat.isColourByViewer();
3104 colourByViewer &= structureState.hasColourByJmol() ? structureState
3105 .getColourByJmol() : true;
3106 jmoldat.setColourByViewer(colourByViewer);
3108 if (jmoldat.getStateData().length() < structureState
3109 .getContent().length())
3112 jmoldat.setStateData(structureState.getContent());
3115 if (ids[p].getFile() != null)
3117 File mapkey = new File(ids[p].getFile());
3118 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3119 if (seqstrmaps == null)
3121 jmoldat.getFileData().put(
3123 seqstrmaps = jmoldat.new StructureData(pdbFile,
3126 if (!seqstrmaps.getSeqList().contains(seq))
3128 seqstrmaps.getSeqList().add(seq);
3134 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");
3141 // Instantiate the associated structure views
3142 for (Entry<String, StructureViewerModel> entry : structureViewers
3145 createOrLinkStructureViewer(entry, af, ap);
3155 protected void createOrLinkStructureViewer(
3156 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3159 final StructureViewerModel svattrib = viewerData.getValue();
3162 * Search for any viewer windows already open from other alignment views
3163 * that exactly match the stored structure state
3165 StructureViewerBase comp = findMatchingViewer(viewerData);
3169 linkStructureViewer(ap, comp, svattrib);
3174 * Pending an XML element for ViewerType, just check if stateData contains
3175 * "chimera" (part of the chimera session filename).
3177 if (svattrib.getStateData().indexOf("chimera") > -1)
3179 createChimeraViewer(viewerData, af);
3183 createJmolViewer(viewerData, af);
3188 * Create a new Chimera viewer.
3193 protected void createChimeraViewer(
3194 Entry<String, StructureViewerModel> viewerData, AlignFrame af)
3196 final StructureViewerModel data = viewerData.getValue();
3197 String chimeraSession = data.getStateData();
3199 if (new File(chimeraSession).exists())
3201 Set<Entry<File, StructureData>> fileData = data.getFileData()
3203 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3204 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3205 for (Entry<File, StructureData> pdb : fileData)
3207 String filePath = pdb.getValue().getFilePath();
3208 String pdbId = pdb.getValue().getPdbId();
3209 pdbs.add(new PDBEntry(filePath, pdbId));
3210 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3211 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3215 boolean colourByChimera = data.isColourByViewer();
3216 boolean colourBySequence = data.isColourWithAlignPanel();
3218 // TODO can/should this be done via StructureViewer (like Jmol)?
3219 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3220 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3222 new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray,
3223 seqsArray, colourByChimera, colourBySequence);
3227 Cache.log.error("Chimera session file " + chimeraSession
3233 * Create a new Jmol window. First parse the Jmol state to translate filenames
3234 * loaded into the view, and record the order in which files are shown in the
3235 * Jmol view, so we can add the sequence mappings in same order.
3240 protected void createJmolViewer(
3241 final Entry<String, StructureViewerModel> viewerData,
3244 final StructureViewerModel svattrib = viewerData.getValue();
3245 String state = svattrib.getStateData();
3246 List<String> pdbfilenames = new ArrayList<String>();
3247 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3248 List<String> pdbids = new ArrayList<String>();
3249 StringBuilder newFileLoc = new StringBuilder(64);
3250 int cp = 0, ncp, ecp;
3251 Map<File, StructureData> oldFiles = svattrib.getFileData();
3252 while ((ncp = state.indexOf("load ", cp)) > -1)
3256 // look for next filename in load statement
3257 newFileLoc.append(state.substring(cp,
3258 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3259 String oldfilenam = state.substring(ncp,
3260 ecp = state.indexOf("\"", ncp));
3261 // recover the new mapping data for this old filename
3262 // have to normalize filename - since Jmol and jalview do
3264 // translation differently.
3265 StructureData filedat = oldFiles.get(new File(oldfilenam));
3266 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3267 pdbfilenames.add(filedat.getFilePath());
3268 pdbids.add(filedat.getPdbId());
3269 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3270 newFileLoc.append("\"");
3271 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3272 // look for next file statement.
3273 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3277 // just append rest of state
3278 newFileLoc.append(state.substring(cp));
3282 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3283 newFileLoc = new StringBuilder(state);
3284 newFileLoc.append("; load append ");
3285 for (File id : oldFiles.keySet())
3287 // add this and any other pdb files that should be present in
3289 StructureData filedat = oldFiles.get(id);
3290 newFileLoc.append(filedat.getFilePath());
3291 pdbfilenames.add(filedat.getFilePath());
3292 pdbids.add(filedat.getPdbId());
3293 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3294 newFileLoc.append(" \"");
3295 newFileLoc.append(filedat.getFilePath());
3296 newFileLoc.append("\"");
3299 newFileLoc.append(";");
3302 if (newFileLoc.length() > 0)
3304 int histbug = newFileLoc.indexOf("history = ");
3306 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3307 String val = (diff == -1) ? null : newFileLoc
3308 .substring(histbug, diff);
3309 if (val != null && val.length() >= 4)
3311 if (val.contains("e"))
3313 if (val.trim().equals("true"))
3321 newFileLoc.replace(histbug, diff, val);
3325 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3327 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3328 final SequenceI[][] sq = seqmaps
3329 .toArray(new SequenceI[seqmaps.size()][]);
3330 final String fileloc = newFileLoc.toString();
3331 final String sviewid = viewerData.getKey();
3332 final AlignFrame alf = af;
3333 final Rectangle rect = new Rectangle(svattrib.getX(),
3334 svattrib.getY(), svattrib.getWidth(), svattrib.getHeight());
3337 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3342 JalviewStructureDisplayI sview = null;
3345 // JAL-1333 note - we probably can't migrate Jmol views to UCSF
3347 sview = new StructureViewer(alf.alignPanel
3348 .getStructureSelectionManager()).createView(
3349 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3350 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3351 addNewStructureViewer(sview);
3352 } catch (OutOfMemoryError ex)
3354 new OOMWarning("restoring structure view for PDB id " + id,
3355 (OutOfMemoryError) ex.getCause());
3356 if (sview != null && sview.isVisible())
3358 sview.closeViewer();
3359 sview.setVisible(false);
3365 } catch (InvocationTargetException ex)
3367 warn("Unexpected error when opening Jmol view.", ex);
3369 } catch (InterruptedException e)
3371 // e.printStackTrace();
3377 * Returns any open frame that matches given structure viewer data. The match
3378 * is based on the unique viewId, or (for older project versions) the frame's
3384 protected StructureViewerBase findMatchingViewer(
3385 Entry<String, StructureViewerModel> viewerData)
3387 final String sviewid = viewerData.getKey();
3388 final StructureViewerModel svattrib = viewerData.getValue();
3389 StructureViewerBase comp = null;
3390 JInternalFrame[] frames = getAllFrames();
3391 for (JInternalFrame frame : frames)
3393 if (frame instanceof StructureViewerBase)
3396 * Post jalview 2.4 schema includes structure view id
3399 && ((StructureViewerBase) frame).getViewId()
3402 comp = (AppJmol) frame;
3406 * Otherwise test for matching position and size of viewer frame
3408 else if (frame.getX() == svattrib.getX()
3409 && frame.getY() == svattrib.getY()
3410 && frame.getHeight() == svattrib.getHeight()
3411 && frame.getWidth() == svattrib.getWidth())
3413 comp = (AppJmol) frame;
3422 * Link an AlignmentPanel to an existing structure viewer.
3427 * @param useinViewerSuperpos
3428 * @param usetoColourbyseq
3429 * @param viewerColouring
3431 protected void linkStructureViewer(AlignmentPanel ap,
3432 StructureViewerBase viewer, StructureViewerModel svattrib)
3434 // NOTE: if the jalview project is part of a shared session then
3435 // view synchronization should/could be done here.
3437 final boolean useinViewerSuperpos = svattrib.isAlignWithPanel();
3438 final boolean usetoColourbyseq = svattrib.isColourWithAlignPanel();
3439 final boolean viewerColouring = svattrib.isColourByViewer();
3440 Map<File, StructureData> oldFiles = svattrib.getFileData();
3443 * Add mapping for sequences in this view to an already open viewer
3445 final AAStructureBindingModel binding = viewer.getBinding();
3446 for (File id : oldFiles.keySet())
3448 // add this and any other pdb files that should be present in the
3450 StructureData filedat = oldFiles.get(id);
3451 String pdbFile = filedat.getFilePath();
3452 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3453 binding.getSsm().setMapping(seq, null, pdbFile,
3454 jalview.io.AppletFormatAdapter.FILE);
3455 binding.addSequenceForStructFile(pdbFile, seq);
3457 // and add the AlignmentPanel's reference to the view panel
3458 viewer.addAlignmentPanel(ap);
3459 if (useinViewerSuperpos)
3461 viewer.useAlignmentPanelForSuperposition(ap);
3465 viewer.excludeAlignmentPanelForSuperposition(ap);
3467 if (usetoColourbyseq)
3469 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3473 viewer.excludeAlignmentPanelForColourbyseq(ap);
3478 * Get all frames within the Desktop.
3482 protected JInternalFrame[] getAllFrames()
3484 JInternalFrame[] frames = null;
3485 // TODO is this necessary - is it safe - risk of hanging?
3490 frames = Desktop.desktop.getAllFrames();
3491 } catch (ArrayIndexOutOfBoundsException e)
3493 // occasional No such child exceptions are thrown here...
3497 } catch (InterruptedException f)
3501 } while (frames == null);
3508 * - minimum version we are comparing against
3510 * - version of data being processsed.
3511 * @return true if version is development/null or evaluates to the same or
3512 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3514 private boolean isVersionStringLaterThan(String supported, String version)
3516 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3517 || version.equalsIgnoreCase("Test")
3518 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3520 System.err.println("Assuming project file with "
3521 + (version == null ? "null" : version)
3522 + " is compatible with Jalview version " + supported);
3527 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3529 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3531 // convert b to decimal to catch bugfix releases within a series
3532 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3533 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3536 if (Float.valueOf(curT) > Float.valueOf(fileT))
3538 // current version is newer than the version that wrote the file
3541 } catch (NumberFormatException nfe)
3544 .println("** WARNING: Version comparison failed for tokens ("
3548 + ")\n** Current: '"
3549 + supported + "' and Version: '" + version + "'");
3552 if (currentV.hasMoreElements())
3554 // fileV has no minor version but identical series to current
3561 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3563 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3565 if (newStructureViewers != null)
3567 sview.getBinding().setFinishedLoadingFromArchive(false);
3568 newStructureViewers.add(sview);
3572 protected void setLoadingFinishedForNewStructureViewers()
3574 if (newStructureViewers != null)
3576 for (JalviewStructureDisplayI sview : newStructureViewers)
3578 sview.getBinding().setFinishedLoadingFromArchive(true);
3580 newStructureViewers.clear();
3581 newStructureViewers = null;
3585 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3586 Alignment al, JalviewModelSequence jms, Viewport view,
3587 String uniqueSeqSetId, String viewId,
3588 ArrayList<JvAnnotRow> autoAlan)
3590 AlignFrame af = null;
3591 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3592 uniqueSeqSetId, viewId);
3594 af.setFileName(file, "Jalview");
3596 for (int i = 0; i < JSEQ.length; i++)
3598 af.viewport.setSequenceColour(af.viewport.getAlignment()
3599 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3602 af.viewport.gatherViewsHere = view.getGatheredViews();
3604 if (view.getSequenceSetId() != null)
3606 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3607 .get(uniqueSeqSetId);
3609 af.viewport.setSequenceSetId(uniqueSeqSetId);
3612 // propagate shared settings to this new view
3613 af.viewport.setHistoryList(av.getHistoryList());
3614 af.viewport.setRedoList(av.getRedoList());
3618 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3620 // TODO: check if this method can be called repeatedly without
3621 // side-effects if alignpanel already registered.
3622 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3624 // apply Hidden regions to view.
3625 if (hiddenSeqs != null)
3627 for (int s = 0; s < JSEQ.length; s++)
3629 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3631 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3634 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3636 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3639 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3642 for (int s = 0; s < hiddenSeqs.size(); s++)
3644 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3647 af.viewport.hideSequence(hseqs);
3650 // recover view properties and display parameters
3651 if (view.getViewName() != null)
3653 af.viewport.viewName = view.getViewName();
3654 af.setInitialTabVisible();
3656 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3659 af.viewport.setShowAnnotation(view.getShowAnnotation());
3660 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3662 af.viewport.setColourText(view.getShowColourText());
3664 af.viewport.setConservationSelected(view.getConservationSelected());
3665 af.viewport.setShowJVSuffix(view.getShowFullId());
3666 af.viewport.setRightAlignIds(view.getRightAlignIds());
3667 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3668 .getFontStyle(), view.getFontSize()));
3669 af.alignPanel.fontChanged();
3670 af.viewport.setRenderGaps(view.getRenderGaps());
3671 af.viewport.setWrapAlignment(view.getWrapAlignment());
3672 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3673 af.viewport.setShowAnnotation(view.getShowAnnotation());
3674 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3676 af.viewport.setShowBoxes(view.getShowBoxes());
3678 af.viewport.setShowText(view.getShowText());
3680 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3681 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3682 af.viewport.thresholdTextColour = view.getTextColThreshold();
3683 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3684 .isShowUnconserved() : false);
3685 af.viewport.setStartRes(view.getStartRes());
3686 af.viewport.setStartSeq(view.getStartSeq());
3688 ColourSchemeI cs = null;
3689 // apply colourschemes
3690 if (view.getBgColour() != null)
3692 if (view.getBgColour().startsWith("ucs"))
3694 cs = getUserColourScheme(jms, view.getBgColour());
3696 else if (view.getBgColour().startsWith("Annotation"))
3698 AnnotationColours viewAnnColour = view.getAnnotationColours();
3699 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3706 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3711 cs.setThreshold(view.getPidThreshold(), true);
3712 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3716 af.viewport.setGlobalColourScheme(cs);
3717 af.viewport.setColourAppliesToAllGroups(false);
3719 if (view.getConservationSelected() && cs != null)
3721 cs.setConservationInc(view.getConsThreshold());
3724 af.changeColour(cs);
3726 af.viewport.setColourAppliesToAllGroups(true);
3728 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
3730 if (view.hasCentreColumnLabels())
3732 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3734 if (view.hasIgnoreGapsinConsensus())
3736 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3739 if (view.hasFollowHighlight())
3741 af.viewport.followHighlight = view.getFollowHighlight();
3743 if (view.hasFollowSelection())
3745 af.viewport.followSelection = view.getFollowSelection();
3747 if (view.hasShowConsensusHistogram())
3749 af.viewport.setShowConsensusHistogram(view
3750 .getShowConsensusHistogram());
3754 af.viewport.setShowConsensusHistogram(true);
3756 if (view.hasShowSequenceLogo())
3758 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3762 af.viewport.setShowSequenceLogo(false);
3764 if (view.hasNormaliseSequenceLogo())
3766 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3768 if (view.hasShowDbRefTooltip())
3770 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3772 if (view.hasShowNPfeatureTooltip())
3774 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3776 if (view.hasShowGroupConsensus())
3778 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3782 af.viewport.setShowGroupConsensus(false);
3784 if (view.hasShowGroupConservation())
3786 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3790 af.viewport.setShowGroupConservation(false);
3793 // recover featre settings
3794 if (jms.getFeatureSettings() != null)
3796 FeaturesDisplayed fdi;
3797 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
3798 String[] renderOrder = new String[jms.getFeatureSettings()
3799 .getSettingCount()];
3800 Hashtable featureGroups = new Hashtable();
3801 Hashtable featureColours = new Hashtable();
3802 Hashtable featureOrder = new Hashtable();
3804 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3806 Setting setting = jms.getFeatureSettings().getSetting(fs);
3807 if (setting.hasMincolour())
3809 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3810 new java.awt.Color(setting.getMincolour()),
3811 new java.awt.Color(setting.getColour()),
3812 setting.getMin(), setting.getMax()) : new GraduatedColor(
3813 new java.awt.Color(setting.getMincolour()),
3814 new java.awt.Color(setting.getColour()), 0, 1);
3815 if (setting.hasThreshold())
3817 gc.setThresh(setting.getThreshold());
3818 gc.setThreshType(setting.getThreshstate());
3820 gc.setAutoScaled(true); // default
3821 if (setting.hasAutoScale())
3823 gc.setAutoScaled(setting.getAutoScale());
3825 if (setting.hasColourByLabel())
3827 gc.setColourByLabel(setting.getColourByLabel());
3829 // and put in the feature colour table.
3830 featureColours.put(setting.getType(), gc);
3834 featureColours.put(setting.getType(),
3835 new java.awt.Color(setting.getColour()));
3837 renderOrder[fs] = setting.getType();
3838 if (setting.hasOrder())
3840 featureOrder.put(setting.getType(), setting.getOrder());
3844 featureOrder.put(setting.getType(), new Float(fs
3845 / jms.getFeatureSettings().getSettingCount()));
3847 if (setting.getDisplay())
3849 fdi.setVisible(setting.getType());
3852 Hashtable fgtable = new Hashtable();
3853 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3855 Group grp = jms.getFeatureSettings().getGroup(gs);
3856 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3858 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
3859 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
3860 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
3861 FeatureRendererSettings frs = new FeatureRendererSettings(
3862 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
3863 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
3864 .transferSettings(frs);
3868 if (view.getHiddenColumnsCount() > 0)
3870 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3872 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3873 .getHiddenColumns(c).getEnd() // +1
3877 if (view.getCalcIdParam() != null)
3879 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3881 if (calcIdParam != null)
3883 if (recoverCalcIdParam(calcIdParam, af.viewport))
3888 warn("Couldn't recover parameters for "
3889 + calcIdParam.getCalcId());
3894 af.setMenusFromViewport(af.viewport);
3895 // TODO: we don't need to do this if the viewport is aready visible.
3896 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3898 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3899 reorderAutoannotation(af, al, autoAlan);
3900 af.alignPanel.alignmentChanged();
3904 private ColourSchemeI constructAnnotationColour(
3905 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3906 JalviewModelSequence jms, boolean checkGroupAnnColour)
3908 boolean propagateAnnColour = false;
3909 ColourSchemeI cs = null;
3910 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3911 if (checkGroupAnnColour && al.getGroups() != null
3912 && al.getGroups().size() > 0)
3914 // pre 2.8.1 behaviour
3915 // check to see if we should transfer annotation colours
3916 propagateAnnColour = true;
3917 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3919 if (sg.cs instanceof AnnotationColourGradient)
3921 propagateAnnColour = false;
3925 // int find annotation
3926 if (annAlignment.getAlignmentAnnotation() != null)
3928 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3930 if (annAlignment.getAlignmentAnnotation()[i].label
3931 .equals(viewAnnColour.getAnnotation()))
3933 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3935 annAlignment.getAlignmentAnnotation()[i]
3936 .setThreshold(new jalview.datamodel.GraphLine(
3937 viewAnnColour.getThreshold(), "Threshold",
3938 java.awt.Color.black)
3943 if (viewAnnColour.getColourScheme().equals("None"))
3945 cs = new AnnotationColourGradient(
3946 annAlignment.getAlignmentAnnotation()[i],
3947 new java.awt.Color(viewAnnColour.getMinColour()),
3948 new java.awt.Color(viewAnnColour.getMaxColour()),
3949 viewAnnColour.getAboveThreshold());
3951 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3953 cs = new AnnotationColourGradient(
3954 annAlignment.getAlignmentAnnotation()[i],
3955 getUserColourScheme(jms,
3956 viewAnnColour.getColourScheme()),
3957 viewAnnColour.getAboveThreshold());
3961 cs = new AnnotationColourGradient(
3962 annAlignment.getAlignmentAnnotation()[i],
3963 ColourSchemeProperty.getColour(al,
3964 viewAnnColour.getColourScheme()),
3965 viewAnnColour.getAboveThreshold());
3967 if (viewAnnColour.hasPerSequence())
3969 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3972 if (viewAnnColour.hasPredefinedColours())
3974 ((AnnotationColourGradient) cs)
3975 .setPredefinedColours(viewAnnColour
3976 .isPredefinedColours());
3978 if (propagateAnnColour && al.getGroups() != null)
3980 // Also use these settings for all the groups
3981 for (int g = 0; g < al.getGroups().size(); g++)
3983 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3991 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3992 * new AnnotationColourGradient(
3993 * annAlignment.getAlignmentAnnotation()[i], new
3994 * java.awt.Color(viewAnnColour. getMinColour()), new
3995 * java.awt.Color(viewAnnColour. getMaxColour()),
3996 * viewAnnColour.getAboveThreshold()); } else
3999 sg.cs = new AnnotationColourGradient(
4000 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4001 viewAnnColour.getAboveThreshold());
4002 if (cs instanceof AnnotationColourGradient)
4004 if (viewAnnColour.hasPerSequence())
4006 ((AnnotationColourGradient) cs)
4007 .setSeqAssociated(viewAnnColour.isPerSequence());
4009 if (viewAnnColour.hasPredefinedColours())
4011 ((AnnotationColourGradient) cs)
4012 .setPredefinedColours(viewAnnColour
4013 .isPredefinedColours());
4029 private void reorderAutoannotation(AlignFrame af, Alignment al,
4030 ArrayList<JvAnnotRow> autoAlan)
4032 // copy over visualization settings for autocalculated annotation in the
4034 if (al.getAlignmentAnnotation() != null)
4037 * Kludge for magic autoannotation names (see JAL-811)
4039 String[] magicNames = new String[]
4040 { "Consensus", "Quality", "Conservation" };
4041 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4042 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4043 for (String nm : magicNames)
4045 visan.put(nm, nullAnnot);
4047 for (JvAnnotRow auan : autoAlan)
4049 visan.put(auan.template.label
4050 + (auan.template.getCalcId() == null ? "" : "\t"
4051 + auan.template.getCalcId()), auan);
4053 int hSize = al.getAlignmentAnnotation().length;
4054 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4055 // work through any autoCalculated annotation already on the view
4056 // removing it if it should be placed in a different location on the
4057 // annotation panel.
4058 List<String> remains = new ArrayList(visan.keySet());
4059 for (int h = 0; h < hSize; h++)
4061 jalview.datamodel.AlignmentAnnotation jalan = al
4062 .getAlignmentAnnotation()[h];
4063 if (jalan.autoCalculated)
4066 JvAnnotRow valan = visan.get(k = jalan.label);
4067 if (jalan.getCalcId() != null)
4069 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4074 // delete the auto calculated row from the alignment
4075 al.deleteAnnotation(jalan, false);
4079 if (valan != nullAnnot)
4081 if (jalan != valan.template)
4083 // newly created autoannotation row instance
4084 // so keep a reference to the visible annotation row
4085 // and copy over all relevant attributes
4086 if (valan.template.graphHeight >= 0)
4089 jalan.graphHeight = valan.template.graphHeight;
4091 jalan.visible = valan.template.visible;
4093 reorder.add(new JvAnnotRow(valan.order, jalan));
4098 // Add any (possibly stale) autocalculated rows that were not appended to
4099 // the view during construction
4100 for (String other : remains)
4102 JvAnnotRow othera = visan.get(other);
4103 if (othera != nullAnnot && othera.template.getCalcId() != null
4104 && othera.template.getCalcId().length() > 0)
4106 reorder.add(othera);
4109 // now put the automatic annotation in its correct place
4110 int s = 0, srt[] = new int[reorder.size()];
4111 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4112 for (JvAnnotRow jvar : reorder)
4115 srt[s++] = jvar.order;
4118 jalview.util.QuickSort.sort(srt, rws);
4119 // and re-insert the annotation at its correct position
4120 for (JvAnnotRow jvar : rws)
4122 al.addAnnotation(jvar.template, jvar.order);
4124 af.alignPanel.adjustAnnotationHeight();
4128 Hashtable skipList = null;
4131 * TODO remove this method
4134 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4135 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4136 * throw new Error("Implementation Error. No skipList defined for this
4137 * Jalview2XML instance."); } return (AlignFrame)
4138 * skipList.get(view.getSequenceSetId()); }
4142 * Check if the Jalview view contained in object should be skipped or not.
4145 * @return true if view's sequenceSetId is a key in skipList
4147 private boolean skipViewport(JalviewModel object)
4149 if (skipList == null)
4154 if (skipList.containsKey(id = object.getJalviewModelSequence()
4155 .getViewport()[0].getSequenceSetId()))
4157 if (Cache.log != null && Cache.log.isDebugEnabled())
4159 Cache.log.debug("Skipping seuqence set id " + id);
4166 public void addToSkipList(AlignFrame af)
4168 if (skipList == null)
4170 skipList = new Hashtable();
4172 skipList.put(af.getViewport().getSequenceSetId(), af);
4175 public void clearSkipList()
4177 if (skipList != null)
4184 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4185 boolean ignoreUnrefed)
4187 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4188 Vector dseqs = null;
4191 // create a list of new dataset sequences
4192 dseqs = new Vector();
4194 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4196 Sequence vamsasSeq = vamsasSet.getSequence(i);
4197 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4199 // create a new dataset
4202 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4203 dseqs.copyInto(dsseqs);
4204 ds = new jalview.datamodel.Alignment(dsseqs);
4205 debug("Created new dataset " + vamsasSet.getDatasetId()
4206 + " for alignment " + System.identityHashCode(al));
4207 addDatasetRef(vamsasSet.getDatasetId(), ds);
4209 // set the dataset for the newly imported alignment.
4210 if (al.getDataset() == null && !ignoreUnrefed)
4219 * sequence definition to create/merge dataset sequence for
4223 * vector to add new dataset sequence to
4225 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4226 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4228 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4230 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4231 SequenceI dsq = null;
4232 if (sq != null && sq.getDatasetSequence() != null)
4234 dsq = sq.getDatasetSequence();
4236 if (sq == null && ignoreUnrefed)
4240 String sqid = vamsasSeq.getDsseqid();
4243 // need to create or add a new dataset sequence reference to this sequence
4246 dsq = seqRefIds.get(sqid);
4251 // make a new dataset sequence
4252 dsq = sq.createDatasetSequence();
4255 // make up a new dataset reference for this sequence
4256 sqid = seqHash(dsq);
4258 dsq.setVamsasId(uniqueSetSuffix + sqid);
4259 seqRefIds.put(sqid, dsq);
4264 dseqs.addElement(dsq);
4269 ds.addSequence(dsq);
4275 { // make this dataset sequence sq's dataset sequence
4276 sq.setDatasetSequence(dsq);
4277 // and update the current dataset alignment
4282 if (!dseqs.contains(dsq))
4289 if (ds.findIndex(dsq) < 0)
4291 ds.addSequence(dsq);
4298 // TODO: refactor this as a merge dataset sequence function
4299 // now check that sq (the dataset sequence) sequence really is the union of
4300 // all references to it
4301 // boolean pre = sq.getStart() < dsq.getStart();
4302 // boolean post = sq.getEnd() > dsq.getEnd();
4306 StringBuffer sb = new StringBuffer();
4307 String newres = jalview.analysis.AlignSeq.extractGaps(
4308 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4309 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4310 && newres.length() > dsq.getLength())
4312 // Update with the longer sequence.
4316 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4317 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4318 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4319 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4321 dsq.setSequence(newres);
4323 // TODO: merges will never happen if we 'know' we have the real dataset
4324 // sequence - this should be detected when id==dssid
4326 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4327 // + (pre ? "prepended" : "") + " "
4328 // + (post ? "appended" : ""));
4333 java.util.Hashtable datasetIds = null;
4335 java.util.IdentityHashMap dataset2Ids = null;
4337 private Alignment getDatasetFor(String datasetId)
4339 if (datasetIds == null)
4341 datasetIds = new Hashtable();
4344 if (datasetIds.containsKey(datasetId))
4346 return (Alignment) datasetIds.get(datasetId);
4351 private void addDatasetRef(String datasetId, Alignment dataset)
4353 if (datasetIds == null)
4355 datasetIds = new Hashtable();
4357 datasetIds.put(datasetId, dataset);
4361 * make a new dataset ID for this jalview dataset alignment
4366 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4368 if (dataset.getDataset() != null)
4370 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4372 String datasetId = makeHashCode(dataset, null);
4373 if (datasetId == null)
4375 // make a new datasetId and record it
4376 if (dataset2Ids == null)
4378 dataset2Ids = new IdentityHashMap();
4382 datasetId = (String) dataset2Ids.get(dataset);
4384 if (datasetId == null)
4386 datasetId = "ds" + dataset2Ids.size() + 1;
4387 dataset2Ids.put(dataset, datasetId);
4393 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4395 for (int d = 0; d < sequence.getDBRefCount(); d++)
4397 DBRef dr = sequence.getDBRef(d);
4398 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4399 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4400 .getVersion(), sequence.getDBRef(d).getAccessionId());
4401 if (dr.getMapping() != null)
4403 entry.setMap(addMapping(dr.getMapping()));
4405 datasetSequence.addDBRef(entry);
4409 private jalview.datamodel.Mapping addMapping(Mapping m)
4411 SequenceI dsto = null;
4412 // Mapping m = dr.getMapping();
4413 int fr[] = new int[m.getMapListFromCount() * 2];
4414 Enumeration f = m.enumerateMapListFrom();
4415 for (int _i = 0; f.hasMoreElements(); _i += 2)
4417 MapListFrom mf = (MapListFrom) f.nextElement();
4418 fr[_i] = mf.getStart();
4419 fr[_i + 1] = mf.getEnd();
4421 int fto[] = new int[m.getMapListToCount() * 2];
4422 f = m.enumerateMapListTo();
4423 for (int _i = 0; f.hasMoreElements(); _i += 2)
4425 MapListTo mf = (MapListTo) f.nextElement();
4426 fto[_i] = mf.getStart();
4427 fto[_i + 1] = mf.getEnd();
4429 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4430 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4431 if (m.getMappingChoice() != null)
4433 MappingChoice mc = m.getMappingChoice();
4434 if (mc.getDseqFor() != null)
4436 String dsfor = "" + mc.getDseqFor();
4437 if (seqRefIds.containsKey(dsfor))
4442 jmap.setTo(seqRefIds.get(dsfor));
4446 frefedSequence.add(new Object[]
4453 * local sequence definition
4455 Sequence ms = mc.getSequence();
4456 SequenceI djs = null;
4457 String sqid = ms.getDsseqid();
4458 if (sqid != null && sqid.length() > 0)
4461 * recover dataset sequence
4463 djs = seqRefIds.get(sqid);
4468 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4469 sqid = ((Object) ms).toString(); // make up a new hascode for
4470 // undefined dataset sequence hash
4471 // (unlikely to happen)
4477 * make a new dataset sequence and add it to refIds hash
4479 djs = new jalview.datamodel.Sequence(ms.getName(),
4481 djs.setStart(jmap.getMap().getToLowest());
4482 djs.setEnd(jmap.getMap().getToHighest());
4483 djs.setVamsasId(uniqueSetSuffix + sqid);
4485 seqRefIds.put(sqid, djs);
4488 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4497 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4498 boolean keepSeqRefs)
4501 jalview.schemabinding.version2.JalviewModel jm = saveState(ap, null,
4507 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4511 uniqueSetSuffix = "";
4512 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4517 if (this.frefedSequence == null)
4519 frefedSequence = new Vector();
4522 viewportsAdded = new Hashtable();
4524 AlignFrame af = loadFromObject(jm, null, false, null);
4525 af.alignPanels.clear();
4526 af.closeMenuItem_actionPerformed(true);
4529 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4530 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4531 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4532 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4533 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4536 return af.alignPanel;
4540 * flag indicating if hashtables should be cleared on finalization TODO this
4541 * flag may not be necessary
4543 private final boolean _cleartables = true;
4545 private Hashtable jvids2vobj;
4550 * @see java.lang.Object#finalize()
4553 protected void finalize() throws Throwable
4555 // really make sure we have no buried refs left.
4560 this.seqRefIds = null;
4561 this.seqsToIds = null;
4565 private void warn(String msg)
4570 private void warn(String msg, Exception e)
4572 if (Cache.log != null)
4576 Cache.log.warn(msg, e);
4580 Cache.log.warn(msg);
4585 System.err.println("Warning: " + msg);
4588 e.printStackTrace();
4593 private void debug(String string)
4595 debug(string, null);
4598 private void debug(String msg, Exception e)
4600 if (Cache.log != null)
4604 Cache.log.debug(msg, e);
4608 Cache.log.debug(msg);
4613 System.err.println("Warning: " + msg);
4616 e.printStackTrace();
4622 * set the object to ID mapping tables used to write/recover objects and XML
4623 * ID strings for the jalview project. If external tables are provided then
4624 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4625 * object goes out of scope. - also populates the datasetIds hashtable with
4626 * alignment objects containing dataset sequences
4629 * Map from ID strings to jalview datamodel
4631 * Map from jalview datamodel to ID strings
4635 public void setObjectMappingTables(Hashtable vobj2jv,
4636 IdentityHashMap jv2vobj)
4638 this.jv2vobj = jv2vobj;
4639 this.vobj2jv = vobj2jv;
4640 Iterator ds = jv2vobj.keySet().iterator();
4642 while (ds.hasNext())
4644 Object jvobj = ds.next();
4645 id = jv2vobj.get(jvobj).toString();
4646 if (jvobj instanceof jalview.datamodel.Alignment)
4648 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4650 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4653 else if (jvobj instanceof jalview.datamodel.Sequence)
4655 // register sequence object so the XML parser can recover it.
4656 if (seqRefIds == null)
4658 seqRefIds = new HashMap<String, SequenceI>();
4660 if (seqsToIds == null)
4662 seqsToIds = new IdentityHashMap<SequenceI, String>();
4664 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4665 seqsToIds.put((SequenceI) jvobj, id);
4667 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4669 if (annotationIds == null)
4671 annotationIds = new Hashtable();
4674 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4675 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4676 if (jvann.annotationId == null)
4678 jvann.annotationId = anid;
4680 if (!jvann.annotationId.equals(anid))
4682 // TODO verify that this is the correct behaviour
4683 this.warn("Overriding Annotation ID for " + anid
4684 + " from different id : " + jvann.annotationId);
4685 jvann.annotationId = anid;
4688 else if (jvobj instanceof String)
4690 if (jvids2vobj == null)
4692 jvids2vobj = new Hashtable();
4693 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4698 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4704 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4705 * objects created from the project archive. If string is null (default for
4706 * construction) then suffix will be set automatically.
4710 public void setUniqueSetSuffix(String string)
4712 uniqueSetSuffix = string;
4717 * uses skipList2 as the skipList for skipping views on sequence sets
4718 * associated with keys in the skipList
4722 public void setSkipList(Hashtable skipList2)
4724 skipList = skipList2;