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.isGatherViewsHere());
1048 Rectangle position = ap.av.getExplodedGeometry();
1049 if (position != null)
1051 view.setXpos(position.x);
1052 view.setYpos(position.y);
1053 view.setWidth(position.width);
1054 view.setHeight(position.height);
1058 view.setXpos(ap.alignFrame.getBounds().x);
1059 view.setYpos(ap.alignFrame.getBounds().y);
1060 view.setWidth(ap.alignFrame.getBounds().width);
1061 view.setHeight(ap.alignFrame.getBounds().height);
1064 view.setStartRes(av.startRes);
1065 view.setStartSeq(av.startSeq);
1067 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1069 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1072 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1074 AnnotationColours ac = constructAnnotationColours(
1075 (jalview.schemes.AnnotationColourGradient) av
1076 .getGlobalColourScheme(),
1079 view.setAnnotationColours(ac);
1080 view.setBgColour("AnnotationColourGradient");
1084 view.setBgColour(ColourSchemeProperty.getColourName(av
1085 .getGlobalColourScheme()));
1088 ColourSchemeI cs = av.getGlobalColourScheme();
1092 if (cs.conservationApplied())
1094 view.setConsThreshold(cs.getConservationInc());
1095 if (cs instanceof jalview.schemes.UserColourScheme)
1097 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1101 if (cs instanceof ResidueColourScheme)
1103 view.setPidThreshold(cs.getThreshold());
1107 view.setConservationSelected(av.getConservationSelected());
1108 view.setPidSelected(av.getAbovePIDThreshold());
1109 view.setFontName(av.font.getName());
1110 view.setFontSize(av.font.getSize());
1111 view.setFontStyle(av.font.getStyle());
1112 view.setRenderGaps(av.isRenderGaps());
1113 view.setShowAnnotation(av.isShowAnnotation());
1114 view.setShowBoxes(av.getShowBoxes());
1115 view.setShowColourText(av.getColourText());
1116 view.setShowFullId(av.getShowJVSuffix());
1117 view.setRightAlignIds(av.isRightAlignIds());
1118 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1119 view.setShowText(av.getShowText());
1120 view.setShowUnconserved(av.getShowUnconserved());
1121 view.setWrapAlignment(av.getWrapAlignment());
1122 view.setTextCol1(av.getTextColour().getRGB());
1123 view.setTextCol2(av.getTextColour2().getRGB());
1124 view.setTextColThreshold(av.getThresholdTextColour());
1125 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1126 view.setShowSequenceLogo(av.isShowSequenceLogo());
1127 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1128 view.setShowGroupConsensus(av.isShowGroupConsensus());
1129 view.setShowGroupConservation(av.isShowGroupConservation());
1130 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1131 view.setShowDbRefTooltip(av.isShowDBRefs());
1132 view.setFollowHighlight(av.followHighlight);
1133 view.setFollowSelection(av.followSelection);
1134 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1135 if (av.getFeaturesDisplayed() != null)
1137 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1139 String[] renderOrder = ap.getSeqPanel().seqCanvas
1140 .getFeatureRenderer().getRenderOrder()
1141 .toArray(new String[0]);
1143 Vector settingsAdded = new Vector();
1144 Object gstyle = null;
1145 GraduatedColor gcol = null;
1146 if (renderOrder != null)
1148 for (int ro = 0; ro < renderOrder.length; ro++)
1150 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1151 .getFeatureStyle(renderOrder[ro]);
1152 Setting setting = new Setting();
1153 setting.setType(renderOrder[ro]);
1154 if (gstyle instanceof GraduatedColor)
1156 gcol = (GraduatedColor) gstyle;
1157 setting.setColour(gcol.getMaxColor().getRGB());
1158 setting.setMincolour(gcol.getMinColor().getRGB());
1159 setting.setMin(gcol.getMin());
1160 setting.setMax(gcol.getMax());
1161 setting.setColourByLabel(gcol.isColourByLabel());
1162 setting.setAutoScale(gcol.isAutoScale());
1163 setting.setThreshold(gcol.getThresh());
1164 setting.setThreshstate(gcol.getThreshType());
1168 setting.setColour(ap.getSeqPanel().seqCanvas
1169 .getFeatureRenderer()
1170 .getColour(renderOrder[ro]).getRGB());
1173 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1175 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1176 .getOrder(renderOrder[ro]);
1179 setting.setOrder(rorder);
1181 fs.addSetting(setting);
1182 settingsAdded.addElement(renderOrder[ro]);
1186 // Make sure we save none displayed feature settings
1187 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1188 .getFeatureColours().keySet().iterator();
1189 while (en.hasNext())
1191 String key = en.next().toString();
1192 if (settingsAdded.contains(key))
1197 Setting setting = new Setting();
1198 setting.setType(key);
1199 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1200 .getColour(key).getRGB());
1202 setting.setDisplay(false);
1203 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1207 setting.setOrder(rorder);
1209 fs.addSetting(setting);
1210 settingsAdded.addElement(key);
1212 // is groups actually supposed to be a map here ?
1213 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1214 .getFeatureGroups().iterator();
1215 Vector groupsAdded = new Vector();
1216 while (en.hasNext())
1218 String grp = en.next().toString();
1219 if (groupsAdded.contains(grp))
1223 Group g = new Group();
1225 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1226 .getFeatureRenderer().checkGroupVisibility(grp, false))
1229 groupsAdded.addElement(grp);
1231 jms.setFeatureSettings(fs);
1235 if (av.hasHiddenColumns())
1237 if (av.getColumnSelection() == null
1238 || av.getColumnSelection().getHiddenColumns() == null)
1240 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1244 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1247 int[] region = av.getColumnSelection().getHiddenColumns()
1249 HiddenColumns hc = new HiddenColumns();
1250 hc.setStart(region[0]);
1251 hc.setEnd(region[1]);
1252 view.addHiddenColumns(hc);
1256 if (calcIdSet.size() > 0)
1258 for (String calcId : calcIdSet)
1260 if (calcId.trim().length() > 0)
1262 CalcIdParam cidp = createCalcIdParam(calcId, av);
1263 // Some calcIds have no parameters.
1266 view.addCalcIdParam(cidp);
1272 jms.addViewport(view);
1274 object.setJalviewModelSequence(jms);
1275 object.getVamsasModel().addSequenceSet(vamsasSet);
1277 if (jout != null && fileName != null)
1279 // We may not want to write the object to disk,
1280 // eg we can copy the alignViewport to a new view object
1281 // using save and then load
1284 JarEntry entry = new JarEntry(fileName);
1285 jout.putNextEntry(entry);
1286 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1288 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1290 marshaller.marshal(object);
1293 } catch (Exception ex)
1295 // TODO: raise error in GUI if marshalling failed.
1296 ex.printStackTrace();
1303 * Save the state of a structure viewer
1308 * the archive XML element under which to save the state
1311 * @param matchedFile
1315 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1316 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1317 String matchedFile, StructureViewerBase viewFrame)
1319 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1320 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1322 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1323 final String pdbId = pdbentry.getId();
1324 if (!pdbId.equals(entry.getId())
1325 && !(entry.getId().length() > 4 && entry.getId()
1326 .toLowerCase().startsWith(pdbId.toLowerCase())))
1330 if (matchedFile == null)
1332 matchedFile = pdbentry.getFile();
1334 else if (!matchedFile.equals(pdbentry.getFile()))
1337 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1338 + pdbentry.getFile());
1342 // can get at it if the ID
1343 // match is ambiguous (e.g.
1345 String statestring = viewFrame.getStateInfo();
1347 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1349 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1350 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1352 StructureState state = new StructureState();
1353 state.setVisible(true);
1354 state.setXpos(viewFrame.getX());
1355 state.setYpos(viewFrame.getY());
1356 state.setWidth(viewFrame.getWidth());
1357 state.setHeight(viewFrame.getHeight());
1358 final String viewId = viewFrame.getViewId();
1359 state.setViewId(viewId);
1360 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1361 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1362 state.setColourByJmol(viewFrame.isColouredByViewer());
1364 * Only store each structure viewer's state once in each XML document.
1366 if (!viewIds.contains(viewId))
1368 viewIds.add(viewId);
1369 state.setContent(statestring.replaceAll("\n", ""));
1373 state.setContent("# duplicate state");
1375 pdb.addStructureState(state);
1382 private AnnotationColours constructAnnotationColours(
1383 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1384 JalviewModelSequence jms)
1386 AnnotationColours ac = new AnnotationColours();
1387 ac.setAboveThreshold(acg.getAboveThreshold());
1388 ac.setThreshold(acg.getAnnotationThreshold());
1389 ac.setAnnotation(acg.getAnnotation());
1390 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1392 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1397 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1401 ac.setMaxColour(acg.getMaxColour().getRGB());
1402 ac.setMinColour(acg.getMinColour().getRGB());
1403 ac.setPerSequence(acg.isSeqAssociated());
1404 ac.setPredefinedColours(acg.isPredefinedColours());
1408 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1409 IdentityHashMap groupRefs, AlignmentViewport av,
1410 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1413 for (int i = 0; i < aa.length; i++)
1415 Annotation an = new Annotation();
1417 if (aa[i].annotationId != null)
1419 annotationIds.put(aa[i].annotationId, aa[i]);
1422 an.setId(aa[i].annotationId);
1424 an.setVisible(aa[i].visible);
1426 an.setDescription(aa[i].description);
1428 if (aa[i].sequenceRef != null)
1430 // TODO later annotation sequenceRef should be the XML ID of the
1431 // sequence rather than its display name
1432 an.setSequenceRef(aa[i].sequenceRef.getName());
1434 if (aa[i].groupRef != null)
1436 Object groupIdr = groupRefs.get(aa[i].groupRef);
1437 if (groupIdr == null)
1439 // make a locally unique String
1440 groupRefs.put(aa[i].groupRef,
1441 groupIdr = ("" + System.currentTimeMillis()
1442 + aa[i].groupRef.getName() + groupRefs.size()));
1444 an.setGroupRef(groupIdr.toString());
1447 // store all visualization attributes for annotation
1448 an.setGraphHeight(aa[i].graphHeight);
1449 an.setCentreColLabels(aa[i].centreColLabels);
1450 an.setScaleColLabels(aa[i].scaleColLabel);
1451 an.setShowAllColLabels(aa[i].showAllColLabels);
1452 an.setBelowAlignment(aa[i].belowAlignment);
1454 if (aa[i].graph > 0)
1457 an.setGraphType(aa[i].graph);
1458 an.setGraphGroup(aa[i].graphGroup);
1459 if (aa[i].getThreshold() != null)
1461 ThresholdLine line = new ThresholdLine();
1462 line.setLabel(aa[i].getThreshold().label);
1463 line.setValue(aa[i].getThreshold().value);
1464 line.setColour(aa[i].getThreshold().colour.getRGB());
1465 an.setThresholdLine(line);
1473 an.setLabel(aa[i].label);
1475 if (aa[i] == av.getAlignmentQualityAnnot()
1476 || aa[i] == av.getAlignmentConservationAnnotation()
1477 || aa[i] == av.getAlignmentConsensusAnnotation()
1478 || aa[i].autoCalculated)
1480 // new way of indicating autocalculated annotation -
1481 an.setAutoCalculated(aa[i].autoCalculated);
1483 if (aa[i].hasScore())
1485 an.setScore(aa[i].getScore());
1488 if (aa[i].getCalcId() != null)
1490 calcIdSet.add(aa[i].getCalcId());
1491 an.setCalcId(aa[i].getCalcId());
1493 if (aa[i].hasProperties())
1495 for (String pr : aa[i].getProperties())
1497 Property prop = new Property();
1499 prop.setValue(aa[i].getProperty(pr));
1500 an.addProperty(prop);
1504 AnnotationElement ae;
1505 if (aa[i].annotations != null)
1507 an.setScoreOnly(false);
1508 for (int a = 0; a < aa[i].annotations.length; a++)
1510 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1515 ae = new AnnotationElement();
1516 if (aa[i].annotations[a].description != null)
1518 ae.setDescription(aa[i].annotations[a].description);
1520 if (aa[i].annotations[a].displayCharacter != null)
1522 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1525 if (!Float.isNaN(aa[i].annotations[a].value))
1527 ae.setValue(aa[i].annotations[a].value);
1531 if (aa[i].annotations[a].secondaryStructure > ' ')
1533 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1537 if (aa[i].annotations[a].colour != null
1538 && aa[i].annotations[a].colour != java.awt.Color.black)
1540 ae.setColour(aa[i].annotations[a].colour.getRGB());
1543 an.addAnnotationElement(ae);
1544 if (aa[i].autoCalculated)
1546 // only write one non-null entry into the annotation row -
1547 // sufficient to get the visualization attributes necessary to
1555 an.setScoreOnly(true);
1557 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1559 // skip autocalculated annotation - these are only provided for
1561 vamsasSet.addAnnotation(an);
1567 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1569 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1570 if (settings != null)
1572 CalcIdParam vCalcIdParam = new CalcIdParam();
1573 vCalcIdParam.setCalcId(calcId);
1574 vCalcIdParam.addServiceURL(settings.getServiceURI());
1575 // generic URI allowing a third party to resolve another instance of the
1576 // service used for this calculation
1577 for (String urls : settings.getServiceURLs())
1579 vCalcIdParam.addServiceURL(urls);
1581 vCalcIdParam.setVersion("1.0");
1582 if (settings.getPreset() != null)
1584 WsParamSetI setting = settings.getPreset();
1585 vCalcIdParam.setName(setting.getName());
1586 vCalcIdParam.setDescription(setting.getDescription());
1590 vCalcIdParam.setName("");
1591 vCalcIdParam.setDescription("Last used parameters");
1593 // need to be able to recover 1) settings 2) user-defined presets or
1594 // recreate settings from preset 3) predefined settings provided by
1595 // service - or settings that can be transferred (or discarded)
1596 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1598 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1599 // todo - decide if updateImmediately is needed for any projects.
1601 return vCalcIdParam;
1606 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1609 if (calcIdParam.getVersion().equals("1.0"))
1611 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1612 .getPreferredServiceFor(calcIdParam.getServiceURL());
1613 if (service != null)
1615 WsParamSetI parmSet = null;
1618 parmSet = service.getParamStore().parseServiceParameterFile(
1619 calcIdParam.getName(), calcIdParam.getDescription(),
1620 calcIdParam.getServiceURL(),
1621 calcIdParam.getParameters().replace("|\\n|", "\n"));
1622 } catch (IOException x)
1624 warn("Couldn't parse parameter data for "
1625 + calcIdParam.getCalcId(), x);
1628 List<ArgumentI> argList = null;
1629 if (calcIdParam.getName().length() > 0)
1631 parmSet = service.getParamStore()
1632 .getPreset(calcIdParam.getName());
1633 if (parmSet != null)
1635 // TODO : check we have a good match with settings in AACon -
1636 // otherwise we'll need to create a new preset
1641 argList = parmSet.getArguments();
1644 AAConSettings settings = new AAConSettings(
1645 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1646 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1647 calcIdParam.isNeedsUpdate());
1652 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1656 throw new Error(MessageManager.formatMessage(
1657 "error.unsupported_version_calcIdparam", new String[]
1658 { calcIdParam.toString() }));
1662 * External mapping between jalview objects and objects yielding a valid and
1663 * unique object ID string. This is null for normal Jalview project IO, but
1664 * non-null when a jalview project is being read or written as part of a
1667 IdentityHashMap jv2vobj = null;
1670 * Construct a unique ID for jvobj using either existing bindings or if none
1671 * exist, the result of the hashcode call for the object.
1674 * jalview data object
1675 * @return unique ID for referring to jvobj
1677 private String makeHashCode(Object jvobj, String altCode)
1679 if (jv2vobj != null)
1681 Object id = jv2vobj.get(jvobj);
1684 return id.toString();
1686 // check string ID mappings
1687 if (jvids2vobj != null && jvobj instanceof String)
1689 id = jvids2vobj.get(jvobj);
1693 return id.toString();
1695 // give up and warn that something has gone wrong
1696 warn("Cannot find ID for object in external mapping : " + jvobj);
1702 * return local jalview object mapped to ID, if it exists
1706 * @return null or object bound to idcode
1708 private Object retrieveExistingObj(String idcode)
1710 if (idcode != null && vobj2jv != null)
1712 return vobj2jv.get(idcode);
1718 * binding from ID strings from external mapping table to jalview data model
1721 private Hashtable vobj2jv;
1723 private Sequence createVamsasSequence(String id, SequenceI jds)
1725 return createVamsasSequence(true, id, jds, null);
1728 private Sequence createVamsasSequence(boolean recurse, String id,
1729 SequenceI jds, SequenceI parentseq)
1731 Sequence vamsasSeq = new Sequence();
1732 vamsasSeq.setId(id);
1733 vamsasSeq.setName(jds.getName());
1734 vamsasSeq.setSequence(jds.getSequenceAsString());
1735 vamsasSeq.setDescription(jds.getDescription());
1736 jalview.datamodel.DBRefEntry[] dbrefs = null;
1737 if (jds.getDatasetSequence() != null)
1739 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1740 if (jds.getDatasetSequence().getDBRef() != null)
1742 dbrefs = jds.getDatasetSequence().getDBRef();
1747 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1748 // dataset sequences only
1749 dbrefs = jds.getDBRef();
1753 for (int d = 0; d < dbrefs.length; d++)
1755 DBRef dbref = new DBRef();
1756 dbref.setSource(dbrefs[d].getSource());
1757 dbref.setVersion(dbrefs[d].getVersion());
1758 dbref.setAccessionId(dbrefs[d].getAccessionId());
1759 if (dbrefs[d].hasMap())
1761 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1763 dbref.setMapping(mp);
1765 vamsasSeq.addDBRef(dbref);
1771 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1772 SequenceI parentseq, SequenceI jds, boolean recurse)
1775 if (jmp.getMap() != null)
1779 jalview.util.MapList mlst = jmp.getMap();
1780 int r[] = mlst.getFromRanges();
1781 for (int s = 0; s < r.length; s += 2)
1783 MapListFrom mfrom = new MapListFrom();
1784 mfrom.setStart(r[s]);
1785 mfrom.setEnd(r[s + 1]);
1786 mp.addMapListFrom(mfrom);
1788 r = mlst.getToRanges();
1789 for (int s = 0; s < r.length; s += 2)
1791 MapListTo mto = new MapListTo();
1793 mto.setEnd(r[s + 1]);
1794 mp.addMapListTo(mto);
1796 mp.setMapFromUnit(mlst.getFromRatio());
1797 mp.setMapToUnit(mlst.getToRatio());
1798 if (jmp.getTo() != null)
1800 MappingChoice mpc = new MappingChoice();
1802 && (parentseq != jmp.getTo() || parentseq
1803 .getDatasetSequence() != jmp.getTo()))
1805 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1811 SequenceI ps = null;
1812 if (parentseq != jmp.getTo()
1813 && parentseq.getDatasetSequence() != jmp.getTo())
1815 // chaining dbref rather than a handshaking one
1816 jmpid = seqHash(ps = jmp.getTo());
1820 jmpid = seqHash(ps = parentseq);
1822 mpc.setDseqFor(jmpid);
1823 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1825 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1826 seqRefIds.put(mpc.getDseqFor(), ps);
1830 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1833 mp.setMappingChoice(mpc);
1839 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
1840 List<UserColourScheme> userColours, JalviewModelSequence jms)
1843 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1844 boolean newucs = false;
1845 if (!userColours.contains(ucs))
1847 userColours.add(ucs);
1850 id = "ucs" + userColours.indexOf(ucs);
1853 // actually create the scheme's entry in the XML model
1854 java.awt.Color[] colours = ucs.getColours();
1855 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1856 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1858 for (int i = 0; i < colours.length; i++)
1860 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1861 col.setName(ResidueProperties.aa[i]);
1862 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1863 jbucs.addColour(col);
1865 if (ucs.getLowerCaseColours() != null)
1867 colours = ucs.getLowerCaseColours();
1868 for (int i = 0; i < colours.length; i++)
1870 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1871 col.setName(ResidueProperties.aa[i].toLowerCase());
1872 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1873 jbucs.addColour(col);
1878 uc.setUserColourScheme(jbucs);
1879 jms.addUserColours(uc);
1885 jalview.schemes.UserColourScheme getUserColourScheme(
1886 JalviewModelSequence jms, String id)
1888 UserColours[] uc = jms.getUserColours();
1889 UserColours colours = null;
1891 for (int i = 0; i < uc.length; i++)
1893 if (uc[i].getId().equals(id))
1901 java.awt.Color[] newColours = new java.awt.Color[24];
1903 for (int i = 0; i < 24; i++)
1905 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1906 .getUserColourScheme().getColour(i).getRGB(), 16));
1909 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1912 if (colours.getUserColourScheme().getColourCount() > 24)
1914 newColours = new java.awt.Color[23];
1915 for (int i = 0; i < 23; i++)
1917 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1918 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1920 ucs.setLowerCaseColours(newColours);
1927 * contains last error message (if any) encountered by XML loader.
1929 String errorMessage = null;
1932 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1933 * exceptions are raised during project XML parsing
1935 public boolean attemptversion1parse = true;
1938 * Load a jalview project archive from a jar file
1941 * - HTTP URL or filename
1943 public AlignFrame loadJalviewAlign(final String file)
1946 jalview.gui.AlignFrame af = null;
1950 // create list to store references for any new Jmol viewers created
1951 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1952 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1953 // Workaround is to make sure caller implements the JarInputStreamProvider
1955 // so we can re-open the jar input stream for each entry.
1957 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1958 af = loadJalviewAlign(jprovider);
1960 } catch (MalformedURLException e)
1962 errorMessage = "Invalid URL format for '" + file + "'";
1968 SwingUtilities.invokeAndWait(new Runnable()
1972 setLoadingFinishedForNewStructureViewers();
1975 } catch (Exception x)
1983 private jarInputStreamProvider createjarInputStreamProvider(
1984 final String file) throws MalformedURLException
1987 errorMessage = null;
1988 uniqueSetSuffix = null;
1990 viewportsAdded = null;
1991 frefedSequence = null;
1993 if (file.startsWith("http://"))
1995 url = new URL(file);
1997 final URL _url = url;
1998 return new jarInputStreamProvider()
2002 public JarInputStream getJarInputStream() throws IOException
2006 return new JarInputStream(_url.openStream());
2010 return new JarInputStream(new FileInputStream(file));
2015 public String getFilename()
2023 * Recover jalview session from a jalview project archive. Caller may
2024 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2025 * themselves. Any null fields will be initialised with default values,
2026 * non-null fields are left alone.
2031 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2033 errorMessage = null;
2034 if (uniqueSetSuffix == null)
2036 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2038 if (seqRefIds == null)
2040 seqRefIds = new HashMap<String, SequenceI>();
2042 if (viewportsAdded == null)
2044 viewportsAdded = new Hashtable();
2046 if (frefedSequence == null)
2048 frefedSequence = new Vector();
2051 jalview.gui.AlignFrame af = null, _af = null;
2052 Hashtable gatherToThisFrame = new Hashtable();
2053 final String file = jprovider.getFilename();
2056 JarInputStream jin = null;
2057 JarEntry jarentry = null;
2062 jin = jprovider.getJarInputStream();
2063 for (int i = 0; i < entryCount; i++)
2065 jarentry = jin.getNextJarEntry();
2068 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2070 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2071 JalviewModel object = new JalviewModel();
2073 Unmarshaller unmar = new Unmarshaller(object);
2074 unmar.setValidation(false);
2075 object = (JalviewModel) unmar.unmarshal(in);
2076 if (true) // !skipViewport(object))
2078 _af = loadFromObject(object, file, true, jprovider);
2079 if (object.getJalviewModelSequence().getViewportCount() > 0)
2082 if (af.viewport.isGatherViewsHere())
2084 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2090 else if (jarentry != null)
2092 // Some other file here.
2095 } while (jarentry != null);
2096 resolveFrefedSequences();
2097 } catch (java.io.FileNotFoundException ex)
2099 ex.printStackTrace();
2100 errorMessage = "Couldn't locate Jalview XML file : " + file;
2101 System.err.println("Exception whilst loading jalview XML file : "
2103 } catch (java.net.UnknownHostException ex)
2105 ex.printStackTrace();
2106 errorMessage = "Couldn't locate Jalview XML file : " + file;
2107 System.err.println("Exception whilst loading jalview XML file : "
2109 } catch (Exception ex)
2111 System.err.println("Parsing as Jalview Version 2 file failed.");
2112 ex.printStackTrace(System.err);
2113 if (attemptversion1parse)
2115 // Is Version 1 Jar file?
2118 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2119 } catch (Exception ex2)
2121 System.err.println("Exception whilst loading as jalviewXMLV1:");
2122 ex2.printStackTrace();
2126 if (Desktop.instance != null)
2128 Desktop.instance.stopLoading();
2132 System.out.println("Successfully loaded archive file");
2135 ex.printStackTrace();
2137 System.err.println("Exception whilst loading jalview XML file : "
2139 } catch (OutOfMemoryError e)
2141 // Don't use the OOM Window here
2142 errorMessage = "Out of memory loading jalview XML file";
2143 System.err.println("Out of memory whilst loading jalview XML file");
2144 e.printStackTrace();
2147 if (Desktop.instance != null)
2149 Desktop.instance.stopLoading();
2152 Enumeration en = gatherToThisFrame.elements();
2153 while (en.hasMoreElements())
2155 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2157 if (errorMessage != null)
2165 * check errorMessage for a valid error message and raise an error box in the
2166 * GUI or write the current errorMessage to stderr and then clear the error
2169 protected void reportErrors()
2171 reportErrors(false);
2174 protected void reportErrors(final boolean saving)
2176 if (errorMessage != null)
2178 final String finalErrorMessage = errorMessage;
2181 javax.swing.SwingUtilities.invokeLater(new Runnable()
2186 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2187 finalErrorMessage, "Error "
2188 + (saving ? "saving" : "loading")
2189 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2195 System.err.println("Problem loading Jalview file: " + errorMessage);
2198 errorMessage = null;
2201 Hashtable<String, String> alreadyLoadedPDB;
2204 * when set, local views will be updated from view stored in JalviewXML
2205 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2206 * sync if this is set to true.
2208 private final boolean updateLocalViews = false;
2210 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2212 if (alreadyLoadedPDB == null)
2214 alreadyLoadedPDB = new Hashtable();
2217 if (alreadyLoadedPDB.containsKey(pdbId))
2219 return alreadyLoadedPDB.get(pdbId).toString();
2224 JarInputStream jin = jprovider.getJarInputStream();
2226 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2227 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2228 * FileInputStream(jprovider)); }
2231 JarEntry entry = null;
2234 entry = jin.getNextJarEntry();
2235 } while (entry != null && !entry.getName().equals(pdbId));
2238 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2239 File outFile = File.createTempFile("jalview_pdb", ".txt");
2240 outFile.deleteOnExit();
2241 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2244 while ((data = in.readLine()) != null)
2251 } catch (Exception foo)
2256 String t = outFile.getAbsolutePath();
2257 alreadyLoadedPDB.put(pdbId, t);
2262 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2264 } catch (Exception ex)
2266 ex.printStackTrace();
2272 private class JvAnnotRow
2274 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2281 * persisted version of annotation row from which to take vis properties
2283 public jalview.datamodel.AlignmentAnnotation template;
2286 * original position of the annotation row in the alignment
2292 * Load alignment frame from jalview XML DOM object
2297 * filename source string
2298 * @param loadTreesAndStructures
2299 * when false only create Viewport
2301 * data source provider
2302 * @return alignment frame created from view stored in DOM
2304 AlignFrame loadFromObject(JalviewModel object, String file,
2305 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2307 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2308 Sequence[] vamsasSeq = vamsasSet.getSequence();
2310 JalviewModelSequence jms = object.getJalviewModelSequence();
2312 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2315 // ////////////////////////////////
2318 Vector hiddenSeqs = null;
2319 jalview.datamodel.Sequence jseq;
2321 ArrayList tmpseqs = new ArrayList();
2323 boolean multipleView = false;
2325 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2326 int vi = 0; // counter in vamsasSeq array
2327 for (int i = 0; i < jseqs.length; i++)
2329 String seqId = jseqs[i].getId();
2331 if (seqRefIds.get(seqId) != null)
2333 tmpseqs.add(seqRefIds.get(seqId));
2334 multipleView = true;
2338 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2339 vamsasSeq[vi].getSequence());
2340 jseq.setDescription(vamsasSeq[vi].getDescription());
2341 jseq.setStart(jseqs[i].getStart());
2342 jseq.setEnd(jseqs[i].getEnd());
2343 jseq.setVamsasId(uniqueSetSuffix + seqId);
2344 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2349 if (jseqs[i].getHidden())
2351 if (hiddenSeqs == null)
2353 hiddenSeqs = new Vector();
2356 hiddenSeqs.addElement(seqRefIds.get(seqId));
2362 // Create the alignment object from the sequence set
2363 // ///////////////////////////////
2364 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2367 tmpseqs.toArray(orderedSeqs);
2369 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2372 // / Add the alignment properties
2373 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2375 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2376 al.setProperty(ssp.getKey(), ssp.getValue());
2380 // SequenceFeatures are added to the DatasetSequence,
2381 // so we must create or recover the dataset before loading features
2382 // ///////////////////////////////
2383 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2385 // older jalview projects do not have a dataset id.
2386 al.setDataset(null);
2390 // recover dataset - passing on flag indicating if this a 'viewless'
2391 // sequence set (a.k.a. a stored dataset for the project)
2392 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2393 .getViewportCount() == 0);
2395 // ///////////////////////////////
2397 Hashtable pdbloaded = new Hashtable();
2400 // load sequence features, database references and any associated PDB
2401 // structures for the alignment
2402 for (int i = 0; i < vamsasSeq.length; i++)
2404 if (jseqs[i].getFeaturesCount() > 0)
2406 Features[] features = jseqs[i].getFeatures();
2407 for (int f = 0; f < features.length; f++)
2409 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2410 features[f].getType(), features[f].getDescription(),
2411 features[f].getStatus(), features[f].getBegin(),
2412 features[f].getEnd(), features[f].getFeatureGroup());
2414 sf.setScore(features[f].getScore());
2415 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2417 OtherData keyValue = features[f].getOtherData(od);
2418 if (keyValue.getKey().startsWith("LINK"))
2420 sf.addLink(keyValue.getValue());
2424 sf.setValue(keyValue.getKey(), keyValue.getValue());
2429 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2432 if (vamsasSeq[i].getDBRefCount() > 0)
2434 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2436 if (jseqs[i].getPdbidsCount() > 0)
2438 Pdbids[] ids = jseqs[i].getPdbids();
2439 for (int p = 0; p < ids.length; p++)
2441 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2442 entry.setId(ids[p].getId());
2443 entry.setType(ids[p].getType());
2444 if (ids[p].getFile() != null)
2446 if (!pdbloaded.containsKey(ids[p].getFile()))
2448 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2452 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2455 StructureSelectionManager.getStructureSelectionManager(
2456 Desktop.instance).registerPDBEntry(entry);
2457 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2461 } // end !multipleview
2463 // ///////////////////////////////
2464 // LOAD SEQUENCE MAPPINGS
2466 if (vamsasSet.getAlcodonFrameCount() > 0)
2468 // TODO Potentially this should only be done once for all views of an
2470 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2471 for (int i = 0; i < alc.length; i++)
2473 AlignedCodonFrame cf = new AlignedCodonFrame();
2474 if (alc[i].getAlcodMapCount() > 0)
2476 AlcodMap[] maps = alc[i].getAlcodMap();
2477 for (int m = 0; m < maps.length; m++)
2479 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2481 jalview.datamodel.Mapping mapping = null;
2482 // attach to dna sequence reference.
2483 if (maps[m].getMapping() != null)
2485 mapping = addMapping(maps[m].getMapping());
2489 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2494 frefedSequence.add(new Object[]
2495 { maps[m].getDnasq(), cf, mapping });
2499 al.addCodonFrame(cf);
2503 // ////////////////////////////////
2505 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2507 * store any annotations which forward reference a group's ID
2509 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2511 if (vamsasSet.getAnnotationCount() > 0)
2513 Annotation[] an = vamsasSet.getAnnotation();
2515 for (int i = 0; i < an.length; i++)
2518 * test if annotation is automatically calculated for this view only
2520 boolean autoForView = false;
2521 if (an[i].getLabel().equals("Quality")
2522 || an[i].getLabel().equals("Conservation")
2523 || an[i].getLabel().equals("Consensus"))
2525 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2527 if (!an[i].hasAutoCalculated())
2529 an[i].setAutoCalculated(true);
2533 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2535 // remove ID - we don't recover annotation from other views for
2536 // view-specific annotation
2540 // set visiblity for other annotation in this view
2541 if (an[i].getId() != null
2542 && annotationIds.containsKey(an[i].getId()))
2544 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2545 .get(an[i].getId());
2546 // in principle Visible should always be true for annotation displayed
2547 // in multiple views
2548 if (an[i].hasVisible())
2550 jda.visible = an[i].getVisible();
2553 al.addAnnotation(jda);
2557 // Construct new annotation from model.
2558 AnnotationElement[] ae = an[i].getAnnotationElement();
2559 jalview.datamodel.Annotation[] anot = null;
2560 java.awt.Color firstColour = null;
2562 if (!an[i].getScoreOnly())
2564 anot = new jalview.datamodel.Annotation[al.getWidth()];
2565 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2567 anpos = ae[aa].getPosition();
2569 if (anpos >= anot.length)
2574 anot[anpos] = new jalview.datamodel.Annotation(
2576 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2577 (ae[aa].getSecondaryStructure() == null || ae[aa]
2578 .getSecondaryStructure().length() == 0) ? ' '
2579 : ae[aa].getSecondaryStructure().charAt(0),
2583 // JBPNote: Consider verifying dataflow for IO of secondary
2584 // structure annotation read from Stockholm files
2585 // this was added to try to ensure that
2586 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2588 // anot[ae[aa].getPosition()].displayCharacter = "";
2590 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2591 if (firstColour == null)
2593 firstColour = anot[anpos].colour;
2597 jalview.datamodel.AlignmentAnnotation jaa = null;
2599 if (an[i].getGraph())
2601 float llim = 0, hlim = 0;
2602 // if (autoForView || an[i].isAutoCalculated()) {
2605 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2606 an[i].getDescription(), anot, llim, hlim,
2607 an[i].getGraphType());
2609 jaa.graphGroup = an[i].getGraphGroup();
2610 jaa._linecolour = firstColour;
2611 if (an[i].getThresholdLine() != null)
2613 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2614 .getThresholdLine().getValue(), an[i]
2615 .getThresholdLine().getLabel(), new java.awt.Color(
2616 an[i].getThresholdLine().getColour())));
2619 if (autoForView || an[i].isAutoCalculated())
2621 // Hardwire the symbol display line to ensure that labels for
2622 // histograms are displayed
2628 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2629 an[i].getDescription(), anot);
2630 jaa._linecolour = firstColour;
2632 // register new annotation
2633 if (an[i].getId() != null)
2635 annotationIds.put(an[i].getId(), jaa);
2636 jaa.annotationId = an[i].getId();
2638 // recover sequence association
2639 if (an[i].getSequenceRef() != null)
2641 if (al.findName(an[i].getSequenceRef()) != null)
2643 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2645 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2648 // and make a note of any group association
2649 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2651 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2652 .get(an[i].getGroupRef());
2655 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2656 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2661 if (an[i].hasScore())
2663 jaa.setScore(an[i].getScore());
2665 if (an[i].hasVisible())
2667 jaa.visible = an[i].getVisible();
2670 if (an[i].hasCentreColLabels())
2672 jaa.centreColLabels = an[i].getCentreColLabels();
2675 if (an[i].hasScaleColLabels())
2677 jaa.scaleColLabel = an[i].getScaleColLabels();
2679 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2681 // newer files have an 'autoCalculated' flag and store calculation
2682 // state in viewport properties
2683 jaa.autoCalculated = true; // means annotation will be marked for
2684 // update at end of load.
2686 if (an[i].hasGraphHeight())
2688 jaa.graphHeight = an[i].getGraphHeight();
2690 if (an[i].hasBelowAlignment())
2692 jaa.belowAlignment = an[i].isBelowAlignment();
2694 jaa.setCalcId(an[i].getCalcId());
2695 if (an[i].getPropertyCount() > 0)
2697 for (jalview.schemabinding.version2.Property prop : an[i]
2700 jaa.setProperty(prop.getName(), prop.getValue());
2703 if (jaa.autoCalculated)
2705 autoAlan.add(new JvAnnotRow(i, jaa));
2708 // if (!autoForView)
2710 // add autocalculated group annotation and any user created annotation
2712 al.addAnnotation(jaa);
2716 // ///////////////////////
2718 // Create alignment markup and styles for this view
2719 if (jms.getJGroupCount() > 0)
2721 JGroup[] groups = jms.getJGroup();
2722 boolean addAnnotSchemeGroup = false;
2723 for (int i = 0; i < groups.length; i++)
2725 ColourSchemeI cs = null;
2727 if (groups[i].getColour() != null)
2729 if (groups[i].getColour().startsWith("ucs"))
2731 cs = getUserColourScheme(jms, groups[i].getColour());
2733 else if (groups[i].getColour().equals("AnnotationColourGradient")
2734 && groups[i].getAnnotationColours() != null)
2736 addAnnotSchemeGroup = true;
2741 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2746 cs.setThreshold(groups[i].getPidThreshold(), true);
2750 Vector seqs = new Vector();
2752 for (int s = 0; s < groups[i].getSeqCount(); s++)
2754 String seqId = groups[i].getSeq(s) + "";
2755 jalview.datamodel.SequenceI ts = seqRefIds.get(seqId);
2759 seqs.addElement(ts);
2763 if (seqs.size() < 1)
2768 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2769 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2770 groups[i].getDisplayText(), groups[i].getColourText(),
2771 groups[i].getStart(), groups[i].getEnd());
2773 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2775 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2776 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2777 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2778 .isShowUnconserved() : false);
2779 sg.thresholdTextColour = groups[i].getTextColThreshold();
2780 if (groups[i].hasShowConsensusHistogram())
2782 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2785 if (groups[i].hasShowSequenceLogo())
2787 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2789 if (groups[i].hasNormaliseSequenceLogo())
2791 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2793 if (groups[i].hasIgnoreGapsinConsensus())
2795 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2797 if (groups[i].getConsThreshold() != 0)
2799 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2800 "All", ResidueProperties.propHash, 3,
2801 sg.getSequences(null), 0, sg.getWidth() - 1);
2803 c.verdict(false, 25);
2804 sg.cs.setConservation(c);
2807 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2809 // re-instate unique group/annotation row reference
2810 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2811 .get(groups[i].getId());
2814 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2817 if (jaa.autoCalculated)
2819 // match up and try to set group autocalc alignment row for this
2821 if (jaa.label.startsWith("Consensus for "))
2823 sg.setConsensus(jaa);
2825 // match up and try to set group autocalc alignment row for this
2827 if (jaa.label.startsWith("Conservation for "))
2829 sg.setConservationRow(jaa);
2836 if (addAnnotSchemeGroup)
2838 // reconstruct the annotation colourscheme
2839 sg.cs = constructAnnotationColour(
2840 groups[i].getAnnotationColours(), null, al, jms, false);
2846 // only dataset in this model, so just return.
2849 // ///////////////////////////////
2852 // If we just load in the same jar file again, the sequenceSetId
2853 // will be the same, and we end up with multiple references
2854 // to the same sequenceSet. We must modify this id on load
2855 // so that each load of the file gives a unique id
2856 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2857 String viewId = (view.getId() == null ? null : view.getId()
2859 AlignFrame af = null;
2860 AlignViewport av = null;
2861 // now check to see if we really need to create a new viewport.
2862 if (multipleView && viewportsAdded.size() == 0)
2864 // We recovered an alignment for which a viewport already exists.
2865 // TODO: fix up any settings necessary for overlaying stored state onto
2866 // state recovered from another document. (may not be necessary).
2867 // we may need a binding from a viewport in memory to one recovered from
2869 // and then recover its containing af to allow the settings to be applied.
2870 // TODO: fix for vamsas demo
2872 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2874 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2875 if (seqsetobj != null)
2877 if (seqsetobj instanceof String)
2879 uniqueSeqSetId = (String) seqsetobj;
2881 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2887 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2893 * indicate that annotation colours are applied across all groups (pre
2894 * Jalview 2.8.1 behaviour)
2896 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2897 object.getVersion());
2899 AlignmentPanel ap = null;
2900 boolean isnewview = true;
2903 // Check to see if this alignment already has a view id == viewId
2904 jalview.gui.AlignmentPanel views[] = Desktop
2905 .getAlignmentPanels(uniqueSeqSetId);
2906 if (views != null && views.length > 0)
2908 for (int v = 0; v < views.length; v++)
2910 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2912 // recover the existing alignpanel, alignframe, viewport
2913 af = views[v].alignFrame;
2916 // TODO: could even skip resetting view settings if we don't want to
2917 // change the local settings from other jalview processes
2926 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
2927 uniqueSeqSetId, viewId, autoAlan);
2932 // /////////////////////////////////////
2933 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2937 for (int t = 0; t < jms.getTreeCount(); t++)
2940 Tree tree = jms.getTree(t);
2942 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2945 tp = af.ShowNewickTree(
2946 new jalview.io.NewickFile(tree.getNewick()),
2947 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2948 tree.getXpos(), tree.getYpos());
2949 if (tree.getId() != null)
2951 // perhaps bind the tree id to something ?
2956 // update local tree attributes ?
2957 // TODO: should check if tp has been manipulated by user - if so its
2958 // settings shouldn't be modified
2959 tp.setTitle(tree.getTitle());
2960 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2961 .getWidth(), tree.getHeight()));
2962 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2965 tp.treeCanvas.av = av; // af.viewport;
2966 tp.treeCanvas.ap = ap; // af.alignPanel;
2971 warn("There was a problem recovering stored Newick tree: \n"
2972 + tree.getNewick());
2976 tp.fitToWindow.setState(tree.getFitToWindow());
2977 tp.fitToWindow_actionPerformed(null);
2979 if (tree.getFontName() != null)
2981 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2982 .getFontStyle(), tree.getFontSize()));
2986 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2987 .getFontStyle(), tree.getFontSize()));
2990 tp.showPlaceholders(tree.getMarkUnlinked());
2991 tp.showBootstrap(tree.getShowBootstrap());
2992 tp.showDistances(tree.getShowDistances());
2994 tp.treeCanvas.threshold = tree.getThreshold();
2996 if (tree.getCurrentTree())
2998 af.viewport.setCurrentTree(tp.getTree());
3002 } catch (Exception ex)
3004 ex.printStackTrace();
3008 // //LOAD STRUCTURES
3009 if (loadTreesAndStructures)
3011 loadStructures(jprovider, jseqs, af, ap);
3013 // and finally return.
3018 * Load and link any saved structure viewers.
3025 protected void loadStructures(jarInputStreamProvider jprovider,
3026 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3029 * Run through all PDB ids on the alignment, and collect mappings between
3030 * distinct view ids and all sequences referring to that view.
3032 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3034 for (int i = 0; i < jseqs.length; i++)
3036 if (jseqs[i].getPdbidsCount() > 0)
3038 Pdbids[] ids = jseqs[i].getPdbids();
3039 for (int p = 0; p < ids.length; p++)
3041 final int structureStateCount = ids[p].getStructureStateCount();
3042 for (int s = 0; s < structureStateCount; s++)
3044 // check to see if we haven't already created this structure view
3045 final StructureState structureState = ids[p]
3046 .getStructureState(s);
3047 String sviewid = (structureState.getViewId() == null) ? null
3048 : structureState.getViewId() + uniqueSetSuffix;
3049 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3050 // Originally : ids[p].getFile()
3051 // : TODO: verify external PDB file recovery still works in normal
3052 // jalview project load
3053 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3054 jpdb.setId(ids[p].getId());
3056 int x = structureState.getXpos();
3057 int y = structureState.getYpos();
3058 int width = structureState.getWidth();
3059 int height = structureState.getHeight();
3061 // Probably don't need to do this anymore...
3062 // Desktop.desktop.getComponentAt(x, y);
3063 // TODO: NOW: check that this recovers the PDB file correctly.
3064 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3065 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3067 if (sviewid == null)
3069 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3072 if (!structureViewers.containsKey(sviewid))
3074 structureViewers.put(sviewid, new StructureViewerModel(x, y,
3075 width, height, false, false, true));
3076 // Legacy pre-2.7 conversion JAL-823 :
3077 // do not assume any view has to be linked for colour by
3081 // assemble String[] { pdb files }, String[] { id for each
3082 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3083 // seqs_file 2}, boolean[] {
3084 // linkAlignPanel,superposeWithAlignpanel}} from hash
3085 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3086 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3087 | (structureState.hasAlignwithAlignPanel() ? structureState
3088 .getAlignwithAlignPanel() : false));
3091 * Default colour by linked panel to false if not specified (e.g.
3092 * for pre-2.7 projects)
3094 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3095 colourWithAlignPanel |= (structureState
3096 .hasColourwithAlignPanel() ? structureState
3097 .getColourwithAlignPanel() : false);
3098 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3101 * Default colour by viewer to true if not specified (e.g. for
3104 boolean colourByViewer = jmoldat.isColourByViewer();
3105 colourByViewer &= structureState.hasColourByJmol() ? structureState
3106 .getColourByJmol() : true;
3107 jmoldat.setColourByViewer(colourByViewer);
3109 if (jmoldat.getStateData().length() < structureState
3110 .getContent().length())
3113 jmoldat.setStateData(structureState.getContent());
3116 if (ids[p].getFile() != null)
3118 File mapkey = new File(ids[p].getFile());
3119 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3120 if (seqstrmaps == null)
3122 jmoldat.getFileData().put(
3124 seqstrmaps = jmoldat.new StructureData(pdbFile,
3127 if (!seqstrmaps.getSeqList().contains(seq))
3129 seqstrmaps.getSeqList().add(seq);
3135 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");
3142 // Instantiate the associated structure views
3143 for (Entry<String, StructureViewerModel> entry : structureViewers
3146 createOrLinkStructureViewer(entry, af, ap);
3156 protected void createOrLinkStructureViewer(
3157 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3160 final StructureViewerModel svattrib = viewerData.getValue();
3163 * Search for any viewer windows already open from other alignment views
3164 * that exactly match the stored structure state
3166 StructureViewerBase comp = findMatchingViewer(viewerData);
3170 linkStructureViewer(ap, comp, svattrib);
3175 * Pending an XML element for ViewerType, just check if stateData contains
3176 * "chimera" (part of the chimera session filename).
3178 if (svattrib.getStateData().indexOf("chimera") > -1)
3180 createChimeraViewer(viewerData, af);
3184 createJmolViewer(viewerData, af);
3189 * Create a new Chimera viewer.
3194 protected void createChimeraViewer(
3195 Entry<String, StructureViewerModel> viewerData, AlignFrame af)
3197 final StructureViewerModel data = viewerData.getValue();
3198 String chimeraSession = data.getStateData();
3200 if (new File(chimeraSession).exists())
3202 Set<Entry<File, StructureData>> fileData = data.getFileData()
3204 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3205 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3206 for (Entry<File, StructureData> pdb : fileData)
3208 String filePath = pdb.getValue().getFilePath();
3209 String pdbId = pdb.getValue().getPdbId();
3210 pdbs.add(new PDBEntry(filePath, pdbId));
3211 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3212 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3216 boolean colourByChimera = data.isColourByViewer();
3217 boolean colourBySequence = data.isColourWithAlignPanel();
3219 // TODO can/should this be done via StructureViewer (like Jmol)?
3220 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3221 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3223 new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray,
3224 seqsArray, colourByChimera, colourBySequence);
3228 Cache.log.error("Chimera session file " + chimeraSession
3234 * Create a new Jmol window. First parse the Jmol state to translate filenames
3235 * loaded into the view, and record the order in which files are shown in the
3236 * Jmol view, so we can add the sequence mappings in same order.
3241 protected void createJmolViewer(
3242 final Entry<String, StructureViewerModel> viewerData,
3245 final StructureViewerModel svattrib = viewerData.getValue();
3246 String state = svattrib.getStateData();
3247 List<String> pdbfilenames = new ArrayList<String>();
3248 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3249 List<String> pdbids = new ArrayList<String>();
3250 StringBuilder newFileLoc = new StringBuilder(64);
3251 int cp = 0, ncp, ecp;
3252 Map<File, StructureData> oldFiles = svattrib.getFileData();
3253 while ((ncp = state.indexOf("load ", cp)) > -1)
3257 // look for next filename in load statement
3258 newFileLoc.append(state.substring(cp,
3259 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3260 String oldfilenam = state.substring(ncp,
3261 ecp = state.indexOf("\"", ncp));
3262 // recover the new mapping data for this old filename
3263 // have to normalize filename - since Jmol and jalview do
3265 // translation differently.
3266 StructureData filedat = oldFiles.get(new File(oldfilenam));
3267 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3268 pdbfilenames.add(filedat.getFilePath());
3269 pdbids.add(filedat.getPdbId());
3270 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3271 newFileLoc.append("\"");
3272 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3273 // look for next file statement.
3274 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3278 // just append rest of state
3279 newFileLoc.append(state.substring(cp));
3283 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3284 newFileLoc = new StringBuilder(state);
3285 newFileLoc.append("; load append ");
3286 for (File id : oldFiles.keySet())
3288 // add this and any other pdb files that should be present in
3290 StructureData filedat = oldFiles.get(id);
3291 newFileLoc.append(filedat.getFilePath());
3292 pdbfilenames.add(filedat.getFilePath());
3293 pdbids.add(filedat.getPdbId());
3294 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3295 newFileLoc.append(" \"");
3296 newFileLoc.append(filedat.getFilePath());
3297 newFileLoc.append("\"");
3300 newFileLoc.append(";");
3303 if (newFileLoc.length() > 0)
3305 int histbug = newFileLoc.indexOf("history = ");
3307 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3308 String val = (diff == -1) ? null : newFileLoc
3309 .substring(histbug, diff);
3310 if (val != null && val.length() >= 4)
3312 if (val.contains("e"))
3314 if (val.trim().equals("true"))
3322 newFileLoc.replace(histbug, diff, val);
3326 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3328 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3329 final SequenceI[][] sq = seqmaps
3330 .toArray(new SequenceI[seqmaps.size()][]);
3331 final String fileloc = newFileLoc.toString();
3332 final String sviewid = viewerData.getKey();
3333 final AlignFrame alf = af;
3334 final Rectangle rect = new Rectangle(svattrib.getX(),
3335 svattrib.getY(), svattrib.getWidth(), svattrib.getHeight());
3338 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3343 JalviewStructureDisplayI sview = null;
3346 // JAL-1333 note - we probably can't migrate Jmol views to UCSF
3348 sview = new StructureViewer(alf.alignPanel
3349 .getStructureSelectionManager()).createView(
3350 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3351 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3352 addNewStructureViewer(sview);
3353 } catch (OutOfMemoryError ex)
3355 new OOMWarning("restoring structure view for PDB id " + id,
3356 (OutOfMemoryError) ex.getCause());
3357 if (sview != null && sview.isVisible())
3359 sview.closeViewer();
3360 sview.setVisible(false);
3366 } catch (InvocationTargetException ex)
3368 warn("Unexpected error when opening Jmol view.", ex);
3370 } catch (InterruptedException e)
3372 // e.printStackTrace();
3378 * Returns any open frame that matches given structure viewer data. The match
3379 * is based on the unique viewId, or (for older project versions) the frame's
3385 protected StructureViewerBase findMatchingViewer(
3386 Entry<String, StructureViewerModel> viewerData)
3388 final String sviewid = viewerData.getKey();
3389 final StructureViewerModel svattrib = viewerData.getValue();
3390 StructureViewerBase comp = null;
3391 JInternalFrame[] frames = getAllFrames();
3392 for (JInternalFrame frame : frames)
3394 if (frame instanceof StructureViewerBase)
3397 * Post jalview 2.4 schema includes structure view id
3400 && ((StructureViewerBase) frame).getViewId()
3403 comp = (AppJmol) frame;
3407 * Otherwise test for matching position and size of viewer frame
3409 else if (frame.getX() == svattrib.getX()
3410 && frame.getY() == svattrib.getY()
3411 && frame.getHeight() == svattrib.getHeight()
3412 && frame.getWidth() == svattrib.getWidth())
3414 comp = (AppJmol) frame;
3423 * Link an AlignmentPanel to an existing structure viewer.
3428 * @param useinViewerSuperpos
3429 * @param usetoColourbyseq
3430 * @param viewerColouring
3432 protected void linkStructureViewer(AlignmentPanel ap,
3433 StructureViewerBase viewer, StructureViewerModel svattrib)
3435 // NOTE: if the jalview project is part of a shared session then
3436 // view synchronization should/could be done here.
3438 final boolean useinViewerSuperpos = svattrib.isAlignWithPanel();
3439 final boolean usetoColourbyseq = svattrib.isColourWithAlignPanel();
3440 final boolean viewerColouring = svattrib.isColourByViewer();
3441 Map<File, StructureData> oldFiles = svattrib.getFileData();
3444 * Add mapping for sequences in this view to an already open viewer
3446 final AAStructureBindingModel binding = viewer.getBinding();
3447 for (File id : oldFiles.keySet())
3449 // add this and any other pdb files that should be present in the
3451 StructureData filedat = oldFiles.get(id);
3452 String pdbFile = filedat.getFilePath();
3453 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3454 binding.getSsm().setMapping(seq, null, pdbFile,
3455 jalview.io.AppletFormatAdapter.FILE);
3456 binding.addSequenceForStructFile(pdbFile, seq);
3458 // and add the AlignmentPanel's reference to the view panel
3459 viewer.addAlignmentPanel(ap);
3460 if (useinViewerSuperpos)
3462 viewer.useAlignmentPanelForSuperposition(ap);
3466 viewer.excludeAlignmentPanelForSuperposition(ap);
3468 if (usetoColourbyseq)
3470 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3474 viewer.excludeAlignmentPanelForColourbyseq(ap);
3479 * Get all frames within the Desktop.
3483 protected JInternalFrame[] getAllFrames()
3485 JInternalFrame[] frames = null;
3486 // TODO is this necessary - is it safe - risk of hanging?
3491 frames = Desktop.desktop.getAllFrames();
3492 } catch (ArrayIndexOutOfBoundsException e)
3494 // occasional No such child exceptions are thrown here...
3498 } catch (InterruptedException f)
3502 } while (frames == null);
3509 * - minimum version we are comparing against
3511 * - version of data being processsed.
3512 * @return true if version is development/null or evaluates to the same or
3513 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3515 private boolean isVersionStringLaterThan(String supported, String version)
3517 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3518 || version.equalsIgnoreCase("Test")
3519 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3521 System.err.println("Assuming project file with "
3522 + (version == null ? "null" : version)
3523 + " is compatible with Jalview version " + supported);
3528 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3530 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3532 // convert b to decimal to catch bugfix releases within a series
3533 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3534 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3537 if (Float.valueOf(curT) > Float.valueOf(fileT))
3539 // current version is newer than the version that wrote the file
3542 } catch (NumberFormatException nfe)
3545 .println("** WARNING: Version comparison failed for tokens ("
3549 + ")\n** Current: '"
3550 + supported + "' and Version: '" + version + "'");
3553 if (currentV.hasMoreElements())
3555 // fileV has no minor version but identical series to current
3562 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3564 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3566 if (newStructureViewers != null)
3568 sview.getBinding().setFinishedLoadingFromArchive(false);
3569 newStructureViewers.add(sview);
3573 protected void setLoadingFinishedForNewStructureViewers()
3575 if (newStructureViewers != null)
3577 for (JalviewStructureDisplayI sview : newStructureViewers)
3579 sview.getBinding().setFinishedLoadingFromArchive(true);
3581 newStructureViewers.clear();
3582 newStructureViewers = null;
3586 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3587 Alignment al, JalviewModelSequence jms, Viewport view,
3588 String uniqueSeqSetId, String viewId,
3589 ArrayList<JvAnnotRow> autoAlan)
3591 AlignFrame af = null;
3592 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3593 uniqueSeqSetId, viewId);
3595 af.setFileName(file, "Jalview");
3597 for (int i = 0; i < JSEQ.length; i++)
3599 af.viewport.setSequenceColour(af.viewport.getAlignment()
3600 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3603 af.viewport.setGatherViewsHere(view.getGatheredViews());
3605 if (view.getSequenceSetId() != null)
3607 AlignmentViewport av = (AlignmentViewport) viewportsAdded
3608 .get(uniqueSeqSetId);
3610 af.viewport.setSequenceSetId(uniqueSeqSetId);
3613 // propagate shared settings to this new view
3614 af.viewport.setHistoryList(av.getHistoryList());
3615 af.viewport.setRedoList(av.getRedoList());
3619 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3621 // TODO: check if this method can be called repeatedly without
3622 // side-effects if alignpanel already registered.
3623 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3625 // apply Hidden regions to view.
3626 if (hiddenSeqs != null)
3628 for (int s = 0; s < JSEQ.length; s++)
3630 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3632 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3635 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3637 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3640 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3643 for (int s = 0; s < hiddenSeqs.size(); s++)
3645 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3648 af.viewport.hideSequence(hseqs);
3651 // recover view properties and display parameters
3652 if (view.getViewName() != null)
3654 af.viewport.viewName = view.getViewName();
3655 af.setInitialTabVisible();
3657 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3660 af.viewport.setShowAnnotation(view.getShowAnnotation());
3661 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3663 af.viewport.setColourText(view.getShowColourText());
3665 af.viewport.setConservationSelected(view.getConservationSelected());
3666 af.viewport.setShowJVSuffix(view.getShowFullId());
3667 af.viewport.setRightAlignIds(view.getRightAlignIds());
3668 af.viewport.setFont(
3669 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
3670 .getFontSize()), true);
3671 // TODO: allow custom charWidth/Heights to be restored by updating them
3672 // after setting font - which means set above to false
3673 af.viewport.setRenderGaps(view.getRenderGaps());
3674 af.viewport.setWrapAlignment(view.getWrapAlignment());
3675 af.viewport.setShowAnnotation(view.getShowAnnotation());
3677 af.viewport.setShowBoxes(view.getShowBoxes());
3679 af.viewport.setShowText(view.getShowText());
3681 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
3682 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
3683 af.viewport.setThresholdTextColour(view.getTextColThreshold());
3684 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3685 .isShowUnconserved() : false);
3686 af.viewport.setStartRes(view.getStartRes());
3687 af.viewport.setStartSeq(view.getStartSeq());
3688 af.alignPanel.updateLayout();
3689 ColourSchemeI cs = null;
3690 // apply colourschemes
3691 if (view.getBgColour() != null)
3693 if (view.getBgColour().startsWith("ucs"))
3695 cs = getUserColourScheme(jms, view.getBgColour());
3697 else if (view.getBgColour().startsWith("Annotation"))
3699 AnnotationColours viewAnnColour = view.getAnnotationColours();
3700 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3707 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3712 cs.setThreshold(view.getPidThreshold(), true);
3713 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3717 af.viewport.setGlobalColourScheme(cs);
3718 af.viewport.setColourAppliesToAllGroups(false);
3720 if (view.getConservationSelected() && cs != null)
3722 cs.setConservationInc(view.getConsThreshold());
3725 af.changeColour(cs);
3727 af.viewport.setColourAppliesToAllGroups(true);
3729 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
3731 if (view.hasCentreColumnLabels())
3733 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3735 if (view.hasIgnoreGapsinConsensus())
3737 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3740 if (view.hasFollowHighlight())
3742 af.viewport.followHighlight = view.getFollowHighlight();
3744 if (view.hasFollowSelection())
3746 af.viewport.followSelection = view.getFollowSelection();
3748 if (view.hasShowConsensusHistogram())
3750 af.viewport.setShowConsensusHistogram(view
3751 .getShowConsensusHistogram());
3755 af.viewport.setShowConsensusHistogram(true);
3757 if (view.hasShowSequenceLogo())
3759 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3763 af.viewport.setShowSequenceLogo(false);
3765 if (view.hasNormaliseSequenceLogo())
3767 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3769 if (view.hasShowDbRefTooltip())
3771 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
3773 if (view.hasShowNPfeatureTooltip())
3775 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
3777 if (view.hasShowGroupConsensus())
3779 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3783 af.viewport.setShowGroupConsensus(false);
3785 if (view.hasShowGroupConservation())
3787 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3791 af.viewport.setShowGroupConservation(false);
3794 // recover featre settings
3795 if (jms.getFeatureSettings() != null)
3797 FeaturesDisplayed fdi;
3798 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
3799 String[] renderOrder = new String[jms.getFeatureSettings()
3800 .getSettingCount()];
3801 Hashtable featureGroups = new Hashtable();
3802 Hashtable featureColours = new Hashtable();
3803 Hashtable featureOrder = new Hashtable();
3805 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3807 Setting setting = jms.getFeatureSettings().getSetting(fs);
3808 if (setting.hasMincolour())
3810 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3811 new java.awt.Color(setting.getMincolour()),
3812 new java.awt.Color(setting.getColour()),
3813 setting.getMin(), setting.getMax()) : new GraduatedColor(
3814 new java.awt.Color(setting.getMincolour()),
3815 new java.awt.Color(setting.getColour()), 0, 1);
3816 if (setting.hasThreshold())
3818 gc.setThresh(setting.getThreshold());
3819 gc.setThreshType(setting.getThreshstate());
3821 gc.setAutoScaled(true); // default
3822 if (setting.hasAutoScale())
3824 gc.setAutoScaled(setting.getAutoScale());
3826 if (setting.hasColourByLabel())
3828 gc.setColourByLabel(setting.getColourByLabel());
3830 // and put in the feature colour table.
3831 featureColours.put(setting.getType(), gc);
3835 featureColours.put(setting.getType(),
3836 new java.awt.Color(setting.getColour()));
3838 renderOrder[fs] = setting.getType();
3839 if (setting.hasOrder())
3841 featureOrder.put(setting.getType(), setting.getOrder());
3845 featureOrder.put(setting.getType(), new Float(fs
3846 / jms.getFeatureSettings().getSettingCount()));
3848 if (setting.getDisplay())
3850 fdi.setVisible(setting.getType());
3853 Hashtable fgtable = new Hashtable();
3854 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3856 Group grp = jms.getFeatureSettings().getGroup(gs);
3857 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3859 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
3860 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
3861 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
3862 FeatureRendererSettings frs = new FeatureRendererSettings(
3863 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
3864 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
3865 .transferSettings(frs);
3869 if (view.getHiddenColumnsCount() > 0)
3871 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3873 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3874 .getHiddenColumns(c).getEnd() // +1
3878 if (view.getCalcIdParam() != null)
3880 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3882 if (calcIdParam != null)
3884 if (recoverCalcIdParam(calcIdParam, af.viewport))
3889 warn("Couldn't recover parameters for "
3890 + calcIdParam.getCalcId());
3895 af.setMenusFromViewport(af.viewport);
3896 // TODO: we don't need to do this if the viewport is aready visible.
3897 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3899 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3900 reorderAutoannotation(af, al, autoAlan);
3901 af.alignPanel.alignmentChanged();
3905 private ColourSchemeI constructAnnotationColour(
3906 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3907 JalviewModelSequence jms, boolean checkGroupAnnColour)
3909 boolean propagateAnnColour = false;
3910 ColourSchemeI cs = null;
3911 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3912 if (checkGroupAnnColour && al.getGroups() != null
3913 && al.getGroups().size() > 0)
3915 // pre 2.8.1 behaviour
3916 // check to see if we should transfer annotation colours
3917 propagateAnnColour = true;
3918 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3920 if (sg.cs instanceof AnnotationColourGradient)
3922 propagateAnnColour = false;
3926 // int find annotation
3927 if (annAlignment.getAlignmentAnnotation() != null)
3929 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3931 if (annAlignment.getAlignmentAnnotation()[i].label
3932 .equals(viewAnnColour.getAnnotation()))
3934 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3936 annAlignment.getAlignmentAnnotation()[i]
3937 .setThreshold(new jalview.datamodel.GraphLine(
3938 viewAnnColour.getThreshold(), "Threshold",
3939 java.awt.Color.black)
3944 if (viewAnnColour.getColourScheme().equals("None"))
3946 cs = new AnnotationColourGradient(
3947 annAlignment.getAlignmentAnnotation()[i],
3948 new java.awt.Color(viewAnnColour.getMinColour()),
3949 new java.awt.Color(viewAnnColour.getMaxColour()),
3950 viewAnnColour.getAboveThreshold());
3952 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3954 cs = new AnnotationColourGradient(
3955 annAlignment.getAlignmentAnnotation()[i],
3956 getUserColourScheme(jms,
3957 viewAnnColour.getColourScheme()),
3958 viewAnnColour.getAboveThreshold());
3962 cs = new AnnotationColourGradient(
3963 annAlignment.getAlignmentAnnotation()[i],
3964 ColourSchemeProperty.getColour(al,
3965 viewAnnColour.getColourScheme()),
3966 viewAnnColour.getAboveThreshold());
3968 if (viewAnnColour.hasPerSequence())
3970 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3973 if (viewAnnColour.hasPredefinedColours())
3975 ((AnnotationColourGradient) cs)
3976 .setPredefinedColours(viewAnnColour
3977 .isPredefinedColours());
3979 if (propagateAnnColour && al.getGroups() != null)
3981 // Also use these settings for all the groups
3982 for (int g = 0; g < al.getGroups().size(); g++)
3984 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3992 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3993 * new AnnotationColourGradient(
3994 * annAlignment.getAlignmentAnnotation()[i], new
3995 * java.awt.Color(viewAnnColour. getMinColour()), new
3996 * java.awt.Color(viewAnnColour. getMaxColour()),
3997 * viewAnnColour.getAboveThreshold()); } else
4000 sg.cs = new AnnotationColourGradient(
4001 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4002 viewAnnColour.getAboveThreshold());
4003 if (cs instanceof AnnotationColourGradient)
4005 if (viewAnnColour.hasPerSequence())
4007 ((AnnotationColourGradient) cs)
4008 .setSeqAssociated(viewAnnColour.isPerSequence());
4010 if (viewAnnColour.hasPredefinedColours())
4012 ((AnnotationColourGradient) cs)
4013 .setPredefinedColours(viewAnnColour
4014 .isPredefinedColours());
4030 private void reorderAutoannotation(AlignFrame af, Alignment al,
4031 ArrayList<JvAnnotRow> autoAlan)
4033 // copy over visualization settings for autocalculated annotation in the
4035 if (al.getAlignmentAnnotation() != null)
4038 * Kludge for magic autoannotation names (see JAL-811)
4040 String[] magicNames = new String[]
4041 { "Consensus", "Quality", "Conservation" };
4042 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4043 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4044 for (String nm : magicNames)
4046 visan.put(nm, nullAnnot);
4048 for (JvAnnotRow auan : autoAlan)
4050 visan.put(auan.template.label
4051 + (auan.template.getCalcId() == null ? "" : "\t"
4052 + auan.template.getCalcId()), auan);
4054 int hSize = al.getAlignmentAnnotation().length;
4055 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4056 // work through any autoCalculated annotation already on the view
4057 // removing it if it should be placed in a different location on the
4058 // annotation panel.
4059 List<String> remains = new ArrayList(visan.keySet());
4060 for (int h = 0; h < hSize; h++)
4062 jalview.datamodel.AlignmentAnnotation jalan = al
4063 .getAlignmentAnnotation()[h];
4064 if (jalan.autoCalculated)
4067 JvAnnotRow valan = visan.get(k = jalan.label);
4068 if (jalan.getCalcId() != null)
4070 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4075 // delete the auto calculated row from the alignment
4076 al.deleteAnnotation(jalan, false);
4080 if (valan != nullAnnot)
4082 if (jalan != valan.template)
4084 // newly created autoannotation row instance
4085 // so keep a reference to the visible annotation row
4086 // and copy over all relevant attributes
4087 if (valan.template.graphHeight >= 0)
4090 jalan.graphHeight = valan.template.graphHeight;
4092 jalan.visible = valan.template.visible;
4094 reorder.add(new JvAnnotRow(valan.order, jalan));
4099 // Add any (possibly stale) autocalculated rows that were not appended to
4100 // the view during construction
4101 for (String other : remains)
4103 JvAnnotRow othera = visan.get(other);
4104 if (othera != nullAnnot && othera.template.getCalcId() != null
4105 && othera.template.getCalcId().length() > 0)
4107 reorder.add(othera);
4110 // now put the automatic annotation in its correct place
4111 int s = 0, srt[] = new int[reorder.size()];
4112 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4113 for (JvAnnotRow jvar : reorder)
4116 srt[s++] = jvar.order;
4119 jalview.util.QuickSort.sort(srt, rws);
4120 // and re-insert the annotation at its correct position
4121 for (JvAnnotRow jvar : rws)
4123 al.addAnnotation(jvar.template, jvar.order);
4125 af.alignPanel.adjustAnnotationHeight();
4129 Hashtable skipList = null;
4132 * TODO remove this method
4135 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4136 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4137 * throw new Error("Implementation Error. No skipList defined for this
4138 * Jalview2XML instance."); } return (AlignFrame)
4139 * skipList.get(view.getSequenceSetId()); }
4143 * Check if the Jalview view contained in object should be skipped or not.
4146 * @return true if view's sequenceSetId is a key in skipList
4148 private boolean skipViewport(JalviewModel object)
4150 if (skipList == null)
4155 if (skipList.containsKey(id = object.getJalviewModelSequence()
4156 .getViewport()[0].getSequenceSetId()))
4158 if (Cache.log != null && Cache.log.isDebugEnabled())
4160 Cache.log.debug("Skipping seuqence set id " + id);
4167 public void addToSkipList(AlignFrame af)
4169 if (skipList == null)
4171 skipList = new Hashtable();
4173 skipList.put(af.getViewport().getSequenceSetId(), af);
4176 public void clearSkipList()
4178 if (skipList != null)
4185 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4186 boolean ignoreUnrefed)
4188 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4189 Vector dseqs = null;
4192 // create a list of new dataset sequences
4193 dseqs = new Vector();
4195 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4197 Sequence vamsasSeq = vamsasSet.getSequence(i);
4198 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4200 // create a new dataset
4203 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4204 dseqs.copyInto(dsseqs);
4205 ds = new jalview.datamodel.Alignment(dsseqs);
4206 debug("Created new dataset " + vamsasSet.getDatasetId()
4207 + " for alignment " + System.identityHashCode(al));
4208 addDatasetRef(vamsasSet.getDatasetId(), ds);
4210 // set the dataset for the newly imported alignment.
4211 if (al.getDataset() == null && !ignoreUnrefed)
4220 * sequence definition to create/merge dataset sequence for
4224 * vector to add new dataset sequence to
4226 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4227 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4229 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4231 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4232 SequenceI dsq = null;
4233 if (sq != null && sq.getDatasetSequence() != null)
4235 dsq = sq.getDatasetSequence();
4237 if (sq == null && ignoreUnrefed)
4241 String sqid = vamsasSeq.getDsseqid();
4244 // need to create or add a new dataset sequence reference to this sequence
4247 dsq = seqRefIds.get(sqid);
4252 // make a new dataset sequence
4253 dsq = sq.createDatasetSequence();
4256 // make up a new dataset reference for this sequence
4257 sqid = seqHash(dsq);
4259 dsq.setVamsasId(uniqueSetSuffix + sqid);
4260 seqRefIds.put(sqid, dsq);
4265 dseqs.addElement(dsq);
4270 ds.addSequence(dsq);
4276 { // make this dataset sequence sq's dataset sequence
4277 sq.setDatasetSequence(dsq);
4278 // and update the current dataset alignment
4283 if (!dseqs.contains(dsq))
4290 if (ds.findIndex(dsq) < 0)
4292 ds.addSequence(dsq);
4299 // TODO: refactor this as a merge dataset sequence function
4300 // now check that sq (the dataset sequence) sequence really is the union of
4301 // all references to it
4302 // boolean pre = sq.getStart() < dsq.getStart();
4303 // boolean post = sq.getEnd() > dsq.getEnd();
4307 StringBuffer sb = new StringBuffer();
4308 String newres = jalview.analysis.AlignSeq.extractGaps(
4309 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4310 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4311 && newres.length() > dsq.getLength())
4313 // Update with the longer sequence.
4317 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4318 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4319 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4320 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4322 dsq.setSequence(newres);
4324 // TODO: merges will never happen if we 'know' we have the real dataset
4325 // sequence - this should be detected when id==dssid
4327 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4328 // + (pre ? "prepended" : "") + " "
4329 // + (post ? "appended" : ""));
4334 java.util.Hashtable datasetIds = null;
4336 java.util.IdentityHashMap dataset2Ids = null;
4338 private Alignment getDatasetFor(String datasetId)
4340 if (datasetIds == null)
4342 datasetIds = new Hashtable();
4345 if (datasetIds.containsKey(datasetId))
4347 return (Alignment) datasetIds.get(datasetId);
4352 private void addDatasetRef(String datasetId, Alignment dataset)
4354 if (datasetIds == null)
4356 datasetIds = new Hashtable();
4358 datasetIds.put(datasetId, dataset);
4362 * make a new dataset ID for this jalview dataset alignment
4367 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4369 if (dataset.getDataset() != null)
4371 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4373 String datasetId = makeHashCode(dataset, null);
4374 if (datasetId == null)
4376 // make a new datasetId and record it
4377 if (dataset2Ids == null)
4379 dataset2Ids = new IdentityHashMap();
4383 datasetId = (String) dataset2Ids.get(dataset);
4385 if (datasetId == null)
4387 datasetId = "ds" + dataset2Ids.size() + 1;
4388 dataset2Ids.put(dataset, datasetId);
4394 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4396 for (int d = 0; d < sequence.getDBRefCount(); d++)
4398 DBRef dr = sequence.getDBRef(d);
4399 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4400 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4401 .getVersion(), sequence.getDBRef(d).getAccessionId());
4402 if (dr.getMapping() != null)
4404 entry.setMap(addMapping(dr.getMapping()));
4406 datasetSequence.addDBRef(entry);
4410 private jalview.datamodel.Mapping addMapping(Mapping m)
4412 SequenceI dsto = null;
4413 // Mapping m = dr.getMapping();
4414 int fr[] = new int[m.getMapListFromCount() * 2];
4415 Enumeration f = m.enumerateMapListFrom();
4416 for (int _i = 0; f.hasMoreElements(); _i += 2)
4418 MapListFrom mf = (MapListFrom) f.nextElement();
4419 fr[_i] = mf.getStart();
4420 fr[_i + 1] = mf.getEnd();
4422 int fto[] = new int[m.getMapListToCount() * 2];
4423 f = m.enumerateMapListTo();
4424 for (int _i = 0; f.hasMoreElements(); _i += 2)
4426 MapListTo mf = (MapListTo) f.nextElement();
4427 fto[_i] = mf.getStart();
4428 fto[_i + 1] = mf.getEnd();
4430 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4431 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4432 if (m.getMappingChoice() != null)
4434 MappingChoice mc = m.getMappingChoice();
4435 if (mc.getDseqFor() != null)
4437 String dsfor = "" + mc.getDseqFor();
4438 if (seqRefIds.containsKey(dsfor))
4443 jmap.setTo(seqRefIds.get(dsfor));
4447 frefedSequence.add(new Object[]
4454 * local sequence definition
4456 Sequence ms = mc.getSequence();
4457 SequenceI djs = null;
4458 String sqid = ms.getDsseqid();
4459 if (sqid != null && sqid.length() > 0)
4462 * recover dataset sequence
4464 djs = seqRefIds.get(sqid);
4469 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4470 sqid = ((Object) ms).toString(); // make up a new hascode for
4471 // undefined dataset sequence hash
4472 // (unlikely to happen)
4478 * make a new dataset sequence and add it to refIds hash
4480 djs = new jalview.datamodel.Sequence(ms.getName(),
4482 djs.setStart(jmap.getMap().getToLowest());
4483 djs.setEnd(jmap.getMap().getToHighest());
4484 djs.setVamsasId(uniqueSetSuffix + sqid);
4486 seqRefIds.put(sqid, djs);
4489 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4498 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4499 boolean keepSeqRefs)
4502 jalview.schemabinding.version2.JalviewModel jm = saveState(ap, null,
4508 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4512 uniqueSetSuffix = "";
4513 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4518 if (this.frefedSequence == null)
4520 frefedSequence = new Vector();
4523 viewportsAdded = new Hashtable();
4525 AlignFrame af = loadFromObject(jm, null, false, null);
4526 af.alignPanels.clear();
4527 af.closeMenuItem_actionPerformed(true);
4530 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4531 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4532 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4533 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4534 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4537 return af.alignPanel;
4541 * flag indicating if hashtables should be cleared on finalization TODO this
4542 * flag may not be necessary
4544 private final boolean _cleartables = true;
4546 private Hashtable jvids2vobj;
4551 * @see java.lang.Object#finalize()
4554 protected void finalize() throws Throwable
4556 // really make sure we have no buried refs left.
4561 this.seqRefIds = null;
4562 this.seqsToIds = null;
4566 private void warn(String msg)
4571 private void warn(String msg, Exception e)
4573 if (Cache.log != null)
4577 Cache.log.warn(msg, e);
4581 Cache.log.warn(msg);
4586 System.err.println("Warning: " + msg);
4589 e.printStackTrace();
4594 private void debug(String string)
4596 debug(string, null);
4599 private void debug(String msg, Exception e)
4601 if (Cache.log != null)
4605 Cache.log.debug(msg, e);
4609 Cache.log.debug(msg);
4614 System.err.println("Warning: " + msg);
4617 e.printStackTrace();
4623 * set the object to ID mapping tables used to write/recover objects and XML
4624 * ID strings for the jalview project. If external tables are provided then
4625 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4626 * object goes out of scope. - also populates the datasetIds hashtable with
4627 * alignment objects containing dataset sequences
4630 * Map from ID strings to jalview datamodel
4632 * Map from jalview datamodel to ID strings
4636 public void setObjectMappingTables(Hashtable vobj2jv,
4637 IdentityHashMap jv2vobj)
4639 this.jv2vobj = jv2vobj;
4640 this.vobj2jv = vobj2jv;
4641 Iterator ds = jv2vobj.keySet().iterator();
4643 while (ds.hasNext())
4645 Object jvobj = ds.next();
4646 id = jv2vobj.get(jvobj).toString();
4647 if (jvobj instanceof jalview.datamodel.Alignment)
4649 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4651 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4654 else if (jvobj instanceof jalview.datamodel.Sequence)
4656 // register sequence object so the XML parser can recover it.
4657 if (seqRefIds == null)
4659 seqRefIds = new HashMap<String, SequenceI>();
4661 if (seqsToIds == null)
4663 seqsToIds = new IdentityHashMap<SequenceI, String>();
4665 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4666 seqsToIds.put((SequenceI) jvobj, id);
4668 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4670 if (annotationIds == null)
4672 annotationIds = new Hashtable();
4675 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4676 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4677 if (jvann.annotationId == null)
4679 jvann.annotationId = anid;
4681 if (!jvann.annotationId.equals(anid))
4683 // TODO verify that this is the correct behaviour
4684 this.warn("Overriding Annotation ID for " + anid
4685 + " from different id : " + jvann.annotationId);
4686 jvann.annotationId = anid;
4689 else if (jvobj instanceof String)
4691 if (jvids2vobj == null)
4693 jvids2vobj = new Hashtable();
4694 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4699 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4705 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4706 * objects created from the project archive. If string is null (default for
4707 * construction) then suffix will be set automatically.
4711 public void setUniqueSetSuffix(String string)
4713 uniqueSetSuffix = string;
4718 * uses skipList2 as the skipList for skipping views on sequence sets
4719 * associated with keys in the skipList
4723 public void setSkipList(Hashtable skipList2)
4725 skipList = skipList2;