2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ 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 * Map of reconstructed AlignFrame objects that appear to have come from
155 * SplitFrame objects (have a dna/protein complement view).
157 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
160 * create/return unique hash string for sq
163 * @return new or existing unique string for sq
165 String seqHash(SequenceI sq)
167 if (seqsToIds == null)
171 if (seqsToIds.containsKey(sq))
173 return seqsToIds.get(sq);
177 // create sequential key
178 String key = "sq" + (seqsToIds.size() + 1);
179 key = makeHashCode(sq, key); // check we don't have an external reference
181 seqsToIds.put(sq, key);
190 if (seqRefIds != null)
194 if (seqsToIds != null)
204 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
205 // seqRefIds = new Hashtable();
206 // seqsToIds = new IdentityHashMap();
212 if (seqsToIds == null)
214 seqsToIds = new IdentityHashMap<SequenceI, String>();
216 if (seqRefIds == null)
218 seqRefIds = new HashMap<String, SequenceI>();
226 public Jalview2XML(boolean raiseGUI)
228 this.raiseGUI = raiseGUI;
231 public void resolveFrefedSequences()
233 if (frefedSequence.size() > 0)
235 int r = 0, rSize = frefedSequence.size();
238 Object[] ref = (Object[]) frefedSequence.elementAt(r);
241 String sref = (String) ref[0];
242 if (seqRefIds.containsKey(sref))
244 if (ref[1] instanceof jalview.datamodel.Mapping)
246 SequenceI seq = seqRefIds.get(sref);
247 while (seq.getDatasetSequence() != null)
249 seq = seq.getDatasetSequence();
251 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
255 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
257 SequenceI seq = seqRefIds.get(sref);
258 while (seq.getDatasetSequence() != null)
260 seq = seq.getDatasetSequence();
263 && ref[2] instanceof jalview.datamodel.Mapping)
265 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
266 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
267 seq, mp.getTo(), mp.getMap());
272 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
273 + ref[2].getClass() + " type objects.");
279 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
280 + ref[1].getClass() + " type objects.");
283 frefedSequence.remove(r);
289 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
291 + " with objecttype "
292 + ref[1].getClass());
299 frefedSequence.remove(r);
307 * This maintains a map of viewports, the key being the seqSetId. Important to
308 * set historyItem and redoList for multiple views
310 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
312 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
314 String uniqueSetSuffix = "";
317 * List of pdbfiles added to Jar
319 List<String> pdbfiles = null;
321 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
322 public void saveState(File statefile)
324 FileOutputStream fos = null;
327 fos = new FileOutputStream(statefile);
328 JarOutputStream jout = new JarOutputStream(fos);
331 } catch (Exception e)
333 // TODO: inform user of the problem - they need to know if their data was
335 if (errorMessage == null)
337 errorMessage = "Couldn't write Jalview Archive to output file '"
338 + statefile + "' - See console error log for details";
342 errorMessage += "(output file was '" + statefile + "')";
352 } catch (IOException e)
362 * Writes a jalview project archive to the given Jar output stream.
366 public void saveState(JarOutputStream jout)
368 AlignFrame[] frames = Desktop.getAlignFrames(); // Desktop.desktop.getAllFrames();
375 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
380 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
381 // //////////////////////////////////////////////////
383 Vector shortNames = new Vector();
386 for (int i = frames.length - 1; i > -1; i--)
388 AlignFrame af = frames[i];
392 .containsKey(af.getViewport().getSequenceSetId()))
397 String shortName = af.getTitle();
399 if (shortName.indexOf(File.separatorChar) > -1)
401 shortName = shortName.substring(shortName
402 .lastIndexOf(File.separatorChar) + 1);
407 while (shortNames.contains(shortName))
409 if (shortName.endsWith("_" + (count - 1)))
411 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
414 shortName = shortName.concat("_" + count);
418 shortNames.addElement(shortName);
420 if (!shortName.endsWith(".xml"))
422 shortName = shortName + ".xml";
425 int ap, apSize = af.alignPanels.size();
427 for (ap = 0; ap < apSize; ap++)
429 AlignmentPanel apanel = af.alignPanels.get(ap);
430 String fileName = apSize == 1 ? shortName : ap + shortName;
431 if (!fileName.endsWith(".xml"))
433 fileName = fileName + ".xml";
436 saveState(apanel, fileName, jout);
438 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
440 if (!dsses.containsKey(dssid))
442 dsses.put(dssid, af);
447 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
453 } catch (Exception foo)
458 } catch (Exception ex)
460 // TODO: inform user of the problem - they need to know if their data was
462 if (errorMessage == null)
464 errorMessage = "Couldn't write Jalview Archive - see error output for details";
466 ex.printStackTrace();
470 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
471 public boolean saveAlignment(AlignFrame af, String jarFile,
477 int apSize = af.alignPanels.size();
478 FileOutputStream fos = new FileOutputStream(jarFile);
479 JarOutputStream jout = new JarOutputStream(fos);
480 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
481 for (AlignmentPanel apanel : af.alignPanels)
483 String jfileName = apSize == 1 ? fileName : fileName + ap;
485 if (!jfileName.endsWith(".xml"))
487 jfileName = jfileName + ".xml";
489 saveState(apanel, jfileName, jout);
490 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
492 if (!dsses.containsKey(dssid))
494 dsses.put(dssid, af);
497 writeDatasetFor(dsses, fileName, jout);
501 } catch (Exception foo)
507 } catch (Exception ex)
509 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
510 ex.printStackTrace();
515 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
516 String fileName, JarOutputStream jout)
519 for (String dssids : dsses.keySet())
521 AlignFrame _af = dsses.get(dssids);
522 String jfileName = fileName + " Dataset for " + _af.getTitle();
523 if (!jfileName.endsWith(".xml"))
525 jfileName = jfileName + ".xml";
527 saveState(_af.alignPanel, jfileName, true, jout);
532 * create a JalviewModel from an alignment view and marshall it to a
536 * panel to create jalview model for
538 * name of alignment panel written to output stream
544 public JalviewModel saveState(AlignmentPanel ap, String fileName,
545 JarOutputStream jout)
547 return saveState(ap, fileName, false, jout);
551 * create a JalviewModel from an alignment view and marshall it to a
555 * panel to create jalview model for
557 * name of alignment panel written to output stream
559 * when true, only write the dataset for the alignment, not the data
560 * associated with the view.
566 public JalviewModel saveState(AlignmentPanel ap, String fileName,
567 boolean storeDS, JarOutputStream jout)
570 List<String> viewIds = new ArrayList<String>();
571 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
573 AlignViewport av = ap.av;
575 JalviewModel object = new JalviewModel();
576 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
578 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
579 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
580 "Development Build"));
582 jalview.datamodel.AlignmentI jal = av.getAlignment();
584 if (av.hasHiddenRows())
586 jal = jal.getHiddenSequences().getFullAlignment();
589 SequenceSet vamsasSet = new SequenceSet();
591 JalviewModelSequence jms = new JalviewModelSequence();
593 vamsasSet.setGapChar(jal.getGapCharacter() + "");
595 if (jal.getDataset() != null)
597 // dataset id is the dataset's hashcode
598 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
601 // switch jal and the dataset
602 jal = jal.getDataset();
605 if (jal.getProperties() != null)
607 Enumeration en = jal.getProperties().keys();
608 while (en.hasMoreElements())
610 String key = en.nextElement().toString();
611 SequenceSetProperties ssp = new SequenceSetProperties();
613 ssp.setValue(jal.getProperties().get(key).toString());
614 vamsasSet.addSequenceSetProperties(ssp);
619 Set<String> calcIdSet = new HashSet<String>();
623 jalview.datamodel.SequenceI jds, jdatasq;
624 for (int i = 0; i < jal.getHeight(); i++)
626 jds = jal.getSequenceAt(i);
627 jdatasq = jds.getDatasetSequence() == null ? jds : jds
628 .getDatasetSequence();
631 if (seqRefIds.get(id) != null)
633 // This happens for two reasons: 1. multiple views are being serialised.
634 // 2. the hashCode has collided with another sequence's code. This DOES
635 // HAPPEN! (PF00072.15.stk does this)
636 // JBPNote: Uncomment to debug writing out of files that do not read
637 // back in due to ArrayOutOfBoundExceptions.
638 // System.err.println("vamsasSeq backref: "+id+"");
639 // System.err.println(jds.getName()+"
640 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
641 // System.err.println("Hashcode: "+seqHash(jds));
642 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
643 // System.err.println(rsq.getName()+"
644 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
645 // System.err.println("Hashcode: "+seqHash(rsq));
649 vamsasSeq = createVamsasSequence(id, jds);
650 vamsasSet.addSequence(vamsasSeq);
651 seqRefIds.put(id, jds);
655 jseq.setStart(jds.getStart());
656 jseq.setEnd(jds.getEnd());
657 jseq.setColour(av.getSequenceColour(jds).getRGB());
659 jseq.setId(id); // jseq id should be a string not a number
662 // Store any sequences this sequence represents
663 if (av.hasHiddenRows())
665 jseq.setHidden(av.getAlignment().getHiddenSequences()
668 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
670 jalview.datamodel.SequenceI[] reps = av
671 .getRepresentedSequences(jal.getSequenceAt(i))
672 .getSequencesInOrder(jal);
674 for (int h = 0; h < reps.length; h++)
676 if (reps[h] != jal.getSequenceAt(i))
678 jseq.addHiddenSequences(jal.findIndex(reps[h]));
685 if (jds.getSequenceFeatures() != null)
687 jalview.datamodel.SequenceFeature[] sf = jds
688 .getSequenceFeatures();
690 while (index < sf.length)
692 Features features = new Features();
694 features.setBegin(sf[index].getBegin());
695 features.setEnd(sf[index].getEnd());
696 features.setDescription(sf[index].getDescription());
697 features.setType(sf[index].getType());
698 features.setFeatureGroup(sf[index].getFeatureGroup());
699 features.setScore(sf[index].getScore());
700 if (sf[index].links != null)
702 for (int l = 0; l < sf[index].links.size(); l++)
704 OtherData keyValue = new OtherData();
705 keyValue.setKey("LINK_" + l);
706 keyValue.setValue(sf[index].links.elementAt(l).toString());
707 features.addOtherData(keyValue);
710 if (sf[index].otherDetails != null)
713 Enumeration keys = sf[index].otherDetails.keys();
714 while (keys.hasMoreElements())
716 key = keys.nextElement().toString();
717 OtherData keyValue = new OtherData();
718 keyValue.setKey(key);
719 keyValue.setValue(sf[index].otherDetails.get(key).toString());
720 features.addOtherData(keyValue);
724 jseq.addFeatures(features);
729 if (jdatasq.getPDBId() != null)
731 Enumeration en = jdatasq.getPDBId().elements();
732 while (en.hasMoreElements())
734 Pdbids pdb = new Pdbids();
735 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
738 pdb.setId(entry.getId());
739 pdb.setType(entry.getType());
742 * Store any structure views associated with this sequence. This
743 * section copes with duplicate entries in the project, so a dataset
744 * only view *should* be coped with sensibly.
746 // This must have been loaded, is it still visible?
747 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
748 String matchedFile = null;
749 for (int f = frames.length - 1; f > -1; f--)
751 if (frames[f] instanceof StructureViewerBase)
753 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
754 matchedFile = saveStructureState(ap, jds, pdb, entry,
755 viewIds, matchedFile, viewFrame);
759 if (matchedFile != null || entry.getFile() != null)
761 if (entry.getFile() != null)
764 matchedFile = entry.getFile();
766 pdb.setFile(matchedFile); // entry.getFile());
767 if (pdbfiles == null)
769 pdbfiles = new ArrayList<String>();
772 if (!pdbfiles.contains(entry.getId()))
774 pdbfiles.add(entry.getId());
775 DataInputStream dis = null;
778 File file = new File(matchedFile);
779 if (file.exists() && jout != null)
781 byte[] data = new byte[(int) file.length()];
782 jout.putNextEntry(new JarEntry(entry.getId()));
783 dis = new DataInputStream(new FileInputStream(file));
786 DataOutputStream dout = new DataOutputStream(jout);
787 dout.write(data, 0, data.length);
791 } catch (Exception ex)
793 ex.printStackTrace();
801 } catch (IOException e)
811 if (entry.getProperty() != null)
813 PdbentryItem item = new PdbentryItem();
814 Hashtable properties = entry.getProperty();
815 Enumeration en2 = properties.keys();
816 while (en2.hasMoreElements())
818 Property prop = new Property();
819 String key = en2.nextElement().toString();
821 prop.setValue(properties.get(key).toString());
822 item.addProperty(prop);
824 pdb.addPdbentryItem(item);
834 if (!storeDS && av.hasHiddenRows())
836 jal = av.getAlignment();
839 if (jal.getCodonFrames() != null)
841 Set<AlignedCodonFrame> jac = jal.getCodonFrames();
842 for (AlignedCodonFrame acf : jac)
844 AlcodonFrame alc = new AlcodonFrame();
845 vamsasSet.addAlcodonFrame(alc);
846 if (acf.getProtMappings() != null
847 && acf.getProtMappings().length > 0)
849 SequenceI[] dnas = acf.getdnaSeqs();
850 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
851 for (int m = 0; m < pmaps.length; m++)
853 AlcodMap alcmap = new AlcodMap();
854 alcmap.setDnasq(seqHash(dnas[m]));
855 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
857 alc.addAlcodMap(alcmap);
862 // AlcodonFrame alc = new AlcodonFrame();
863 // vamsasSet.addAlcodonFrame(alc);
864 // for (int p = 0; p < acf.aaWidth; p++)
866 // Alcodon cmap = new Alcodon();
867 // if (acf.codons[p] != null)
869 // // Null codons indicate a gapped column in the translated peptide
871 // cmap.setPos1(acf.codons[p][0]);
872 // cmap.setPos2(acf.codons[p][1]);
873 // cmap.setPos3(acf.codons[p][2]);
875 // alc.addAlcodon(cmap);
877 // if (acf.getProtMappings() != null
878 // && acf.getProtMappings().length > 0)
880 // SequenceI[] dnas = acf.getdnaSeqs();
881 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
882 // for (int m = 0; m < pmaps.length; m++)
884 // AlcodMap alcmap = new AlcodMap();
885 // alcmap.setDnasq(seqHash(dnas[m]));
886 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
888 // alc.addAlcodMap(alcmap);
895 // /////////////////////////////////
896 if (!storeDS && av.currentTree != null)
898 // FIND ANY ASSOCIATED TREES
899 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
900 if (Desktop.desktop != null)
902 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
904 for (int t = 0; t < frames.length; t++)
906 if (frames[t] instanceof TreePanel)
908 TreePanel tp = (TreePanel) frames[t];
910 if (tp.treeCanvas.av.getAlignment() == jal)
912 Tree tree = new Tree();
913 tree.setTitle(tp.getTitle());
914 tree.setCurrentTree((av.currentTree == tp.getTree()));
915 tree.setNewick(tp.getTree().toString());
916 tree.setThreshold(tp.treeCanvas.threshold);
918 tree.setFitToWindow(tp.fitToWindow.getState());
919 tree.setFontName(tp.getTreeFont().getName());
920 tree.setFontSize(tp.getTreeFont().getSize());
921 tree.setFontStyle(tp.getTreeFont().getStyle());
922 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
924 tree.setShowBootstrap(tp.bootstrapMenu.getState());
925 tree.setShowDistances(tp.distanceMenu.getState());
927 tree.setHeight(tp.getHeight());
928 tree.setWidth(tp.getWidth());
929 tree.setXpos(tp.getX());
930 tree.setYpos(tp.getY());
931 tree.setId(makeHashCode(tp, null));
940 * store forward refs from an annotationRow to any groups
942 IdentityHashMap groupRefs = new IdentityHashMap();
945 for (SequenceI sq : jal.getSequences())
947 // Store annotation on dataset sequences only
948 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
949 if (aa != null && aa.length > 0)
951 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
958 if (jal.getAlignmentAnnotation() != null)
960 // Store the annotation shown on the alignment.
961 jalview.datamodel.AlignmentAnnotation[] aa = jal
962 .getAlignmentAnnotation();
963 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
968 if (jal.getGroups() != null)
970 JGroup[] groups = new JGroup[jal.getGroups().size()];
972 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
974 groups[++i] = new JGroup();
976 groups[i].setStart(sg.getStartRes());
977 groups[i].setEnd(sg.getEndRes());
978 groups[i].setName(sg.getName());
979 if (groupRefs.containsKey(sg))
981 // group has references so set it's ID field
982 groups[i].setId(groupRefs.get(sg).toString());
986 if (sg.cs.conservationApplied())
988 groups[i].setConsThreshold(sg.cs.getConservationInc());
990 if (sg.cs instanceof jalview.schemes.UserColourScheme)
992 groups[i].setColour(setUserColourScheme(sg.cs, userColours,
998 .setColour(ColourSchemeProperty.getColourName(sg.cs));
1001 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1003 groups[i].setColour("AnnotationColourGradient");
1004 groups[i].setAnnotationColours(constructAnnotationColours(
1005 (jalview.schemes.AnnotationColourGradient) sg.cs,
1008 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1011 .setColour(setUserColourScheme(sg.cs, userColours, jms));
1015 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1018 groups[i].setPidThreshold(sg.cs.getThreshold());
1021 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1022 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1023 groups[i].setDisplayText(sg.getDisplayText());
1024 groups[i].setColourText(sg.getColourText());
1025 groups[i].setTextCol1(sg.textColour.getRGB());
1026 groups[i].setTextCol2(sg.textColour2.getRGB());
1027 groups[i].setTextColThreshold(sg.thresholdTextColour);
1028 groups[i].setShowUnconserved(sg.getShowNonconserved());
1029 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1030 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1031 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1032 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1033 for (int s = 0; s < sg.getSize(); s++)
1035 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1037 groups[i].addSeq(seqHash(seq));
1041 jms.setJGroup(groups);
1045 // /////////SAVE VIEWPORT
1046 Viewport view = new Viewport();
1047 view.setTitle(ap.alignFrame.getTitle());
1048 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1049 av.getSequenceSetId()));
1050 view.setId(av.getViewId());
1051 if (av.getCodingComplement() != null)
1053 view.setComplementId(av.getCodingComplement().getViewId());
1055 view.setViewName(av.viewName);
1056 view.setGatheredViews(av.isGatherViewsHere());
1058 Rectangle position = ap.av.getExplodedGeometry();
1059 if (position == null)
1061 position = ap.alignFrame.getBounds();
1063 view.setXpos(position.x);
1064 view.setYpos(position.y);
1065 view.setWidth(position.width);
1066 view.setHeight(position.height);
1068 view.setStartRes(av.startRes);
1069 view.setStartSeq(av.startSeq);
1071 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1073 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1076 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1078 AnnotationColours ac = constructAnnotationColours(
1079 (jalview.schemes.AnnotationColourGradient) av
1080 .getGlobalColourScheme(),
1083 view.setAnnotationColours(ac);
1084 view.setBgColour("AnnotationColourGradient");
1088 view.setBgColour(ColourSchemeProperty.getColourName(av
1089 .getGlobalColourScheme()));
1092 ColourSchemeI cs = av.getGlobalColourScheme();
1096 if (cs.conservationApplied())
1098 view.setConsThreshold(cs.getConservationInc());
1099 if (cs instanceof jalview.schemes.UserColourScheme)
1101 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1105 if (cs instanceof ResidueColourScheme)
1107 view.setPidThreshold(cs.getThreshold());
1111 view.setConservationSelected(av.getConservationSelected());
1112 view.setPidSelected(av.getAbovePIDThreshold());
1113 view.setFontName(av.font.getName());
1114 view.setFontSize(av.font.getSize());
1115 view.setFontStyle(av.font.getStyle());
1116 view.setRenderGaps(av.isRenderGaps());
1117 view.setShowAnnotation(av.isShowAnnotation());
1118 view.setShowBoxes(av.getShowBoxes());
1119 view.setShowColourText(av.getColourText());
1120 view.setShowFullId(av.getShowJVSuffix());
1121 view.setRightAlignIds(av.isRightAlignIds());
1122 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1123 view.setShowText(av.getShowText());
1124 view.setShowUnconserved(av.getShowUnconserved());
1125 view.setWrapAlignment(av.getWrapAlignment());
1126 view.setTextCol1(av.getTextColour().getRGB());
1127 view.setTextCol2(av.getTextColour2().getRGB());
1128 view.setTextColThreshold(av.getThresholdTextColour());
1129 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1130 view.setShowSequenceLogo(av.isShowSequenceLogo());
1131 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1132 view.setShowGroupConsensus(av.isShowGroupConsensus());
1133 view.setShowGroupConservation(av.isShowGroupConservation());
1134 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1135 view.setShowDbRefTooltip(av.isShowDBRefs());
1136 view.setFollowHighlight(av.isFollowHighlight());
1137 view.setFollowSelection(av.followSelection);
1138 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1139 if (av.getFeaturesDisplayed() != null)
1141 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1143 String[] renderOrder = ap.getSeqPanel().seqCanvas
1144 .getFeatureRenderer().getRenderOrder()
1145 .toArray(new String[0]);
1147 Vector settingsAdded = new Vector();
1148 Object gstyle = null;
1149 GraduatedColor gcol = null;
1150 if (renderOrder != null)
1152 for (int ro = 0; ro < renderOrder.length; ro++)
1154 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1155 .getFeatureStyle(renderOrder[ro]);
1156 Setting setting = new Setting();
1157 setting.setType(renderOrder[ro]);
1158 if (gstyle instanceof GraduatedColor)
1160 gcol = (GraduatedColor) gstyle;
1161 setting.setColour(gcol.getMaxColor().getRGB());
1162 setting.setMincolour(gcol.getMinColor().getRGB());
1163 setting.setMin(gcol.getMin());
1164 setting.setMax(gcol.getMax());
1165 setting.setColourByLabel(gcol.isColourByLabel());
1166 setting.setAutoScale(gcol.isAutoScale());
1167 setting.setThreshold(gcol.getThresh());
1168 setting.setThreshstate(gcol.getThreshType());
1172 setting.setColour(ap.getSeqPanel().seqCanvas
1173 .getFeatureRenderer()
1174 .getColour(renderOrder[ro]).getRGB());
1177 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1179 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1180 .getOrder(renderOrder[ro]);
1183 setting.setOrder(rorder);
1185 fs.addSetting(setting);
1186 settingsAdded.addElement(renderOrder[ro]);
1190 // Make sure we save none displayed feature settings
1191 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1192 .getFeatureColours().keySet().iterator();
1193 while (en.hasNext())
1195 String key = en.next().toString();
1196 if (settingsAdded.contains(key))
1201 Setting setting = new Setting();
1202 setting.setType(key);
1203 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1204 .getColour(key).getRGB());
1206 setting.setDisplay(false);
1207 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1211 setting.setOrder(rorder);
1213 fs.addSetting(setting);
1214 settingsAdded.addElement(key);
1216 // is groups actually supposed to be a map here ?
1217 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1218 .getFeatureGroups().iterator();
1219 Vector groupsAdded = new Vector();
1220 while (en.hasNext())
1222 String grp = en.next().toString();
1223 if (groupsAdded.contains(grp))
1227 Group g = new Group();
1229 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1230 .getFeatureRenderer().checkGroupVisibility(grp, false))
1233 groupsAdded.addElement(grp);
1235 jms.setFeatureSettings(fs);
1239 if (av.hasHiddenColumns())
1241 if (av.getColumnSelection() == null
1242 || av.getColumnSelection().getHiddenColumns() == null)
1244 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1248 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1251 int[] region = av.getColumnSelection().getHiddenColumns()
1253 HiddenColumns hc = new HiddenColumns();
1254 hc.setStart(region[0]);
1255 hc.setEnd(region[1]);
1256 view.addHiddenColumns(hc);
1260 if (calcIdSet.size() > 0)
1262 for (String calcId : calcIdSet)
1264 if (calcId.trim().length() > 0)
1266 CalcIdParam cidp = createCalcIdParam(calcId, av);
1267 // Some calcIds have no parameters.
1270 view.addCalcIdParam(cidp);
1276 jms.addViewport(view);
1278 object.setJalviewModelSequence(jms);
1279 object.getVamsasModel().addSequenceSet(vamsasSet);
1281 if (jout != null && fileName != null)
1283 // We may not want to write the object to disk,
1284 // eg we can copy the alignViewport to a new view object
1285 // using save and then load
1288 JarEntry entry = new JarEntry(fileName);
1289 jout.putNextEntry(entry);
1290 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1292 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1294 marshaller.marshal(object);
1297 } catch (Exception ex)
1299 // TODO: raise error in GUI if marshalling failed.
1300 ex.printStackTrace();
1307 * Save the state of a structure viewer
1312 * the archive XML element under which to save the state
1315 * @param matchedFile
1319 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1320 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1321 String matchedFile, StructureViewerBase viewFrame)
1323 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1324 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1326 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1327 final String pdbId = pdbentry.getId();
1328 if (!pdbId.equals(entry.getId())
1329 && !(entry.getId().length() > 4 && entry.getId()
1330 .toLowerCase().startsWith(pdbId.toLowerCase())))
1334 if (matchedFile == null)
1336 matchedFile = pdbentry.getFile();
1338 else if (!matchedFile.equals(pdbentry.getFile()))
1341 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1342 + pdbentry.getFile());
1346 // can get at it if the ID
1347 // match is ambiguous (e.g.
1349 String statestring = viewFrame.getStateInfo();
1351 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1353 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1354 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1356 StructureState state = new StructureState();
1357 state.setVisible(true);
1358 state.setXpos(viewFrame.getX());
1359 state.setYpos(viewFrame.getY());
1360 state.setWidth(viewFrame.getWidth());
1361 state.setHeight(viewFrame.getHeight());
1362 final String viewId = viewFrame.getViewId();
1363 state.setViewId(viewId);
1364 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1365 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1366 state.setColourByJmol(viewFrame.isColouredByViewer());
1368 * Only store each structure viewer's state once in each XML document.
1370 if (!viewIds.contains(viewId))
1372 viewIds.add(viewId);
1373 state.setContent(statestring.replaceAll("\n", ""));
1377 state.setContent("# duplicate state");
1379 pdb.addStructureState(state);
1386 private AnnotationColours constructAnnotationColours(
1387 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1388 JalviewModelSequence jms)
1390 AnnotationColours ac = new AnnotationColours();
1391 ac.setAboveThreshold(acg.getAboveThreshold());
1392 ac.setThreshold(acg.getAnnotationThreshold());
1393 ac.setAnnotation(acg.getAnnotation());
1394 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1396 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1401 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1405 ac.setMaxColour(acg.getMaxColour().getRGB());
1406 ac.setMinColour(acg.getMinColour().getRGB());
1407 ac.setPerSequence(acg.isSeqAssociated());
1408 ac.setPredefinedColours(acg.isPredefinedColours());
1412 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1413 IdentityHashMap groupRefs, AlignmentViewport av,
1414 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1417 for (int i = 0; i < aa.length; i++)
1419 Annotation an = new Annotation();
1421 if (aa[i].annotationId != null)
1423 annotationIds.put(aa[i].annotationId, aa[i]);
1426 an.setId(aa[i].annotationId);
1428 an.setVisible(aa[i].visible);
1430 an.setDescription(aa[i].description);
1432 if (aa[i].sequenceRef != null)
1434 // TODO later annotation sequenceRef should be the XML ID of the
1435 // sequence rather than its display name
1436 an.setSequenceRef(aa[i].sequenceRef.getName());
1438 if (aa[i].groupRef != null)
1440 Object groupIdr = groupRefs.get(aa[i].groupRef);
1441 if (groupIdr == null)
1443 // make a locally unique String
1444 groupRefs.put(aa[i].groupRef,
1445 groupIdr = ("" + System.currentTimeMillis()
1446 + aa[i].groupRef.getName() + groupRefs.size()));
1448 an.setGroupRef(groupIdr.toString());
1451 // store all visualization attributes for annotation
1452 an.setGraphHeight(aa[i].graphHeight);
1453 an.setCentreColLabels(aa[i].centreColLabels);
1454 an.setScaleColLabels(aa[i].scaleColLabel);
1455 an.setShowAllColLabels(aa[i].showAllColLabels);
1456 an.setBelowAlignment(aa[i].belowAlignment);
1458 if (aa[i].graph > 0)
1461 an.setGraphType(aa[i].graph);
1462 an.setGraphGroup(aa[i].graphGroup);
1463 if (aa[i].getThreshold() != null)
1465 ThresholdLine line = new ThresholdLine();
1466 line.setLabel(aa[i].getThreshold().label);
1467 line.setValue(aa[i].getThreshold().value);
1468 line.setColour(aa[i].getThreshold().colour.getRGB());
1469 an.setThresholdLine(line);
1477 an.setLabel(aa[i].label);
1479 if (aa[i] == av.getAlignmentQualityAnnot()
1480 || aa[i] == av.getAlignmentConservationAnnotation()
1481 || aa[i] == av.getAlignmentConsensusAnnotation()
1482 || aa[i].autoCalculated)
1484 // new way of indicating autocalculated annotation -
1485 an.setAutoCalculated(aa[i].autoCalculated);
1487 if (aa[i].hasScore())
1489 an.setScore(aa[i].getScore());
1492 if (aa[i].getCalcId() != null)
1494 calcIdSet.add(aa[i].getCalcId());
1495 an.setCalcId(aa[i].getCalcId());
1497 if (aa[i].hasProperties())
1499 for (String pr : aa[i].getProperties())
1501 Property prop = new Property();
1503 prop.setValue(aa[i].getProperty(pr));
1504 an.addProperty(prop);
1508 AnnotationElement ae;
1509 if (aa[i].annotations != null)
1511 an.setScoreOnly(false);
1512 for (int a = 0; a < aa[i].annotations.length; a++)
1514 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1519 ae = new AnnotationElement();
1520 if (aa[i].annotations[a].description != null)
1522 ae.setDescription(aa[i].annotations[a].description);
1524 if (aa[i].annotations[a].displayCharacter != null)
1526 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1529 if (!Float.isNaN(aa[i].annotations[a].value))
1531 ae.setValue(aa[i].annotations[a].value);
1535 if (aa[i].annotations[a].secondaryStructure > ' ')
1537 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1541 if (aa[i].annotations[a].colour != null
1542 && aa[i].annotations[a].colour != java.awt.Color.black)
1544 ae.setColour(aa[i].annotations[a].colour.getRGB());
1547 an.addAnnotationElement(ae);
1548 if (aa[i].autoCalculated)
1550 // only write one non-null entry into the annotation row -
1551 // sufficient to get the visualization attributes necessary to
1559 an.setScoreOnly(true);
1561 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1563 // skip autocalculated annotation - these are only provided for
1565 vamsasSet.addAnnotation(an);
1571 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1573 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1574 if (settings != null)
1576 CalcIdParam vCalcIdParam = new CalcIdParam();
1577 vCalcIdParam.setCalcId(calcId);
1578 vCalcIdParam.addServiceURL(settings.getServiceURI());
1579 // generic URI allowing a third party to resolve another instance of the
1580 // service used for this calculation
1581 for (String urls : settings.getServiceURLs())
1583 vCalcIdParam.addServiceURL(urls);
1585 vCalcIdParam.setVersion("1.0");
1586 if (settings.getPreset() != null)
1588 WsParamSetI setting = settings.getPreset();
1589 vCalcIdParam.setName(setting.getName());
1590 vCalcIdParam.setDescription(setting.getDescription());
1594 vCalcIdParam.setName("");
1595 vCalcIdParam.setDescription("Last used parameters");
1597 // need to be able to recover 1) settings 2) user-defined presets or
1598 // recreate settings from preset 3) predefined settings provided by
1599 // service - or settings that can be transferred (or discarded)
1600 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1602 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1603 // todo - decide if updateImmediately is needed for any projects.
1605 return vCalcIdParam;
1610 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1613 if (calcIdParam.getVersion().equals("1.0"))
1615 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1616 .getPreferredServiceFor(calcIdParam.getServiceURL());
1617 if (service != null)
1619 WsParamSetI parmSet = null;
1622 parmSet = service.getParamStore().parseServiceParameterFile(
1623 calcIdParam.getName(), calcIdParam.getDescription(),
1624 calcIdParam.getServiceURL(),
1625 calcIdParam.getParameters().replace("|\\n|", "\n"));
1626 } catch (IOException x)
1628 warn("Couldn't parse parameter data for "
1629 + calcIdParam.getCalcId(), x);
1632 List<ArgumentI> argList = null;
1633 if (calcIdParam.getName().length() > 0)
1635 parmSet = service.getParamStore()
1636 .getPreset(calcIdParam.getName());
1637 if (parmSet != null)
1639 // TODO : check we have a good match with settings in AACon -
1640 // otherwise we'll need to create a new preset
1645 argList = parmSet.getArguments();
1648 AAConSettings settings = new AAConSettings(
1649 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1650 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1651 calcIdParam.isNeedsUpdate());
1656 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1660 throw new Error(MessageManager.formatMessage(
1661 "error.unsupported_version_calcIdparam", new Object[]
1662 { calcIdParam.toString() }));
1666 * External mapping between jalview objects and objects yielding a valid and
1667 * unique object ID string. This is null for normal Jalview project IO, but
1668 * non-null when a jalview project is being read or written as part of a
1671 IdentityHashMap jv2vobj = null;
1674 * Construct a unique ID for jvobj using either existing bindings or if none
1675 * exist, the result of the hashcode call for the object.
1678 * jalview data object
1679 * @return unique ID for referring to jvobj
1681 private String makeHashCode(Object jvobj, String altCode)
1683 if (jv2vobj != null)
1685 Object id = jv2vobj.get(jvobj);
1688 return id.toString();
1690 // check string ID mappings
1691 if (jvids2vobj != null && jvobj instanceof String)
1693 id = jvids2vobj.get(jvobj);
1697 return id.toString();
1699 // give up and warn that something has gone wrong
1700 warn("Cannot find ID for object in external mapping : " + jvobj);
1706 * return local jalview object mapped to ID, if it exists
1710 * @return null or object bound to idcode
1712 private Object retrieveExistingObj(String idcode)
1714 if (idcode != null && vobj2jv != null)
1716 return vobj2jv.get(idcode);
1722 * binding from ID strings from external mapping table to jalview data model
1725 private Hashtable vobj2jv;
1727 private Sequence createVamsasSequence(String id, SequenceI jds)
1729 return createVamsasSequence(true, id, jds, null);
1732 private Sequence createVamsasSequence(boolean recurse, String id,
1733 SequenceI jds, SequenceI parentseq)
1735 Sequence vamsasSeq = new Sequence();
1736 vamsasSeq.setId(id);
1737 vamsasSeq.setName(jds.getName());
1738 vamsasSeq.setSequence(jds.getSequenceAsString());
1739 vamsasSeq.setDescription(jds.getDescription());
1740 jalview.datamodel.DBRefEntry[] dbrefs = null;
1741 if (jds.getDatasetSequence() != null)
1743 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1744 if (jds.getDatasetSequence().getDBRef() != null)
1746 dbrefs = jds.getDatasetSequence().getDBRef();
1751 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1752 // dataset sequences only
1753 dbrefs = jds.getDBRef();
1757 for (int d = 0; d < dbrefs.length; d++)
1759 DBRef dbref = new DBRef();
1760 dbref.setSource(dbrefs[d].getSource());
1761 dbref.setVersion(dbrefs[d].getVersion());
1762 dbref.setAccessionId(dbrefs[d].getAccessionId());
1763 if (dbrefs[d].hasMap())
1765 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1767 dbref.setMapping(mp);
1769 vamsasSeq.addDBRef(dbref);
1775 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1776 SequenceI parentseq, SequenceI jds, boolean recurse)
1779 if (jmp.getMap() != null)
1783 jalview.util.MapList mlst = jmp.getMap();
1784 List<int[]> r = mlst.getFromRanges();
1785 for (int[] range : r)
1787 MapListFrom mfrom = new MapListFrom();
1788 mfrom.setStart(range[0]);
1789 mfrom.setEnd(range[1]);
1790 mp.addMapListFrom(mfrom);
1792 r = mlst.getToRanges();
1793 for (int[] range : r)
1795 MapListTo mto = new MapListTo();
1796 mto.setStart(range[0]);
1797 mto.setEnd(range[1]);
1798 mp.addMapListTo(mto);
1800 mp.setMapFromUnit(mlst.getFromRatio());
1801 mp.setMapToUnit(mlst.getToRatio());
1802 if (jmp.getTo() != null)
1804 MappingChoice mpc = new MappingChoice();
1806 && (parentseq != jmp.getTo() || parentseq
1807 .getDatasetSequence() != jmp.getTo()))
1809 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1815 SequenceI ps = null;
1816 if (parentseq != jmp.getTo()
1817 && parentseq.getDatasetSequence() != jmp.getTo())
1819 // chaining dbref rather than a handshaking one
1820 jmpid = seqHash(ps = jmp.getTo());
1824 jmpid = seqHash(ps = parentseq);
1826 mpc.setDseqFor(jmpid);
1827 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1829 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1830 seqRefIds.put(mpc.getDseqFor(), ps);
1834 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1837 mp.setMappingChoice(mpc);
1843 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
1844 List<UserColourScheme> userColours, JalviewModelSequence jms)
1847 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1848 boolean newucs = false;
1849 if (!userColours.contains(ucs))
1851 userColours.add(ucs);
1854 id = "ucs" + userColours.indexOf(ucs);
1857 // actually create the scheme's entry in the XML model
1858 java.awt.Color[] colours = ucs.getColours();
1859 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1860 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1862 for (int i = 0; i < colours.length; i++)
1864 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1865 col.setName(ResidueProperties.aa[i]);
1866 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1867 jbucs.addColour(col);
1869 if (ucs.getLowerCaseColours() != null)
1871 colours = ucs.getLowerCaseColours();
1872 for (int i = 0; i < colours.length; i++)
1874 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1875 col.setName(ResidueProperties.aa[i].toLowerCase());
1876 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1877 jbucs.addColour(col);
1882 uc.setUserColourScheme(jbucs);
1883 jms.addUserColours(uc);
1889 jalview.schemes.UserColourScheme getUserColourScheme(
1890 JalviewModelSequence jms, String id)
1892 UserColours[] uc = jms.getUserColours();
1893 UserColours colours = null;
1895 for (int i = 0; i < uc.length; i++)
1897 if (uc[i].getId().equals(id))
1905 java.awt.Color[] newColours = new java.awt.Color[24];
1907 for (int i = 0; i < 24; i++)
1909 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1910 .getUserColourScheme().getColour(i).getRGB(), 16));
1913 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1916 if (colours.getUserColourScheme().getColourCount() > 24)
1918 newColours = new java.awt.Color[23];
1919 for (int i = 0; i < 23; i++)
1921 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1922 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1924 ucs.setLowerCaseColours(newColours);
1931 * contains last error message (if any) encountered by XML loader.
1933 String errorMessage = null;
1936 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1937 * exceptions are raised during project XML parsing
1939 public boolean attemptversion1parse = true;
1942 * Load a jalview project archive from a jar file
1945 * - HTTP URL or filename
1947 public AlignFrame loadJalviewAlign(final String file)
1950 jalview.gui.AlignFrame af = null;
1954 // create list to store references for any new Jmol viewers created
1955 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1956 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1957 // Workaround is to make sure caller implements the JarInputStreamProvider
1959 // so we can re-open the jar input stream for each entry.
1961 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1962 af = loadJalviewAlign(jprovider);
1964 } catch (MalformedURLException e)
1966 errorMessage = "Invalid URL format for '" + file + "'";
1972 SwingUtilities.invokeAndWait(new Runnable()
1976 setLoadingFinishedForNewStructureViewers();
1979 } catch (Exception x)
1987 private jarInputStreamProvider createjarInputStreamProvider(
1988 final String file) throws MalformedURLException
1991 errorMessage = null;
1992 uniqueSetSuffix = null;
1994 viewportsAdded.clear();
1995 frefedSequence = null;
1997 if (file.startsWith("http://"))
1999 url = new URL(file);
2001 final URL _url = url;
2002 return new jarInputStreamProvider()
2006 public JarInputStream getJarInputStream() throws IOException
2010 return new JarInputStream(_url.openStream());
2014 return new JarInputStream(new FileInputStream(file));
2019 public String getFilename()
2027 * Recover jalview session from a jalview project archive. Caller may
2028 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2029 * themselves. Any null fields will be initialised with default values,
2030 * non-null fields are left alone.
2035 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2037 errorMessage = null;
2038 if (uniqueSetSuffix == null)
2040 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2042 if (seqRefIds == null)
2044 seqRefIds = new HashMap<String, SequenceI>();
2046 if (frefedSequence == null)
2048 frefedSequence = new Vector();
2051 AlignFrame af = null, _af = null;
2052 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
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();
2153 * Regather multiple views (with the same sequence set id) to the frame (if
2154 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2155 * views instead of separate frames. Note this doesn't restore a state where
2156 * some expanded views in turn have tabbed views - the last "first tab" read
2157 * in will play the role of gatherer for all.
2159 for (AlignFrame fr : gatherToThisFrame.values())
2161 Desktop.instance.gatherViews(fr);
2164 restoreSplitFrames();
2166 if (errorMessage != null)
2174 * Try to reconstruct and display SplitFrame windows, where each contains
2175 * complementary dna and protein alignments. Done by pairing up AlignFrame
2176 * objects (created earlier) which have complementary viewport ids associated.
2178 protected void restoreSplitFrames()
2180 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2181 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2182 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2185 * Identify the DNA alignments
2187 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2190 AlignFrame af = candidate.getValue();
2191 if (af.getViewport().getAlignment().isNucleotide())
2193 dna.put(candidate.getKey().getId(), af);
2198 * Try to match up the protein complements
2200 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2203 AlignFrame af = candidate.getValue();
2204 if (!af.getViewport().getAlignment().isNucleotide())
2206 String complementId = candidate.getKey().getComplementId();
2207 // only non-null complements should be in the Map
2208 if (complementId != null && dna.containsKey(complementId))
2210 final AlignFrame dnaFrame = dna.get(complementId);
2211 SplitFrame sf = createSplitFrame(dnaFrame, af);
2212 addedToSplitFrames.add(dnaFrame);
2213 addedToSplitFrames.add(af);
2214 if (af.viewport.isGatherViewsHere())
2223 * Open any that we failed to pair up (which shouldn't happen!) as
2224 * standalone AlignFrame's.
2226 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2229 AlignFrame af = candidate.getValue();
2230 if (!addedToSplitFrames.contains(af)) {
2231 Viewport view = candidate.getKey();
2232 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2234 System.err.println("Failed to restore view " + view.getTitle()
2235 + " to split frame");
2240 * Gather back into tabbed views as flagged.
2242 for (SplitFrame sf : gatherTo)
2244 Desktop.instance.gatherViews(sf);
2247 splitFrameCandidates.clear();
2251 * Construct and display one SplitFrame holding DNA and protein alignments.
2254 * @param proteinFrame
2257 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2258 AlignFrame proteinFrame)
2260 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2261 String title = MessageManager.getString("label.linked_view_title");
2262 int width = (int) dnaFrame.getBounds().getWidth();
2263 int height = (int) (dnaFrame.getBounds().getHeight()
2264 + proteinFrame.getBounds().getHeight() + 50);
2265 Desktop.addInternalFrame(splitFrame, title, width, height);
2268 * And compute cDNA consensus (couldn't do earlier with consensus as
2269 * mappings were not yet present)
2271 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2277 * check errorMessage for a valid error message and raise an error box in the
2278 * GUI or write the current errorMessage to stderr and then clear the error
2281 protected void reportErrors()
2283 reportErrors(false);
2286 protected void reportErrors(final boolean saving)
2288 if (errorMessage != null)
2290 final String finalErrorMessage = errorMessage;
2293 javax.swing.SwingUtilities.invokeLater(new Runnable()
2298 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2299 finalErrorMessage, "Error "
2300 + (saving ? "saving" : "loading")
2301 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2307 System.err.println("Problem loading Jalview file: " + errorMessage);
2310 errorMessage = null;
2313 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2316 * when set, local views will be updated from view stored in JalviewXML
2317 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2318 * sync if this is set to true.
2320 private final boolean updateLocalViews = false;
2322 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2324 if (alreadyLoadedPDB.containsKey(pdbId))
2326 return alreadyLoadedPDB.get(pdbId).toString();
2331 JarInputStream jin = jprovider.getJarInputStream();
2333 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2334 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2335 * FileInputStream(jprovider)); }
2338 JarEntry entry = null;
2341 entry = jin.getNextJarEntry();
2342 } while (entry != null && !entry.getName().equals(pdbId));
2345 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2346 File outFile = File.createTempFile("jalview_pdb", ".txt");
2347 outFile.deleteOnExit();
2348 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2351 while ((data = in.readLine()) != null)
2358 } catch (Exception foo)
2363 String t = outFile.getAbsolutePath();
2364 alreadyLoadedPDB.put(pdbId, t);
2369 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2371 } catch (Exception ex)
2373 ex.printStackTrace();
2379 private class JvAnnotRow
2381 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2388 * persisted version of annotation row from which to take vis properties
2390 public jalview.datamodel.AlignmentAnnotation template;
2393 * original position of the annotation row in the alignment
2399 * Load alignment frame from jalview XML DOM object
2404 * filename source string
2405 * @param loadTreesAndStructures
2406 * when false only create Viewport
2408 * data source provider
2409 * @return alignment frame created from view stored in DOM
2411 AlignFrame loadFromObject(JalviewModel object, String file,
2412 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2414 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2415 Sequence[] vamsasSeq = vamsasSet.getSequence();
2417 JalviewModelSequence jms = object.getJalviewModelSequence();
2419 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2422 // ////////////////////////////////
2425 List<SequenceI> hiddenSeqs = null;
2426 jalview.datamodel.Sequence jseq;
2428 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2430 boolean multipleView = false;
2432 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2433 int vi = 0; // counter in vamsasSeq array
2434 for (int i = 0; i < jseqs.length; i++)
2436 String seqId = jseqs[i].getId();
2438 if (seqRefIds.get(seqId) != null)
2440 tmpseqs.add(seqRefIds.get(seqId));
2441 multipleView = true;
2445 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2446 vamsasSeq[vi].getSequence());
2447 jseq.setDescription(vamsasSeq[vi].getDescription());
2448 jseq.setStart(jseqs[i].getStart());
2449 jseq.setEnd(jseqs[i].getEnd());
2450 jseq.setVamsasId(uniqueSetSuffix + seqId);
2451 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2456 if (jseqs[i].getHidden())
2458 if (hiddenSeqs == null)
2460 hiddenSeqs = new ArrayList<SequenceI>();
2463 hiddenSeqs.add(seqRefIds.get(seqId));
2469 // Create the alignment object from the sequence set
2470 // ///////////////////////////////
2471 SequenceI[] orderedSeqs = tmpseqs
2472 .toArray(new SequenceI[tmpseqs.size()]);
2474 Alignment al = new Alignment(orderedSeqs);
2476 // / Add the alignment properties
2477 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2479 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2480 al.setProperty(ssp.getKey(), ssp.getValue());
2484 // SequenceFeatures are added to the DatasetSequence,
2485 // so we must create or recover the dataset before loading features
2486 // ///////////////////////////////
2487 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2489 // older jalview projects do not have a dataset id.
2490 al.setDataset(null);
2494 // recover dataset - passing on flag indicating if this a 'viewless'
2495 // sequence set (a.k.a. a stored dataset for the project)
2496 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2497 .getViewportCount() == 0);
2499 // ///////////////////////////////
2501 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2504 // load sequence features, database references and any associated PDB
2505 // structures for the alignment
2506 for (int i = 0; i < vamsasSeq.length; i++)
2508 if (jseqs[i].getFeaturesCount() > 0)
2510 Features[] features = jseqs[i].getFeatures();
2511 for (int f = 0; f < features.length; f++)
2513 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2514 features[f].getType(), features[f].getDescription(),
2515 features[f].getStatus(), features[f].getBegin(),
2516 features[f].getEnd(), features[f].getFeatureGroup());
2518 sf.setScore(features[f].getScore());
2519 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2521 OtherData keyValue = features[f].getOtherData(od);
2522 if (keyValue.getKey().startsWith("LINK"))
2524 sf.addLink(keyValue.getValue());
2528 sf.setValue(keyValue.getKey(), keyValue.getValue());
2533 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2536 if (vamsasSeq[i].getDBRefCount() > 0)
2538 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2540 if (jseqs[i].getPdbidsCount() > 0)
2542 Pdbids[] ids = jseqs[i].getPdbids();
2543 for (int p = 0; p < ids.length; p++)
2545 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2546 entry.setId(ids[p].getId());
2547 if (ids[p].getType() != null)
2549 if (ids[p].getType().equalsIgnoreCase("PDB"))
2551 entry.setType(PDBEntry.Type.PDB);
2555 entry.setType(PDBEntry.Type.FILE);
2558 if (ids[p].getFile() != null)
2560 if (!pdbloaded.containsKey(ids[p].getFile()))
2562 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2566 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2569 StructureSelectionManager.getStructureSelectionManager(
2570 Desktop.instance).registerPDBEntry(entry);
2571 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2575 } // end !multipleview
2577 // ///////////////////////////////
2578 // LOAD SEQUENCE MAPPINGS
2580 if (vamsasSet.getAlcodonFrameCount() > 0)
2582 // TODO Potentially this should only be done once for all views of an
2584 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2585 for (int i = 0; i < alc.length; i++)
2587 AlignedCodonFrame cf = new AlignedCodonFrame();
2588 if (alc[i].getAlcodMapCount() > 0)
2590 AlcodMap[] maps = alc[i].getAlcodMap();
2591 for (int m = 0; m < maps.length; m++)
2593 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2595 jalview.datamodel.Mapping mapping = null;
2596 // attach to dna sequence reference.
2597 if (maps[m].getMapping() != null)
2599 mapping = addMapping(maps[m].getMapping());
2603 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2608 frefedSequence.add(new Object[]
2609 { maps[m].getDnasq(), cf, mapping });
2613 al.addCodonFrame(cf);
2617 // ////////////////////////////////
2619 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2621 * store any annotations which forward reference a group's ID
2623 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2625 if (vamsasSet.getAnnotationCount() > 0)
2627 Annotation[] an = vamsasSet.getAnnotation();
2629 for (int i = 0; i < an.length; i++)
2632 * test if annotation is automatically calculated for this view only
2634 boolean autoForView = false;
2635 if (an[i].getLabel().equals("Quality")
2636 || an[i].getLabel().equals("Conservation")
2637 || an[i].getLabel().equals("Consensus"))
2639 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2641 if (!an[i].hasAutoCalculated())
2643 an[i].setAutoCalculated(true);
2647 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2649 // remove ID - we don't recover annotation from other views for
2650 // view-specific annotation
2654 // set visiblity for other annotation in this view
2655 if (an[i].getId() != null
2656 && annotationIds.containsKey(an[i].getId()))
2658 AlignmentAnnotation jda = annotationIds.get(an[i].getId());
2659 // in principle Visible should always be true for annotation displayed
2660 // in multiple views
2661 if (an[i].hasVisible())
2663 jda.visible = an[i].getVisible();
2666 al.addAnnotation(jda);
2670 // Construct new annotation from model.
2671 AnnotationElement[] ae = an[i].getAnnotationElement();
2672 jalview.datamodel.Annotation[] anot = null;
2673 java.awt.Color firstColour = null;
2675 if (!an[i].getScoreOnly())
2677 anot = new jalview.datamodel.Annotation[al.getWidth()];
2678 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2680 anpos = ae[aa].getPosition();
2682 if (anpos >= anot.length)
2687 anot[anpos] = new jalview.datamodel.Annotation(
2689 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2690 (ae[aa].getSecondaryStructure() == null || ae[aa]
2691 .getSecondaryStructure().length() == 0) ? ' '
2692 : ae[aa].getSecondaryStructure().charAt(0),
2696 // JBPNote: Consider verifying dataflow for IO of secondary
2697 // structure annotation read from Stockholm files
2698 // this was added to try to ensure that
2699 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2701 // anot[ae[aa].getPosition()].displayCharacter = "";
2703 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2704 if (firstColour == null)
2706 firstColour = anot[anpos].colour;
2710 jalview.datamodel.AlignmentAnnotation jaa = null;
2712 if (an[i].getGraph())
2714 float llim = 0, hlim = 0;
2715 // if (autoForView || an[i].isAutoCalculated()) {
2718 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2719 an[i].getDescription(), anot, llim, hlim,
2720 an[i].getGraphType());
2722 jaa.graphGroup = an[i].getGraphGroup();
2723 jaa._linecolour = firstColour;
2724 if (an[i].getThresholdLine() != null)
2726 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2727 .getThresholdLine().getValue(), an[i]
2728 .getThresholdLine().getLabel(), new java.awt.Color(
2729 an[i].getThresholdLine().getColour())));
2732 if (autoForView || an[i].isAutoCalculated())
2734 // Hardwire the symbol display line to ensure that labels for
2735 // histograms are displayed
2741 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2742 an[i].getDescription(), anot);
2743 jaa._linecolour = firstColour;
2745 // register new annotation
2746 if (an[i].getId() != null)
2748 annotationIds.put(an[i].getId(), jaa);
2749 jaa.annotationId = an[i].getId();
2751 // recover sequence association
2752 if (an[i].getSequenceRef() != null)
2754 if (al.findName(an[i].getSequenceRef()) != null)
2756 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2758 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2761 // and make a note of any group association
2762 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2764 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2765 .get(an[i].getGroupRef());
2768 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2769 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2774 if (an[i].hasScore())
2776 jaa.setScore(an[i].getScore());
2778 if (an[i].hasVisible())
2780 jaa.visible = an[i].getVisible();
2783 if (an[i].hasCentreColLabels())
2785 jaa.centreColLabels = an[i].getCentreColLabels();
2788 if (an[i].hasScaleColLabels())
2790 jaa.scaleColLabel = an[i].getScaleColLabels();
2792 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2794 // newer files have an 'autoCalculated' flag and store calculation
2795 // state in viewport properties
2796 jaa.autoCalculated = true; // means annotation will be marked for
2797 // update at end of load.
2799 if (an[i].hasGraphHeight())
2801 jaa.graphHeight = an[i].getGraphHeight();
2803 if (an[i].hasBelowAlignment())
2805 jaa.belowAlignment = an[i].isBelowAlignment();
2807 jaa.setCalcId(an[i].getCalcId());
2808 if (an[i].getPropertyCount() > 0)
2810 for (jalview.schemabinding.version2.Property prop : an[i]
2813 jaa.setProperty(prop.getName(), prop.getValue());
2816 if (jaa.autoCalculated)
2818 autoAlan.add(new JvAnnotRow(i, jaa));
2821 // if (!autoForView)
2823 // add autocalculated group annotation and any user created annotation
2825 al.addAnnotation(jaa);
2829 // ///////////////////////
2831 // Create alignment markup and styles for this view
2832 if (jms.getJGroupCount() > 0)
2834 JGroup[] groups = jms.getJGroup();
2835 boolean addAnnotSchemeGroup = false;
2836 for (int i = 0; i < groups.length; i++)
2838 ColourSchemeI cs = null;
2840 if (groups[i].getColour() != null)
2842 if (groups[i].getColour().startsWith("ucs"))
2844 cs = getUserColourScheme(jms, groups[i].getColour());
2846 else if (groups[i].getColour().equals("AnnotationColourGradient")
2847 && groups[i].getAnnotationColours() != null)
2849 addAnnotSchemeGroup = true;
2854 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2859 cs.setThreshold(groups[i].getPidThreshold(), true);
2863 Vector seqs = new Vector();
2865 for (int s = 0; s < groups[i].getSeqCount(); s++)
2867 String seqId = groups[i].getSeq(s) + "";
2868 jalview.datamodel.SequenceI ts = seqRefIds.get(seqId);
2872 seqs.addElement(ts);
2876 if (seqs.size() < 1)
2881 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2882 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2883 groups[i].getDisplayText(), groups[i].getColourText(),
2884 groups[i].getStart(), groups[i].getEnd());
2886 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2888 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2889 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2890 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2891 .isShowUnconserved() : false);
2892 sg.thresholdTextColour = groups[i].getTextColThreshold();
2893 if (groups[i].hasShowConsensusHistogram())
2895 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2898 if (groups[i].hasShowSequenceLogo())
2900 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2902 if (groups[i].hasNormaliseSequenceLogo())
2904 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2906 if (groups[i].hasIgnoreGapsinConsensus())
2908 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2910 if (groups[i].getConsThreshold() != 0)
2912 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2913 "All", ResidueProperties.propHash, 3,
2914 sg.getSequences(null), 0, sg.getWidth() - 1);
2916 c.verdict(false, 25);
2917 sg.cs.setConservation(c);
2920 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2922 // re-instate unique group/annotation row reference
2923 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2924 .get(groups[i].getId());
2927 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2930 if (jaa.autoCalculated)
2932 // match up and try to set group autocalc alignment row for this
2934 if (jaa.label.startsWith("Consensus for "))
2936 sg.setConsensus(jaa);
2938 // match up and try to set group autocalc alignment row for this
2940 if (jaa.label.startsWith("Conservation for "))
2942 sg.setConservationRow(jaa);
2949 if (addAnnotSchemeGroup)
2951 // reconstruct the annotation colourscheme
2952 sg.cs = constructAnnotationColour(
2953 groups[i].getAnnotationColours(), null, al, jms, false);
2959 // only dataset in this model, so just return.
2962 // ///////////////////////////////
2965 // If we just load in the same jar file again, the sequenceSetId
2966 // will be the same, and we end up with multiple references
2967 // to the same sequenceSet. We must modify this id on load
2968 // so that each load of the file gives a unique id
2969 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2970 String viewId = (view.getId() == null ? null : view.getId()
2972 AlignFrame af = null;
2973 AlignViewport av = null;
2974 // now check to see if we really need to create a new viewport.
2975 if (multipleView && viewportsAdded.size() == 0)
2977 // We recovered an alignment for which a viewport already exists.
2978 // TODO: fix up any settings necessary for overlaying stored state onto
2979 // state recovered from another document. (may not be necessary).
2980 // we may need a binding from a viewport in memory to one recovered from
2982 // and then recover its containing af to allow the settings to be applied.
2983 // TODO: fix for vamsas demo
2985 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2987 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2988 if (seqsetobj != null)
2990 if (seqsetobj instanceof String)
2992 uniqueSeqSetId = (String) seqsetobj;
2994 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3000 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3006 * indicate that annotation colours are applied across all groups (pre
3007 * Jalview 2.8.1 behaviour)
3009 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
3010 object.getVersion());
3012 AlignmentPanel ap = null;
3013 boolean isnewview = true;
3016 // Check to see if this alignment already has a view id == viewId
3017 jalview.gui.AlignmentPanel views[] = Desktop
3018 .getAlignmentPanels(uniqueSeqSetId);
3019 if (views != null && views.length > 0)
3021 for (int v = 0; v < views.length; v++)
3023 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3025 // recover the existing alignpanel, alignframe, viewport
3026 af = views[v].alignFrame;
3029 // TODO: could even skip resetting view settings if we don't want to
3030 // change the local settings from other jalview processes
3039 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3040 uniqueSeqSetId, viewId, autoAlan);
3045 // /////////////////////////////////////
3046 if (loadTreesAndStructures && jms.getTreeCount() > 0)
3050 for (int t = 0; t < jms.getTreeCount(); t++)
3053 Tree tree = jms.getTree(t);
3055 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3058 tp = af.ShowNewickTree(
3059 new jalview.io.NewickFile(tree.getNewick()),
3060 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3061 tree.getXpos(), tree.getYpos());
3062 if (tree.getId() != null)
3064 // perhaps bind the tree id to something ?
3069 // update local tree attributes ?
3070 // TODO: should check if tp has been manipulated by user - if so its
3071 // settings shouldn't be modified
3072 tp.setTitle(tree.getTitle());
3073 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3074 .getWidth(), tree.getHeight()));
3075 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3078 tp.treeCanvas.av = av; // af.viewport;
3079 tp.treeCanvas.ap = ap; // af.alignPanel;
3084 warn("There was a problem recovering stored Newick tree: \n"
3085 + tree.getNewick());
3089 tp.fitToWindow.setState(tree.getFitToWindow());
3090 tp.fitToWindow_actionPerformed(null);
3092 if (tree.getFontName() != null)
3094 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3095 .getFontStyle(), tree.getFontSize()));
3099 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3100 .getFontStyle(), tree.getFontSize()));
3103 tp.showPlaceholders(tree.getMarkUnlinked());
3104 tp.showBootstrap(tree.getShowBootstrap());
3105 tp.showDistances(tree.getShowDistances());
3107 tp.treeCanvas.threshold = tree.getThreshold();
3109 if (tree.getCurrentTree())
3111 af.viewport.setCurrentTree(tp.getTree());
3115 } catch (Exception ex)
3117 ex.printStackTrace();
3121 // //LOAD STRUCTURES
3122 if (loadTreesAndStructures)
3124 loadStructures(jprovider, jseqs, af, ap);
3126 // and finally return.
3131 * Load and link any saved structure viewers.
3138 protected void loadStructures(jarInputStreamProvider jprovider,
3139 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3142 * Run through all PDB ids on the alignment, and collect mappings between
3143 * distinct view ids and all sequences referring to that view.
3145 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3147 for (int i = 0; i < jseqs.length; i++)
3149 if (jseqs[i].getPdbidsCount() > 0)
3151 Pdbids[] ids = jseqs[i].getPdbids();
3152 for (int p = 0; p < ids.length; p++)
3154 final int structureStateCount = ids[p].getStructureStateCount();
3155 for (int s = 0; s < structureStateCount; s++)
3157 // check to see if we haven't already created this structure view
3158 final StructureState structureState = ids[p]
3159 .getStructureState(s);
3160 String sviewid = (structureState.getViewId() == null) ? null
3161 : structureState.getViewId() + uniqueSetSuffix;
3162 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3163 // Originally : ids[p].getFile()
3164 // : TODO: verify external PDB file recovery still works in normal
3165 // jalview project load
3166 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3167 jpdb.setId(ids[p].getId());
3169 int x = structureState.getXpos();
3170 int y = structureState.getYpos();
3171 int width = structureState.getWidth();
3172 int height = structureState.getHeight();
3174 // Probably don't need to do this anymore...
3175 // Desktop.desktop.getComponentAt(x, y);
3176 // TODO: NOW: check that this recovers the PDB file correctly.
3177 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3178 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3180 if (sviewid == null)
3182 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3185 if (!structureViewers.containsKey(sviewid))
3187 structureViewers.put(sviewid, new StructureViewerModel(x, y,
3188 width, height, false, false, true));
3189 // Legacy pre-2.7 conversion JAL-823 :
3190 // do not assume any view has to be linked for colour by
3194 // assemble String[] { pdb files }, String[] { id for each
3195 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3196 // seqs_file 2}, boolean[] {
3197 // linkAlignPanel,superposeWithAlignpanel}} from hash
3198 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3199 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3200 | (structureState.hasAlignwithAlignPanel() ? structureState
3201 .getAlignwithAlignPanel() : false));
3204 * Default colour by linked panel to false if not specified (e.g.
3205 * for pre-2.7 projects)
3207 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3208 colourWithAlignPanel |= (structureState
3209 .hasColourwithAlignPanel() ? structureState
3210 .getColourwithAlignPanel() : false);
3211 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3214 * Default colour by viewer to true if not specified (e.g. for
3217 boolean colourByViewer = jmoldat.isColourByViewer();
3218 colourByViewer &= structureState.hasColourByJmol() ? structureState
3219 .getColourByJmol() : true;
3220 jmoldat.setColourByViewer(colourByViewer);
3222 if (jmoldat.getStateData().length() < structureState
3223 .getContent().length())
3226 jmoldat.setStateData(structureState.getContent());
3229 if (ids[p].getFile() != null)
3231 File mapkey = new File(ids[p].getFile());
3232 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3233 if (seqstrmaps == null)
3235 jmoldat.getFileData().put(
3237 seqstrmaps = jmoldat.new StructureData(pdbFile,
3240 if (!seqstrmaps.getSeqList().contains(seq))
3242 seqstrmaps.getSeqList().add(seq);
3248 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");
3255 // Instantiate the associated structure views
3256 for (Entry<String, StructureViewerModel> entry : structureViewers
3259 createOrLinkStructureViewer(entry, af, ap);
3269 protected void createOrLinkStructureViewer(
3270 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3273 final StructureViewerModel svattrib = viewerData.getValue();
3276 * Search for any viewer windows already open from other alignment views
3277 * that exactly match the stored structure state
3279 StructureViewerBase comp = findMatchingViewer(viewerData);
3283 linkStructureViewer(ap, comp, svattrib);
3288 * Pending an XML element for ViewerType, just check if stateData contains
3289 * "chimera" (part of the chimera session filename).
3291 if (svattrib.getStateData().indexOf("chimera") > -1)
3293 createChimeraViewer(viewerData, af);
3297 createJmolViewer(viewerData, af);
3302 * Create a new Chimera viewer.
3307 protected void createChimeraViewer(
3308 Entry<String, StructureViewerModel> viewerData, AlignFrame af)
3310 final StructureViewerModel data = viewerData.getValue();
3311 String chimeraSession = data.getStateData();
3313 if (new File(chimeraSession).exists())
3315 Set<Entry<File, StructureData>> fileData = data.getFileData()
3317 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3318 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3319 for (Entry<File, StructureData> pdb : fileData)
3321 String filePath = pdb.getValue().getFilePath();
3322 String pdbId = pdb.getValue().getPdbId();
3323 // pdbs.add(new PDBEntry(filePath, pdbId));
3324 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3325 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3326 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3330 boolean colourByChimera = data.isColourByViewer();
3331 boolean colourBySequence = data.isColourWithAlignPanel();
3333 // TODO can/should this be done via StructureViewer (like Jmol)?
3334 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3335 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3337 new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray,
3338 seqsArray, colourByChimera, colourBySequence);
3342 Cache.log.error("Chimera session file " + chimeraSession
3348 * Create a new Jmol window. First parse the Jmol state to translate filenames
3349 * loaded into the view, and record the order in which files are shown in the
3350 * Jmol view, so we can add the sequence mappings in same order.
3355 protected void createJmolViewer(
3356 final Entry<String, StructureViewerModel> viewerData,
3359 final StructureViewerModel svattrib = viewerData.getValue();
3360 String state = svattrib.getStateData();
3361 List<String> pdbfilenames = new ArrayList<String>();
3362 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3363 List<String> pdbids = new ArrayList<String>();
3364 StringBuilder newFileLoc = new StringBuilder(64);
3365 int cp = 0, ncp, ecp;
3366 Map<File, StructureData> oldFiles = svattrib.getFileData();
3367 while ((ncp = state.indexOf("load ", cp)) > -1)
3371 // look for next filename in load statement
3372 newFileLoc.append(state.substring(cp,
3373 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3374 String oldfilenam = state.substring(ncp,
3375 ecp = state.indexOf("\"", ncp));
3376 // recover the new mapping data for this old filename
3377 // have to normalize filename - since Jmol and jalview do
3379 // translation differently.
3380 StructureData filedat = oldFiles.get(new File(oldfilenam));
3381 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3382 pdbfilenames.add(filedat.getFilePath());
3383 pdbids.add(filedat.getPdbId());
3384 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3385 newFileLoc.append("\"");
3386 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3387 // look for next file statement.
3388 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3392 // just append rest of state
3393 newFileLoc.append(state.substring(cp));
3397 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3398 newFileLoc = new StringBuilder(state);
3399 newFileLoc.append("; load append ");
3400 for (File id : oldFiles.keySet())
3402 // add this and any other pdb files that should be present in
3404 StructureData filedat = oldFiles.get(id);
3405 newFileLoc.append(filedat.getFilePath());
3406 pdbfilenames.add(filedat.getFilePath());
3407 pdbids.add(filedat.getPdbId());
3408 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3409 newFileLoc.append(" \"");
3410 newFileLoc.append(filedat.getFilePath());
3411 newFileLoc.append("\"");
3414 newFileLoc.append(";");
3417 if (newFileLoc.length() > 0)
3419 int histbug = newFileLoc.indexOf("history = ");
3421 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3422 String val = (diff == -1) ? null : newFileLoc
3423 .substring(histbug, diff);
3424 if (val != null && val.length() >= 4)
3426 if (val.contains("e"))
3428 if (val.trim().equals("true"))
3436 newFileLoc.replace(histbug, diff, val);
3440 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3442 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3443 final SequenceI[][] sq = seqmaps
3444 .toArray(new SequenceI[seqmaps.size()][]);
3445 final String fileloc = newFileLoc.toString();
3446 final String sviewid = viewerData.getKey();
3447 final AlignFrame alf = af;
3448 final Rectangle rect = new Rectangle(svattrib.getX(),
3449 svattrib.getY(), svattrib.getWidth(), svattrib.getHeight());
3452 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3457 JalviewStructureDisplayI sview = null;
3460 // JAL-1333 note - we probably can't migrate Jmol views to UCSF
3462 sview = new StructureViewer(alf.alignPanel
3463 .getStructureSelectionManager()).createView(
3464 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3465 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3466 addNewStructureViewer(sview);
3467 } catch (OutOfMemoryError ex)
3469 new OOMWarning("restoring structure view for PDB id " + id,
3470 (OutOfMemoryError) ex.getCause());
3471 if (sview != null && sview.isVisible())
3473 sview.closeViewer(false);
3474 sview.setVisible(false);
3480 } catch (InvocationTargetException ex)
3482 warn("Unexpected error when opening Jmol view.", ex);
3484 } catch (InterruptedException e)
3486 // e.printStackTrace();
3492 * Returns any open frame that matches given structure viewer data. The match
3493 * is based on the unique viewId, or (for older project versions) the frame's
3499 protected StructureViewerBase findMatchingViewer(
3500 Entry<String, StructureViewerModel> viewerData)
3502 final String sviewid = viewerData.getKey();
3503 final StructureViewerModel svattrib = viewerData.getValue();
3504 StructureViewerBase comp = null;
3505 JInternalFrame[] frames = getAllFrames();
3506 for (JInternalFrame frame : frames)
3508 if (frame instanceof StructureViewerBase)
3511 * Post jalview 2.4 schema includes structure view id
3514 && ((StructureViewerBase) frame).getViewId()
3517 comp = (AppJmol) frame;
3521 * Otherwise test for matching position and size of viewer frame
3523 else if (frame.getX() == svattrib.getX()
3524 && frame.getY() == svattrib.getY()
3525 && frame.getHeight() == svattrib.getHeight()
3526 && frame.getWidth() == svattrib.getWidth())
3528 comp = (AppJmol) frame;
3537 * Link an AlignmentPanel to an existing structure viewer.
3542 * @param useinViewerSuperpos
3543 * @param usetoColourbyseq
3544 * @param viewerColouring
3546 protected void linkStructureViewer(AlignmentPanel ap,
3547 StructureViewerBase viewer, StructureViewerModel svattrib)
3549 // NOTE: if the jalview project is part of a shared session then
3550 // view synchronization should/could be done here.
3552 final boolean useinViewerSuperpos = svattrib.isAlignWithPanel();
3553 final boolean usetoColourbyseq = svattrib.isColourWithAlignPanel();
3554 final boolean viewerColouring = svattrib.isColourByViewer();
3555 Map<File, StructureData> oldFiles = svattrib.getFileData();
3558 * Add mapping for sequences in this view to an already open viewer
3560 final AAStructureBindingModel binding = viewer.getBinding();
3561 for (File id : oldFiles.keySet())
3563 // add this and any other pdb files that should be present in the
3565 StructureData filedat = oldFiles.get(id);
3566 String pdbFile = filedat.getFilePath();
3567 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3568 binding.getSsm().setMapping(seq, null, pdbFile,
3569 jalview.io.AppletFormatAdapter.FILE);
3570 binding.addSequenceForStructFile(pdbFile, seq);
3572 // and add the AlignmentPanel's reference to the view panel
3573 viewer.addAlignmentPanel(ap);
3574 if (useinViewerSuperpos)
3576 viewer.useAlignmentPanelForSuperposition(ap);
3580 viewer.excludeAlignmentPanelForSuperposition(ap);
3582 if (usetoColourbyseq)
3584 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3588 viewer.excludeAlignmentPanelForColourbyseq(ap);
3593 * Get all frames within the Desktop.
3597 protected JInternalFrame[] getAllFrames()
3599 JInternalFrame[] frames = null;
3600 // TODO is this necessary - is it safe - risk of hanging?
3605 frames = Desktop.desktop.getAllFrames();
3606 } catch (ArrayIndexOutOfBoundsException e)
3608 // occasional No such child exceptions are thrown here...
3612 } catch (InterruptedException f)
3616 } while (frames == null);
3623 * - minimum version we are comparing against
3625 * - version of data being processsed.
3626 * @return true if version is development/null or evaluates to the same or
3627 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3629 private boolean isVersionStringLaterThan(String supported, String version)
3631 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3632 || version.equalsIgnoreCase("Test")
3633 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3635 System.err.println("Assuming project file with "
3636 + (version == null ? "null" : version)
3637 + " is compatible with Jalview version " + supported);
3642 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3644 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3646 // convert b to decimal to catch bugfix releases within a series
3647 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3648 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3651 if (Float.valueOf(curT) > Float.valueOf(fileT))
3653 // current version is newer than the version that wrote the file
3656 } catch (NumberFormatException nfe)
3659 .println("** WARNING: Version comparison failed for tokens ("
3663 + ")\n** Current: '"
3664 + supported + "' and Version: '" + version + "'");
3667 if (currentV.hasMoreElements())
3669 // fileV has no minor version but identical series to current
3676 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3678 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3680 if (newStructureViewers != null)
3682 sview.getBinding().setFinishedLoadingFromArchive(false);
3683 newStructureViewers.add(sview);
3687 protected void setLoadingFinishedForNewStructureViewers()
3689 if (newStructureViewers != null)
3691 for (JalviewStructureDisplayI sview : newStructureViewers)
3693 sview.getBinding().setFinishedLoadingFromArchive(true);
3695 newStructureViewers.clear();
3696 newStructureViewers = null;
3700 AlignFrame loadViewport(String file, JSeq[] JSEQ,
3701 List<SequenceI> hiddenSeqs, Alignment al,
3702 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
3703 String viewId, List<JvAnnotRow> autoAlan)
3705 AlignFrame af = null;
3706 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3707 uniqueSeqSetId, viewId);
3709 af.setFileName(file, "Jalview");
3711 for (int i = 0; i < JSEQ.length; i++)
3713 af.viewport.setSequenceColour(af.viewport.getAlignment()
3714 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3717 af.viewport.setGatherViewsHere(view.getGatheredViews());
3719 if (view.getSequenceSetId() != null)
3721 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
3723 af.viewport.setSequenceSetId(uniqueSeqSetId);
3726 // propagate shared settings to this new view
3727 af.viewport.setHistoryList(av.getHistoryList());
3728 af.viewport.setRedoList(av.getRedoList());
3732 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3734 // TODO: check if this method can be called repeatedly without
3735 // side-effects if alignpanel already registered.
3736 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3738 // apply Hidden regions to view.
3739 if (hiddenSeqs != null)
3741 for (int s = 0; s < JSEQ.length; s++)
3743 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3745 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3748 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3750 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3753 // jalview.datamodel.SequenceI[] hseqs = new
3754 // jalview.datamodel.SequenceI[hiddenSeqs
3757 // for (int s = 0; s < hiddenSeqs.size(); s++)
3759 // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3762 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
3764 af.viewport.hideSequence(hseqs);
3767 // recover view properties and display parameters
3768 if (view.getViewName() != null)
3770 af.viewport.viewName = view.getViewName();
3771 af.setInitialTabVisible();
3773 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3776 af.viewport.setShowAnnotation(view.getShowAnnotation());
3777 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3779 af.viewport.setColourText(view.getShowColourText());
3781 af.viewport.setConservationSelected(view.getConservationSelected());
3782 af.viewport.setShowJVSuffix(view.getShowFullId());
3783 af.viewport.setRightAlignIds(view.getRightAlignIds());
3784 af.viewport.setFont(
3785 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
3786 .getFontSize()), true);
3787 // TODO: allow custom charWidth/Heights to be restored by updating them
3788 // after setting font - which means set above to false
3789 af.viewport.setRenderGaps(view.getRenderGaps());
3790 af.viewport.setWrapAlignment(view.getWrapAlignment());
3791 af.viewport.setShowAnnotation(view.getShowAnnotation());
3793 af.viewport.setShowBoxes(view.getShowBoxes());
3795 af.viewport.setShowText(view.getShowText());
3797 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
3798 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
3799 af.viewport.setThresholdTextColour(view.getTextColThreshold());
3800 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3801 .isShowUnconserved() : false);
3802 af.viewport.setStartRes(view.getStartRes());
3803 af.viewport.setStartSeq(view.getStartSeq());
3804 af.alignPanel.updateLayout();
3805 ColourSchemeI cs = null;
3806 // apply colourschemes
3807 if (view.getBgColour() != null)
3809 if (view.getBgColour().startsWith("ucs"))
3811 cs = getUserColourScheme(jms, view.getBgColour());
3813 else if (view.getBgColour().startsWith("Annotation"))
3815 AnnotationColours viewAnnColour = view.getAnnotationColours();
3816 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3823 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3828 cs.setThreshold(view.getPidThreshold(), true);
3829 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3833 af.viewport.setGlobalColourScheme(cs);
3834 af.viewport.setColourAppliesToAllGroups(false);
3836 if (view.getConservationSelected() && cs != null)
3838 cs.setConservationInc(view.getConsThreshold());
3841 af.changeColour(cs);
3843 af.viewport.setColourAppliesToAllGroups(true);
3845 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
3847 if (view.hasCentreColumnLabels())
3849 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3851 if (view.hasIgnoreGapsinConsensus())
3853 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3856 if (view.hasFollowHighlight())
3858 af.viewport.setFollowHighlight(view.getFollowHighlight());
3860 if (view.hasFollowSelection())
3862 af.viewport.followSelection = view.getFollowSelection();
3864 if (view.hasShowConsensusHistogram())
3866 af.viewport.setShowConsensusHistogram(view
3867 .getShowConsensusHistogram());
3871 af.viewport.setShowConsensusHistogram(true);
3873 if (view.hasShowSequenceLogo())
3875 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3879 af.viewport.setShowSequenceLogo(false);
3881 if (view.hasNormaliseSequenceLogo())
3883 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3885 if (view.hasShowDbRefTooltip())
3887 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
3889 if (view.hasShowNPfeatureTooltip())
3891 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
3893 if (view.hasShowGroupConsensus())
3895 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3899 af.viewport.setShowGroupConsensus(false);
3901 if (view.hasShowGroupConservation())
3903 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3907 af.viewport.setShowGroupConservation(false);
3910 // recover featre settings
3911 if (jms.getFeatureSettings() != null)
3913 FeaturesDisplayed fdi;
3914 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
3915 String[] renderOrder = new String[jms.getFeatureSettings()
3916 .getSettingCount()];
3917 Hashtable featureGroups = new Hashtable();
3918 Hashtable featureColours = new Hashtable();
3919 Hashtable featureOrder = new Hashtable();
3921 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3923 Setting setting = jms.getFeatureSettings().getSetting(fs);
3924 if (setting.hasMincolour())
3926 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3927 new java.awt.Color(setting.getMincolour()),
3928 new java.awt.Color(setting.getColour()),
3929 setting.getMin(), setting.getMax()) : new GraduatedColor(
3930 new java.awt.Color(setting.getMincolour()),
3931 new java.awt.Color(setting.getColour()), 0, 1);
3932 if (setting.hasThreshold())
3934 gc.setThresh(setting.getThreshold());
3935 gc.setThreshType(setting.getThreshstate());
3937 gc.setAutoScaled(true); // default
3938 if (setting.hasAutoScale())
3940 gc.setAutoScaled(setting.getAutoScale());
3942 if (setting.hasColourByLabel())
3944 gc.setColourByLabel(setting.getColourByLabel());
3946 // and put in the feature colour table.
3947 featureColours.put(setting.getType(), gc);
3951 featureColours.put(setting.getType(),
3952 new java.awt.Color(setting.getColour()));
3954 renderOrder[fs] = setting.getType();
3955 if (setting.hasOrder())
3957 featureOrder.put(setting.getType(), setting.getOrder());
3961 featureOrder.put(setting.getType(), new Float(fs
3962 / jms.getFeatureSettings().getSettingCount()));
3964 if (setting.getDisplay())
3966 fdi.setVisible(setting.getType());
3969 Hashtable fgtable = new Hashtable();
3970 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3972 Group grp = jms.getFeatureSettings().getGroup(gs);
3973 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3975 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
3976 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
3977 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
3978 FeatureRendererSettings frs = new FeatureRendererSettings(
3979 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
3980 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
3981 .transferSettings(frs);
3985 if (view.getHiddenColumnsCount() > 0)
3987 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3989 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3990 .getHiddenColumns(c).getEnd() // +1
3994 if (view.getCalcIdParam() != null)
3996 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3998 if (calcIdParam != null)
4000 if (recoverCalcIdParam(calcIdParam, af.viewport))
4005 warn("Couldn't recover parameters for "
4006 + calcIdParam.getCalcId());
4011 af.setMenusFromViewport(af.viewport);
4013 // TODO: we don't need to do this if the viewport is aready visible.
4015 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4016 * has a 'cdna/protein complement' view, in which case save it in order to
4017 * populate a SplitFrame once all views have been read in.
4019 String complementaryViewId = view.getComplementId();
4020 if (complementaryViewId == null)
4022 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4024 // recompute any autoannotation
4025 af.alignPanel.updateAnnotation(false, true);
4026 reorderAutoannotation(af, al, autoAlan);
4027 af.alignPanel.alignmentChanged();
4031 splitFrameCandidates.put(view, af);
4036 private ColourSchemeI constructAnnotationColour(
4037 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
4038 JalviewModelSequence jms, boolean checkGroupAnnColour)
4040 boolean propagateAnnColour = false;
4041 ColourSchemeI cs = null;
4042 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4043 if (checkGroupAnnColour && al.getGroups() != null
4044 && al.getGroups().size() > 0)
4046 // pre 2.8.1 behaviour
4047 // check to see if we should transfer annotation colours
4048 propagateAnnColour = true;
4049 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4051 if (sg.cs instanceof AnnotationColourGradient)
4053 propagateAnnColour = false;
4057 // int find annotation
4058 if (annAlignment.getAlignmentAnnotation() != null)
4060 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4062 if (annAlignment.getAlignmentAnnotation()[i].label
4063 .equals(viewAnnColour.getAnnotation()))
4065 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4067 annAlignment.getAlignmentAnnotation()[i]
4068 .setThreshold(new jalview.datamodel.GraphLine(
4069 viewAnnColour.getThreshold(), "Threshold",
4070 java.awt.Color.black)
4075 if (viewAnnColour.getColourScheme().equals("None"))
4077 cs = new AnnotationColourGradient(
4078 annAlignment.getAlignmentAnnotation()[i],
4079 new java.awt.Color(viewAnnColour.getMinColour()),
4080 new java.awt.Color(viewAnnColour.getMaxColour()),
4081 viewAnnColour.getAboveThreshold());
4083 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4085 cs = new AnnotationColourGradient(
4086 annAlignment.getAlignmentAnnotation()[i],
4087 getUserColourScheme(jms,
4088 viewAnnColour.getColourScheme()),
4089 viewAnnColour.getAboveThreshold());
4093 cs = new AnnotationColourGradient(
4094 annAlignment.getAlignmentAnnotation()[i],
4095 ColourSchemeProperty.getColour(al,
4096 viewAnnColour.getColourScheme()),
4097 viewAnnColour.getAboveThreshold());
4099 if (viewAnnColour.hasPerSequence())
4101 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4104 if (viewAnnColour.hasPredefinedColours())
4106 ((AnnotationColourGradient) cs)
4107 .setPredefinedColours(viewAnnColour
4108 .isPredefinedColours());
4110 if (propagateAnnColour && al.getGroups() != null)
4112 // Also use these settings for all the groups
4113 for (int g = 0; g < al.getGroups().size(); g++)
4115 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4123 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4124 * new AnnotationColourGradient(
4125 * annAlignment.getAlignmentAnnotation()[i], new
4126 * java.awt.Color(viewAnnColour. getMinColour()), new
4127 * java.awt.Color(viewAnnColour. getMaxColour()),
4128 * viewAnnColour.getAboveThreshold()); } else
4131 sg.cs = new AnnotationColourGradient(
4132 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4133 viewAnnColour.getAboveThreshold());
4134 if (cs instanceof AnnotationColourGradient)
4136 if (viewAnnColour.hasPerSequence())
4138 ((AnnotationColourGradient) cs)
4139 .setSeqAssociated(viewAnnColour.isPerSequence());
4141 if (viewAnnColour.hasPredefinedColours())
4143 ((AnnotationColourGradient) cs)
4144 .setPredefinedColours(viewAnnColour
4145 .isPredefinedColours());
4161 private void reorderAutoannotation(AlignFrame af, Alignment al,
4162 List<JvAnnotRow> autoAlan)
4164 // copy over visualization settings for autocalculated annotation in the
4166 if (al.getAlignmentAnnotation() != null)
4169 * Kludge for magic autoannotation names (see JAL-811)
4171 String[] magicNames = new String[]
4172 { "Consensus", "Quality", "Conservation" };
4173 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4174 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4175 for (String nm : magicNames)
4177 visan.put(nm, nullAnnot);
4179 for (JvAnnotRow auan : autoAlan)
4181 visan.put(auan.template.label
4182 + (auan.template.getCalcId() == null ? "" : "\t"
4183 + auan.template.getCalcId()), auan);
4185 int hSize = al.getAlignmentAnnotation().length;
4186 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4187 // work through any autoCalculated annotation already on the view
4188 // removing it if it should be placed in a different location on the
4189 // annotation panel.
4190 List<String> remains = new ArrayList<String>(visan.keySet());
4191 for (int h = 0; h < hSize; h++)
4193 jalview.datamodel.AlignmentAnnotation jalan = al
4194 .getAlignmentAnnotation()[h];
4195 if (jalan.autoCalculated)
4198 JvAnnotRow valan = visan.get(k = jalan.label);
4199 if (jalan.getCalcId() != null)
4201 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4206 // delete the auto calculated row from the alignment
4207 al.deleteAnnotation(jalan, false);
4211 if (valan != nullAnnot)
4213 if (jalan != valan.template)
4215 // newly created autoannotation row instance
4216 // so keep a reference to the visible annotation row
4217 // and copy over all relevant attributes
4218 if (valan.template.graphHeight >= 0)
4221 jalan.graphHeight = valan.template.graphHeight;
4223 jalan.visible = valan.template.visible;
4225 reorder.add(new JvAnnotRow(valan.order, jalan));
4230 // Add any (possibly stale) autocalculated rows that were not appended to
4231 // the view during construction
4232 for (String other : remains)
4234 JvAnnotRow othera = visan.get(other);
4235 if (othera != nullAnnot && othera.template.getCalcId() != null
4236 && othera.template.getCalcId().length() > 0)
4238 reorder.add(othera);
4241 // now put the automatic annotation in its correct place
4242 int s = 0, srt[] = new int[reorder.size()];
4243 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4244 for (JvAnnotRow jvar : reorder)
4247 srt[s++] = jvar.order;
4250 jalview.util.QuickSort.sort(srt, rws);
4251 // and re-insert the annotation at its correct position
4252 for (JvAnnotRow jvar : rws)
4254 al.addAnnotation(jvar.template, jvar.order);
4256 af.alignPanel.adjustAnnotationHeight();
4260 Hashtable skipList = null;
4263 * TODO remove this method
4266 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4267 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4268 * throw new Error("Implementation Error. No skipList defined for this
4269 * Jalview2XML instance."); } return (AlignFrame)
4270 * skipList.get(view.getSequenceSetId()); }
4274 * Check if the Jalview view contained in object should be skipped or not.
4277 * @return true if view's sequenceSetId is a key in skipList
4279 private boolean skipViewport(JalviewModel object)
4281 if (skipList == null)
4286 if (skipList.containsKey(id = object.getJalviewModelSequence()
4287 .getViewport()[0].getSequenceSetId()))
4289 if (Cache.log != null && Cache.log.isDebugEnabled())
4291 Cache.log.debug("Skipping seuqence set id " + id);
4298 public void addToSkipList(AlignFrame af)
4300 if (skipList == null)
4302 skipList = new Hashtable();
4304 skipList.put(af.getViewport().getSequenceSetId(), af);
4307 public void clearSkipList()
4309 if (skipList != null)
4316 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4317 boolean ignoreUnrefed)
4319 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4320 Vector dseqs = null;
4323 // create a list of new dataset sequences
4324 dseqs = new Vector();
4326 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4328 Sequence vamsasSeq = vamsasSet.getSequence(i);
4329 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4331 // create a new dataset
4334 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4335 dseqs.copyInto(dsseqs);
4336 ds = new jalview.datamodel.Alignment(dsseqs);
4337 debug("Created new dataset " + vamsasSet.getDatasetId()
4338 + " for alignment " + System.identityHashCode(al));
4339 addDatasetRef(vamsasSet.getDatasetId(), ds);
4341 // set the dataset for the newly imported alignment.
4342 if (al.getDataset() == null && !ignoreUnrefed)
4351 * sequence definition to create/merge dataset sequence for
4355 * vector to add new dataset sequence to
4357 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4358 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4360 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4362 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4363 SequenceI dsq = null;
4364 if (sq != null && sq.getDatasetSequence() != null)
4366 dsq = sq.getDatasetSequence();
4368 if (sq == null && ignoreUnrefed)
4372 String sqid = vamsasSeq.getDsseqid();
4375 // need to create or add a new dataset sequence reference to this sequence
4378 dsq = seqRefIds.get(sqid);
4383 // make a new dataset sequence
4384 dsq = sq.createDatasetSequence();
4387 // make up a new dataset reference for this sequence
4388 sqid = seqHash(dsq);
4390 dsq.setVamsasId(uniqueSetSuffix + sqid);
4391 seqRefIds.put(sqid, dsq);
4396 dseqs.addElement(dsq);
4401 ds.addSequence(dsq);
4407 { // make this dataset sequence sq's dataset sequence
4408 sq.setDatasetSequence(dsq);
4409 // and update the current dataset alignment
4414 if (!dseqs.contains(dsq))
4421 if (ds.findIndex(dsq) < 0)
4423 ds.addSequence(dsq);
4430 // TODO: refactor this as a merge dataset sequence function
4431 // now check that sq (the dataset sequence) sequence really is the union of
4432 // all references to it
4433 // boolean pre = sq.getStart() < dsq.getStart();
4434 // boolean post = sq.getEnd() > dsq.getEnd();
4438 // StringBuffer sb = new StringBuffer();
4439 String newres = jalview.analysis.AlignSeq.extractGaps(
4440 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4441 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4442 && newres.length() > dsq.getLength())
4444 // Update with the longer sequence.
4448 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4449 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4450 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4451 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4453 dsq.setSequence(newres);
4455 // TODO: merges will never happen if we 'know' we have the real dataset
4456 // sequence - this should be detected when id==dssid
4458 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4459 // + (pre ? "prepended" : "") + " "
4460 // + (post ? "appended" : ""));
4465 java.util.Hashtable datasetIds = null;
4467 java.util.IdentityHashMap dataset2Ids = null;
4469 private Alignment getDatasetFor(String datasetId)
4471 if (datasetIds == null)
4473 datasetIds = new Hashtable();
4476 if (datasetIds.containsKey(datasetId))
4478 return (Alignment) datasetIds.get(datasetId);
4483 private void addDatasetRef(String datasetId, Alignment dataset)
4485 if (datasetIds == null)
4487 datasetIds = new Hashtable();
4489 datasetIds.put(datasetId, dataset);
4493 * make a new dataset ID for this jalview dataset alignment
4498 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4500 if (dataset.getDataset() != null)
4502 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4504 String datasetId = makeHashCode(dataset, null);
4505 if (datasetId == null)
4507 // make a new datasetId and record it
4508 if (dataset2Ids == null)
4510 dataset2Ids = new IdentityHashMap();
4514 datasetId = (String) dataset2Ids.get(dataset);
4516 if (datasetId == null)
4518 datasetId = "ds" + dataset2Ids.size() + 1;
4519 dataset2Ids.put(dataset, datasetId);
4525 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4527 for (int d = 0; d < sequence.getDBRefCount(); d++)
4529 DBRef dr = sequence.getDBRef(d);
4530 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4531 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4532 .getVersion(), sequence.getDBRef(d).getAccessionId());
4533 if (dr.getMapping() != null)
4535 entry.setMap(addMapping(dr.getMapping()));
4537 datasetSequence.addDBRef(entry);
4541 private jalview.datamodel.Mapping addMapping(Mapping m)
4543 SequenceI dsto = null;
4544 // Mapping m = dr.getMapping();
4545 int fr[] = new int[m.getMapListFromCount() * 2];
4546 Enumeration f = m.enumerateMapListFrom();
4547 for (int _i = 0; f.hasMoreElements(); _i += 2)
4549 MapListFrom mf = (MapListFrom) f.nextElement();
4550 fr[_i] = mf.getStart();
4551 fr[_i + 1] = mf.getEnd();
4553 int fto[] = new int[m.getMapListToCount() * 2];
4554 f = m.enumerateMapListTo();
4555 for (int _i = 0; f.hasMoreElements(); _i += 2)
4557 MapListTo mf = (MapListTo) f.nextElement();
4558 fto[_i] = mf.getStart();
4559 fto[_i + 1] = mf.getEnd();
4561 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4562 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4563 if (m.getMappingChoice() != null)
4565 MappingChoice mc = m.getMappingChoice();
4566 if (mc.getDseqFor() != null)
4568 String dsfor = "" + mc.getDseqFor();
4569 if (seqRefIds.containsKey(dsfor))
4574 jmap.setTo(seqRefIds.get(dsfor));
4578 frefedSequence.add(new Object[]
4585 * local sequence definition
4587 Sequence ms = mc.getSequence();
4588 SequenceI djs = null;
4589 String sqid = ms.getDsseqid();
4590 if (sqid != null && sqid.length() > 0)
4593 * recover dataset sequence
4595 djs = seqRefIds.get(sqid);
4600 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4601 sqid = ((Object) ms).toString(); // make up a new hascode for
4602 // undefined dataset sequence hash
4603 // (unlikely to happen)
4609 * make a new dataset sequence and add it to refIds hash
4611 djs = new jalview.datamodel.Sequence(ms.getName(),
4613 djs.setStart(jmap.getMap().getToLowest());
4614 djs.setEnd(jmap.getMap().getToHighest());
4615 djs.setVamsasId(uniqueSetSuffix + sqid);
4617 seqRefIds.put(sqid, djs);
4620 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4629 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4630 boolean keepSeqRefs)
4633 jalview.schemabinding.version2.JalviewModel jm = saveState(ap, null,
4639 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4643 uniqueSetSuffix = "";
4644 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4649 if (this.frefedSequence == null)
4651 frefedSequence = new Vector();
4654 viewportsAdded.clear();
4656 AlignFrame af = loadFromObject(jm, null, false, null);
4657 af.alignPanels.clear();
4658 af.closeMenuItem_actionPerformed(true);
4661 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4662 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4663 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4664 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4665 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4668 return af.alignPanel;
4672 * flag indicating if hashtables should be cleared on finalization TODO this
4673 * flag may not be necessary
4675 private final boolean _cleartables = true;
4677 private Hashtable jvids2vobj;
4682 * @see java.lang.Object#finalize()
4685 protected void finalize() throws Throwable
4687 // really make sure we have no buried refs left.
4692 this.seqRefIds = null;
4693 this.seqsToIds = null;
4697 private void warn(String msg)
4702 private void warn(String msg, Exception e)
4704 if (Cache.log != null)
4708 Cache.log.warn(msg, e);
4712 Cache.log.warn(msg);
4717 System.err.println("Warning: " + msg);
4720 e.printStackTrace();
4725 private void debug(String string)
4727 debug(string, null);
4730 private void debug(String msg, Exception e)
4732 if (Cache.log != null)
4736 Cache.log.debug(msg, e);
4740 Cache.log.debug(msg);
4745 System.err.println("Warning: " + msg);
4748 e.printStackTrace();
4754 * set the object to ID mapping tables used to write/recover objects and XML
4755 * ID strings for the jalview project. If external tables are provided then
4756 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4757 * object goes out of scope. - also populates the datasetIds hashtable with
4758 * alignment objects containing dataset sequences
4761 * Map from ID strings to jalview datamodel
4763 * Map from jalview datamodel to ID strings
4767 public void setObjectMappingTables(Hashtable vobj2jv,
4768 IdentityHashMap jv2vobj)
4770 this.jv2vobj = jv2vobj;
4771 this.vobj2jv = vobj2jv;
4772 Iterator ds = jv2vobj.keySet().iterator();
4774 while (ds.hasNext())
4776 Object jvobj = ds.next();
4777 id = jv2vobj.get(jvobj).toString();
4778 if (jvobj instanceof jalview.datamodel.Alignment)
4780 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4782 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4785 else if (jvobj instanceof jalview.datamodel.Sequence)
4787 // register sequence object so the XML parser can recover it.
4788 if (seqRefIds == null)
4790 seqRefIds = new HashMap<String, SequenceI>();
4792 if (seqsToIds == null)
4794 seqsToIds = new IdentityHashMap<SequenceI, String>();
4796 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4797 seqsToIds.put((SequenceI) jvobj, id);
4799 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4802 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
4803 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
4804 if (jvann.annotationId == null)
4806 jvann.annotationId = anid;
4808 if (!jvann.annotationId.equals(anid))
4810 // TODO verify that this is the correct behaviour
4811 this.warn("Overriding Annotation ID for " + anid
4812 + " from different id : " + jvann.annotationId);
4813 jvann.annotationId = anid;
4816 else if (jvobj instanceof String)
4818 if (jvids2vobj == null)
4820 jvids2vobj = new Hashtable();
4821 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4826 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4832 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4833 * objects created from the project archive. If string is null (default for
4834 * construction) then suffix will be set automatically.
4838 public void setUniqueSetSuffix(String string)
4840 uniqueSetSuffix = string;
4845 * uses skipList2 as the skipList for skipping views on sequence sets
4846 * associated with keys in the skipList
4850 public void setSkipList(Hashtable skipList2)
4852 skipList = skipList2;