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 java.awt.Color;
24 import java.awt.Rectangle;
25 import java.io.BufferedReader;
26 import java.io.DataInputStream;
27 import java.io.DataOutputStream;
29 import java.io.FileInputStream;
30 import java.io.FileOutputStream;
31 import java.io.IOException;
32 import java.io.InputStreamReader;
33 import java.io.OutputStreamWriter;
34 import java.io.PrintWriter;
35 import java.lang.reflect.InvocationTargetException;
36 import java.net.MalformedURLException;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Enumeration;
41 import java.util.HashMap;
42 import java.util.HashSet;
43 import java.util.Hashtable;
44 import java.util.IdentityHashMap;
45 import java.util.Iterator;
46 import java.util.LinkedHashMap;
47 import java.util.List;
49 import java.util.Map.Entry;
51 import java.util.Vector;
52 import java.util.jar.JarEntry;
53 import java.util.jar.JarInputStream;
54 import java.util.jar.JarOutputStream;
56 import jalview.analysis.Conservation;
57 import jalview.api.FeatureColourI;
58 import jalview.api.ViewStyleI;
59 import jalview.api.structures.JalviewStructureDisplayI;
60 import jalview.bin.Cache;
61 import jalview.datamodel.AlignedCodonFrame;
62 import jalview.datamodel.Alignment;
63 import jalview.datamodel.AlignmentAnnotation;
64 import jalview.datamodel.AlignmentI;
65 import jalview.datamodel.GraphLine;
66 import jalview.datamodel.PDBEntry;
67 import jalview.datamodel.RnaViewerModel;
68 import jalview.datamodel.SequenceGroup;
69 import jalview.datamodel.SequenceI;
70 import jalview.datamodel.StructureViewerModel;
71 import jalview.datamodel.StructureViewerModel.StructureData;
72 import jalview.ext.varna.RnaModel;
73 import jalview.gui.StructureViewer.ViewerType;
74 import jalview.io.DataSourceType;
75 import jalview.io.FileFormat;
76 import jalview.schemabinding.version2.AlcodMap;
77 import jalview.schemabinding.version2.AlcodonFrame;
78 import jalview.schemabinding.version2.Annotation;
79 import jalview.schemabinding.version2.AnnotationColours;
80 import jalview.schemabinding.version2.AnnotationElement;
81 import jalview.schemabinding.version2.CalcIdParam;
82 import jalview.schemabinding.version2.DBRef;
83 import jalview.schemabinding.version2.Features;
84 import jalview.schemabinding.version2.Group;
85 import jalview.schemabinding.version2.HiddenColumns;
86 import jalview.schemabinding.version2.JGroup;
87 import jalview.schemabinding.version2.JSeq;
88 import jalview.schemabinding.version2.JalviewModel;
89 import jalview.schemabinding.version2.JalviewModelSequence;
90 import jalview.schemabinding.version2.MapListFrom;
91 import jalview.schemabinding.version2.MapListTo;
92 import jalview.schemabinding.version2.Mapping;
93 import jalview.schemabinding.version2.MappingChoice;
94 import jalview.schemabinding.version2.OtherData;
95 import jalview.schemabinding.version2.PdbentryItem;
96 import jalview.schemabinding.version2.Pdbids;
97 import jalview.schemabinding.version2.Property;
98 import jalview.schemabinding.version2.RnaViewer;
99 import jalview.schemabinding.version2.SecondaryStructure;
100 import jalview.schemabinding.version2.Sequence;
101 import jalview.schemabinding.version2.SequenceSet;
102 import jalview.schemabinding.version2.SequenceSetProperties;
103 import jalview.schemabinding.version2.Setting;
104 import jalview.schemabinding.version2.StructureState;
105 import jalview.schemabinding.version2.ThresholdLine;
106 import jalview.schemabinding.version2.Tree;
107 import jalview.schemabinding.version2.UserColours;
108 import jalview.schemabinding.version2.Viewport;
109 import jalview.schemes.AnnotationColourGradient;
110 import jalview.schemes.ColourSchemeI;
111 import jalview.schemes.ColourSchemeProperty;
112 import jalview.schemes.FeatureColour;
113 import jalview.schemes.ResidueColourScheme;
114 import jalview.schemes.ResidueProperties;
115 import jalview.schemes.UserColourScheme;
116 import jalview.structure.StructureSelectionManager;
117 import jalview.structures.models.AAStructureBindingModel;
118 import jalview.util.MessageManager;
119 import jalview.util.Platform;
120 import jalview.util.StringUtils;
121 import jalview.util.jarInputStreamProvider;
122 import jalview.viewmodel.AlignmentViewport;
123 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
124 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
125 import jalview.ws.jws2.Jws2Discoverer;
126 import jalview.ws.jws2.dm.AAConSettings;
127 import jalview.ws.jws2.jabaws2.Jws2Instance;
128 import jalview.ws.params.ArgumentI;
129 import jalview.ws.params.AutoCalcSetting;
130 import jalview.ws.params.WsParamSetI;
132 import javax.swing.JInternalFrame;
133 import javax.swing.SwingUtilities;
135 import org.exolab.castor.xml.Marshaller;
136 import org.exolab.castor.xml.Unmarshaller;
139 * Write out the current jalview desktop state as a Jalview XML stream.
141 * Note: the vamsas objects referred to here are primitive versions of the
142 * VAMSAS project schema elements - they are not the same and most likely never
146 * @version $Revision: 1.134 $
148 public class Jalview2XML
150 private static final String VIEWER_PREFIX = "viewer_";
152 private static final String RNA_PREFIX = "rna_";
154 private static final String UTF_8 = "UTF-8";
156 // use this with nextCounter() to make unique names for entities
157 private int counter = 0;
160 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
161 * of sequence objects are created.
163 IdentityHashMap<SequenceI, String> seqsToIds = null;
166 * jalview XML Sequence ID to jalview sequence object reference (both dataset
167 * and alignment sequences. Populated as XML reps of sequence objects are
170 Map<String, SequenceI> seqRefIds = null;
172 Map<String, SequenceI> incompleteSeqs = null;
174 List<SeqFref> frefedSequence = null;
176 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
179 * Map of reconstructed AlignFrame objects that appear to have come from
180 * SplitFrame objects (have a dna/protein complement view).
182 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
185 * Map from displayed rna structure models to their saved session state jar
188 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
191 * create/return unique hash string for sq
194 * @return new or existing unique string for sq
196 String seqHash(SequenceI sq)
198 if (seqsToIds == null)
202 if (seqsToIds.containsKey(sq))
204 return seqsToIds.get(sq);
208 // create sequential key
209 String key = "sq" + (seqsToIds.size() + 1);
210 key = makeHashCode(sq, key); // check we don't have an external reference
212 seqsToIds.put(sq, key);
221 if (seqRefIds != null)
225 if (seqsToIds != null)
229 if (incompleteSeqs != null)
231 incompleteSeqs.clear();
239 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
240 // seqRefIds = new Hashtable();
241 // seqsToIds = new IdentityHashMap();
247 if (seqsToIds == null)
249 seqsToIds = new IdentityHashMap<SequenceI, String>();
251 if (seqRefIds == null)
253 seqRefIds = new HashMap<String, SequenceI>();
255 if (incompleteSeqs == null)
257 incompleteSeqs = new HashMap<String, SequenceI>();
259 if (frefedSequence == null)
261 frefedSequence = new ArrayList<SeqFref>();
269 public Jalview2XML(boolean raiseGUI)
271 this.raiseGUI = raiseGUI;
275 * base class for resolving forward references to sequences by their ID
280 abstract class SeqFref
286 public SeqFref(String _sref, String type)
292 public String getSref()
297 public SequenceI getSrefSeq()
299 return seqRefIds.get(sref);
302 public boolean isResolvable()
304 return seqRefIds.get(sref) != null;
307 public SequenceI getSrefDatasetSeq()
309 SequenceI sq = seqRefIds.get(sref);
312 while (sq.getDatasetSequence() != null)
314 sq = sq.getDatasetSequence();
321 * @return true if the forward reference was fully resolved
323 abstract boolean resolve();
326 public String toString()
328 return type + " reference to " + sref;
333 * create forward reference for a mapping
339 public SeqFref newMappingRef(final String sref,
340 final jalview.datamodel.Mapping _jmap)
342 SeqFref fref = new SeqFref(sref, "Mapping")
344 public jalview.datamodel.Mapping jmap = _jmap;
349 SequenceI seq = getSrefDatasetSeq();
361 public SeqFref newAlcodMapRef(final String sref,
362 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
365 SeqFref fref = new SeqFref(sref, "Codon Frame")
367 AlignedCodonFrame cf = _cf;
369 public jalview.datamodel.Mapping mp = _jmap;
372 public boolean isResolvable()
374 return super.isResolvable() && mp.getTo() != null;
380 SequenceI seq = getSrefDatasetSeq();
385 cf.addMap(seq, mp.getTo(), mp.getMap());
392 public void resolveFrefedSequences()
394 Iterator<SeqFref> nextFref = frefedSequence.iterator();
395 int toresolve = frefedSequence.size();
396 int unresolved = 0, failedtoresolve = 0;
397 while (nextFref.hasNext())
399 SeqFref ref = nextFref.next();
400 if (ref.isResolvable())
412 } catch (Exception x)
415 .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
428 System.err.println("Jalview Project Import: There were " + unresolved
429 + " forward references left unresolved on the stack.");
431 if (failedtoresolve > 0)
433 System.err.println("SERIOUS! " + failedtoresolve
434 + " resolvable forward references failed to resolve.");
436 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
438 System.err.println("Jalview Project Import: There are "
439 + incompleteSeqs.size()
440 + " sequences which may have incomplete metadata.");
441 if (incompleteSeqs.size() < 10)
443 for (SequenceI s : incompleteSeqs.values())
445 System.err.println(s.toString());
451 .println("Too many to report. Skipping output of incomplete sequences.");
457 * This maintains a map of viewports, the key being the seqSetId. Important to
458 * set historyItem and redoList for multiple views
460 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
462 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
464 String uniqueSetSuffix = "";
467 * List of pdbfiles added to Jar
469 List<String> pdbfiles = null;
471 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
472 public void saveState(File statefile)
474 FileOutputStream fos = null;
477 fos = new FileOutputStream(statefile);
478 JarOutputStream jout = new JarOutputStream(fos);
481 } catch (Exception e)
483 // TODO: inform user of the problem - they need to know if their data was
485 if (errorMessage == null)
487 errorMessage = "Couldn't write Jalview Archive to output file '"
488 + statefile + "' - See console error log for details";
492 errorMessage += "(output file was '" + statefile + "')";
502 } catch (IOException e)
512 * Writes a jalview project archive to the given Jar output stream.
516 public void saveState(JarOutputStream jout)
518 AlignFrame[] frames = Desktop.getAlignFrames();
524 saveAllFrames(Arrays.asList(frames), jout);
528 * core method for storing state for a set of AlignFrames.
531 * - frames involving all data to be exported (including containing
534 * - project output stream
536 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
538 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
541 * ensure cached data is clear before starting
543 // todo tidy up seqRefIds, seqsToIds initialisation / reset
545 splitFrameCandidates.clear();
550 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
551 // //////////////////////////////////////////////////
553 List<String> shortNames = new ArrayList<String>();
554 List<String> viewIds = new ArrayList<String>();
557 for (int i = frames.size() - 1; i > -1; i--)
559 AlignFrame af = frames.get(i);
563 .containsKey(af.getViewport().getSequenceSetId()))
568 String shortName = makeFilename(af, shortNames);
570 int ap, apSize = af.alignPanels.size();
572 for (ap = 0; ap < apSize; ap++)
574 AlignmentPanel apanel = af.alignPanels.get(ap);
575 String fileName = apSize == 1 ? shortName : ap + shortName;
576 if (!fileName.endsWith(".xml"))
578 fileName = fileName + ".xml";
581 saveState(apanel, fileName, jout, viewIds);
583 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
585 if (!dsses.containsKey(dssid))
587 dsses.put(dssid, af);
592 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
598 } catch (Exception foo)
603 } catch (Exception ex)
605 // TODO: inform user of the problem - they need to know if their data was
607 if (errorMessage == null)
609 errorMessage = "Couldn't write Jalview Archive - see error output for details";
611 ex.printStackTrace();
616 * Generates a distinct file name, based on the title of the AlignFrame, by
617 * appending _n for increasing n until an unused name is generated. The new
618 * name (without its extension) is added to the list.
622 * @return the generated name, with .xml extension
624 protected String makeFilename(AlignFrame af, List<String> namesUsed)
626 String shortName = af.getTitle();
628 if (shortName.indexOf(File.separatorChar) > -1)
630 shortName = shortName.substring(shortName
631 .lastIndexOf(File.separatorChar) + 1);
636 while (namesUsed.contains(shortName))
638 if (shortName.endsWith("_" + (count - 1)))
640 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
643 shortName = shortName.concat("_" + count);
647 namesUsed.add(shortName);
649 if (!shortName.endsWith(".xml"))
651 shortName = shortName + ".xml";
656 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
657 public boolean saveAlignment(AlignFrame af, String jarFile,
662 FileOutputStream fos = new FileOutputStream(jarFile);
663 JarOutputStream jout = new JarOutputStream(fos);
664 List<AlignFrame> frames = new ArrayList<AlignFrame>();
666 // resolve splitframes
667 if (af.getViewport().getCodingComplement() != null)
669 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
675 saveAllFrames(frames, jout);
679 } catch (Exception foo)
685 } catch (Exception ex)
687 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
688 ex.printStackTrace();
693 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
694 String fileName, JarOutputStream jout)
697 for (String dssids : dsses.keySet())
699 AlignFrame _af = dsses.get(dssids);
700 String jfileName = fileName + " Dataset for " + _af.getTitle();
701 if (!jfileName.endsWith(".xml"))
703 jfileName = jfileName + ".xml";
705 saveState(_af.alignPanel, jfileName, true, jout, null);
710 * create a JalviewModel from an alignment view and marshall it to a
714 * panel to create jalview model for
716 * name of alignment panel written to output stream
723 public JalviewModel saveState(AlignmentPanel ap, String fileName,
724 JarOutputStream jout, List<String> viewIds)
726 return saveState(ap, fileName, false, jout, viewIds);
730 * create a JalviewModel from an alignment view and marshall it to a
734 * panel to create jalview model for
736 * name of alignment panel written to output stream
738 * when true, only write the dataset for the alignment, not the data
739 * associated with the view.
745 public JalviewModel saveState(AlignmentPanel ap, String fileName,
746 boolean storeDS, JarOutputStream jout, List<String> viewIds)
750 viewIds = new ArrayList<String>();
755 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
757 AlignViewport av = ap.av;
759 JalviewModel object = new JalviewModel();
760 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
762 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
763 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
764 "Development Build"));
767 * rjal is full height alignment, jal is actual alignment with full metadata
768 * but excludes hidden sequences.
770 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
772 if (av.hasHiddenRows())
774 rjal = jal.getHiddenSequences().getFullAlignment();
777 SequenceSet vamsasSet = new SequenceSet();
779 JalviewModelSequence jms = new JalviewModelSequence();
781 vamsasSet.setGapChar(jal.getGapCharacter() + "");
783 if (jal.getDataset() != null)
785 // dataset id is the dataset's hashcode
786 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
789 // switch jal and the dataset
790 jal = jal.getDataset();
794 if (jal.getProperties() != null)
796 Enumeration en = jal.getProperties().keys();
797 while (en.hasMoreElements())
799 String key = en.nextElement().toString();
800 SequenceSetProperties ssp = new SequenceSetProperties();
802 ssp.setValue(jal.getProperties().get(key).toString());
803 vamsasSet.addSequenceSetProperties(ssp);
808 Set<String> calcIdSet = new HashSet<String>();
809 // record the set of vamsas sequence XML POJO we create.
810 HashMap<String, Sequence> vamsasSetIds = new HashMap<String, Sequence>();
812 for (final SequenceI jds : rjal.getSequences())
814 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
815 : jds.getDatasetSequence();
816 String id = seqHash(jds);
817 if (vamsasSetIds.get(id) == null)
819 if (seqRefIds.get(id) != null && !storeDS)
821 // This happens for two reasons: 1. multiple views are being
823 // 2. the hashCode has collided with another sequence's code. This
825 // HAPPEN! (PF00072.15.stk does this)
826 // JBPNote: Uncomment to debug writing out of files that do not read
827 // back in due to ArrayOutOfBoundExceptions.
828 // System.err.println("vamsasSeq backref: "+id+"");
829 // System.err.println(jds.getName()+"
830 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
831 // System.err.println("Hashcode: "+seqHash(jds));
832 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
833 // System.err.println(rsq.getName()+"
834 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
835 // System.err.println("Hashcode: "+seqHash(rsq));
839 vamsasSeq = createVamsasSequence(id, jds);
840 vamsasSet.addSequence(vamsasSeq);
841 vamsasSetIds.put(id, vamsasSeq);
842 seqRefIds.put(id, jds);
846 jseq.setStart(jds.getStart());
847 jseq.setEnd(jds.getEnd());
848 jseq.setColour(av.getSequenceColour(jds).getRGB());
850 jseq.setId(id); // jseq id should be a string not a number
853 // Store any sequences this sequence represents
854 if (av.hasHiddenRows())
856 // use rjal, contains the full height alignment
857 jseq.setHidden(av.getAlignment().getHiddenSequences()
860 if (av.isHiddenRepSequence(jds))
862 jalview.datamodel.SequenceI[] reps = av
863 .getRepresentedSequences(jds).getSequencesInOrder(rjal);
865 for (int h = 0; h < reps.length; h++)
869 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
874 // mark sequence as reference - if it is the reference for this view
877 jseq.setViewreference(jds == jal.getSeqrep());
881 // TODO: omit sequence features from each alignment view's XML dump if we
882 // are storing dataset
883 if (jds.getSequenceFeatures() != null)
885 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
887 while (index < sf.length)
889 Features features = new Features();
891 features.setBegin(sf[index].getBegin());
892 features.setEnd(sf[index].getEnd());
893 features.setDescription(sf[index].getDescription());
894 features.setType(sf[index].getType());
895 features.setFeatureGroup(sf[index].getFeatureGroup());
896 features.setScore(sf[index].getScore());
897 if (sf[index].links != null)
899 for (int l = 0; l < sf[index].links.size(); l++)
901 OtherData keyValue = new OtherData();
902 keyValue.setKey("LINK_" + l);
903 keyValue.setValue(sf[index].links.elementAt(l).toString());
904 features.addOtherData(keyValue);
907 if (sf[index].otherDetails != null)
910 Iterator<String> keys = sf[index].otherDetails.keySet()
912 while (keys.hasNext())
915 OtherData keyValue = new OtherData();
916 keyValue.setKey(key);
917 keyValue.setValue(sf[index].otherDetails.get(key).toString());
918 features.addOtherData(keyValue);
922 jseq.addFeatures(features);
927 if (jdatasq.getAllPDBEntries() != null)
929 Enumeration en = jdatasq.getAllPDBEntries().elements();
930 while (en.hasMoreElements())
932 Pdbids pdb = new Pdbids();
933 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
936 String pdbId = entry.getId();
938 pdb.setType(entry.getType());
941 * Store any structure views associated with this sequence. This
942 * section copes with duplicate entries in the project, so a dataset
943 * only view *should* be coped with sensibly.
945 // This must have been loaded, is it still visible?
946 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
947 String matchedFile = null;
948 for (int f = frames.length - 1; f > -1; f--)
950 if (frames[f] instanceof StructureViewerBase)
952 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
953 matchedFile = saveStructureState(ap, jds, pdb, entry,
954 viewIds, matchedFile, viewFrame);
956 * Only store each structure viewer's state once in the project
957 * jar. First time through only (storeDS==false)
959 String viewId = viewFrame.getViewId();
960 if (!storeDS && !viewIds.contains(viewId))
965 String viewerState = viewFrame.getStateInfo();
966 writeJarEntry(jout, getViewerJarEntryName(viewId),
967 viewerState.getBytes());
968 } catch (IOException e)
970 System.err.println("Error saving viewer state: "
977 if (matchedFile != null || entry.getFile() != null)
979 if (entry.getFile() != null)
982 matchedFile = entry.getFile();
984 pdb.setFile(matchedFile); // entry.getFile());
985 if (pdbfiles == null)
987 pdbfiles = new ArrayList<String>();
990 if (!pdbfiles.contains(pdbId))
993 copyFileToJar(jout, matchedFile, pdbId);
997 Enumeration<String> props = entry.getProperties();
998 if (props.hasMoreElements())
1000 PdbentryItem item = new PdbentryItem();
1001 while (props.hasMoreElements())
1003 Property prop = new Property();
1004 String key = props.nextElement();
1006 prop.setValue(entry.getProperty(key).toString());
1007 item.addProperty(prop);
1009 pdb.addPdbentryItem(item);
1012 jseq.addPdbids(pdb);
1016 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1021 if (!storeDS && av.hasHiddenRows())
1023 jal = av.getAlignment();
1027 if (storeDS && jal.getCodonFrames() != null)
1029 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1030 for (AlignedCodonFrame acf : jac)
1032 AlcodonFrame alc = new AlcodonFrame();
1033 if (acf.getProtMappings() != null
1034 && acf.getProtMappings().length > 0)
1036 boolean hasMap = false;
1037 SequenceI[] dnas = acf.getdnaSeqs();
1038 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1039 for (int m = 0; m < pmaps.length; m++)
1041 AlcodMap alcmap = new AlcodMap();
1042 alcmap.setDnasq(seqHash(dnas[m]));
1043 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1045 alc.addAlcodMap(alcmap);
1050 vamsasSet.addAlcodonFrame(alc);
1053 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1055 // AlcodonFrame alc = new AlcodonFrame();
1056 // vamsasSet.addAlcodonFrame(alc);
1057 // for (int p = 0; p < acf.aaWidth; p++)
1059 // Alcodon cmap = new Alcodon();
1060 // if (acf.codons[p] != null)
1062 // // Null codons indicate a gapped column in the translated peptide
1064 // cmap.setPos1(acf.codons[p][0]);
1065 // cmap.setPos2(acf.codons[p][1]);
1066 // cmap.setPos3(acf.codons[p][2]);
1068 // alc.addAlcodon(cmap);
1070 // if (acf.getProtMappings() != null
1071 // && acf.getProtMappings().length > 0)
1073 // SequenceI[] dnas = acf.getdnaSeqs();
1074 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1075 // for (int m = 0; m < pmaps.length; m++)
1077 // AlcodMap alcmap = new AlcodMap();
1078 // alcmap.setDnasq(seqHash(dnas[m]));
1079 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1081 // alc.addAlcodMap(alcmap);
1088 // /////////////////////////////////
1089 if (!storeDS && av.currentTree != null)
1091 // FIND ANY ASSOCIATED TREES
1092 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1093 if (Desktop.desktop != null)
1095 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1097 for (int t = 0; t < frames.length; t++)
1099 if (frames[t] instanceof TreePanel)
1101 TreePanel tp = (TreePanel) frames[t];
1103 if (tp.treeCanvas.av.getAlignment() == jal)
1105 Tree tree = new Tree();
1106 tree.setTitle(tp.getTitle());
1107 tree.setCurrentTree((av.currentTree == tp.getTree()));
1108 tree.setNewick(tp.getTree().toString());
1109 tree.setThreshold(tp.treeCanvas.threshold);
1111 tree.setFitToWindow(tp.fitToWindow.getState());
1112 tree.setFontName(tp.getTreeFont().getName());
1113 tree.setFontSize(tp.getTreeFont().getSize());
1114 tree.setFontStyle(tp.getTreeFont().getStyle());
1115 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1117 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1118 tree.setShowDistances(tp.distanceMenu.getState());
1120 tree.setHeight(tp.getHeight());
1121 tree.setWidth(tp.getWidth());
1122 tree.setXpos(tp.getX());
1123 tree.setYpos(tp.getY());
1124 tree.setId(makeHashCode(tp, null));
1134 * store forward refs from an annotationRow to any groups
1136 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1139 for (SequenceI sq : jal.getSequences())
1141 // Store annotation on dataset sequences only
1142 AlignmentAnnotation[] aa = sq.getAnnotation();
1143 if (aa != null && aa.length > 0)
1145 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1152 if (jal.getAlignmentAnnotation() != null)
1154 // Store the annotation shown on the alignment.
1155 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1156 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1161 if (jal.getGroups() != null)
1163 JGroup[] groups = new JGroup[jal.getGroups().size()];
1165 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1167 JGroup jGroup = new JGroup();
1168 groups[++i] = jGroup;
1170 jGroup.setStart(sg.getStartRes());
1171 jGroup.setEnd(sg.getEndRes());
1172 jGroup.setName(sg.getName());
1173 if (groupRefs.containsKey(sg))
1175 // group has references so set its ID field
1176 jGroup.setId(groupRefs.get(sg));
1180 if (sg.cs.conservationApplied())
1182 jGroup.setConsThreshold(sg.cs.getConservationInc());
1184 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1186 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1190 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1193 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1195 jGroup.setColour("AnnotationColourGradient");
1196 jGroup.setAnnotationColours(constructAnnotationColours(
1197 (jalview.schemes.AnnotationColourGradient) sg.cs,
1200 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1202 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1206 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1209 jGroup.setPidThreshold(sg.cs.getThreshold());
1212 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1213 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1214 jGroup.setDisplayText(sg.getDisplayText());
1215 jGroup.setColourText(sg.getColourText());
1216 jGroup.setTextCol1(sg.textColour.getRGB());
1217 jGroup.setTextCol2(sg.textColour2.getRGB());
1218 jGroup.setTextColThreshold(sg.thresholdTextColour);
1219 jGroup.setShowUnconserved(sg.getShowNonconserved());
1220 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1221 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1222 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1223 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1224 for (SequenceI seq : sg.getSequences())
1226 jGroup.addSeq(seqHash(seq));
1230 jms.setJGroup(groups);
1234 // /////////SAVE VIEWPORT
1235 Viewport view = new Viewport();
1236 view.setTitle(ap.alignFrame.getTitle());
1237 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1238 av.getSequenceSetId()));
1239 view.setId(av.getViewId());
1240 if (av.getCodingComplement() != null)
1242 view.setComplementId(av.getCodingComplement().getViewId());
1244 view.setViewName(av.viewName);
1245 view.setGatheredViews(av.isGatherViewsHere());
1247 Rectangle size = ap.av.getExplodedGeometry();
1248 Rectangle position = size;
1251 size = ap.alignFrame.getBounds();
1252 if (av.getCodingComplement() != null)
1254 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1262 view.setXpos(position.x);
1263 view.setYpos(position.y);
1265 view.setWidth(size.width);
1266 view.setHeight(size.height);
1268 view.setStartRes(av.startRes);
1269 view.setStartSeq(av.startSeq);
1271 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1273 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1276 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1278 AnnotationColours ac = constructAnnotationColours(
1279 (jalview.schemes.AnnotationColourGradient) av
1280 .getGlobalColourScheme(),
1283 view.setAnnotationColours(ac);
1284 view.setBgColour("AnnotationColourGradient");
1288 view.setBgColour(ColourSchemeProperty.getColourName(av
1289 .getGlobalColourScheme()));
1292 ColourSchemeI cs = av.getGlobalColourScheme();
1296 if (cs.conservationApplied())
1298 view.setConsThreshold(cs.getConservationInc());
1299 if (cs instanceof jalview.schemes.UserColourScheme)
1301 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1305 if (cs instanceof ResidueColourScheme)
1307 view.setPidThreshold(cs.getThreshold());
1311 view.setConservationSelected(av.getConservationSelected());
1312 view.setPidSelected(av.getAbovePIDThreshold());
1313 view.setFontName(av.font.getName());
1314 view.setFontSize(av.font.getSize());
1315 view.setFontStyle(av.font.getStyle());
1316 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1317 view.setRenderGaps(av.isRenderGaps());
1318 view.setShowAnnotation(av.isShowAnnotation());
1319 view.setShowBoxes(av.getShowBoxes());
1320 view.setShowColourText(av.getColourText());
1321 view.setShowFullId(av.getShowJVSuffix());
1322 view.setRightAlignIds(av.isRightAlignIds());
1323 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1324 view.setShowText(av.getShowText());
1325 view.setShowUnconserved(av.getShowUnconserved());
1326 view.setWrapAlignment(av.getWrapAlignment());
1327 view.setTextCol1(av.getTextColour().getRGB());
1328 view.setTextCol2(av.getTextColour2().getRGB());
1329 view.setTextColThreshold(av.getThresholdTextColour());
1330 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1331 view.setShowSequenceLogo(av.isShowSequenceLogo());
1332 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1333 view.setShowGroupConsensus(av.isShowGroupConsensus());
1334 view.setShowGroupConservation(av.isShowGroupConservation());
1335 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1336 view.setShowDbRefTooltip(av.isShowDBRefs());
1337 view.setFollowHighlight(av.isFollowHighlight());
1338 view.setFollowSelection(av.followSelection);
1339 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1340 if (av.getFeaturesDisplayed() != null)
1342 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1344 String[] renderOrder = ap.getSeqPanel().seqCanvas
1345 .getFeatureRenderer().getRenderOrder()
1346 .toArray(new String[0]);
1348 Vector<String> settingsAdded = new Vector<String>();
1349 if (renderOrder != null)
1351 for (String featureType : renderOrder)
1353 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1354 .getFeatureRenderer().getFeatureStyle(featureType);
1355 Setting setting = new Setting();
1356 setting.setType(featureType);
1357 if (!fcol.isSimpleColour())
1359 setting.setColour(fcol.getMaxColour().getRGB());
1360 setting.setMincolour(fcol.getMinColour().getRGB());
1361 setting.setMin(fcol.getMin());
1362 setting.setMax(fcol.getMax());
1363 setting.setColourByLabel(fcol.isColourByLabel());
1364 setting.setAutoScale(fcol.isAutoScaled());
1365 setting.setThreshold(fcol.getThreshold());
1366 // -1 = No threshold, 0 = Below, 1 = Above
1367 setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
1368 .isBelowThreshold() ? 0 : -1));
1372 setting.setColour(fcol.getColour().getRGB());
1375 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1377 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1378 .getOrder(featureType);
1381 setting.setOrder(rorder);
1383 fs.addSetting(setting);
1384 settingsAdded.addElement(featureType);
1388 // is groups actually supposed to be a map here ?
1389 Iterator<String> en = ap.getSeqPanel().seqCanvas
1390 .getFeatureRenderer().getFeatureGroups().iterator();
1391 Vector<String> groupsAdded = new Vector<String>();
1392 while (en.hasNext())
1394 String grp = en.next();
1395 if (groupsAdded.contains(grp))
1399 Group g = new Group();
1401 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1402 .getFeatureRenderer().checkGroupVisibility(grp, false))
1405 groupsAdded.addElement(grp);
1407 jms.setFeatureSettings(fs);
1410 if (av.hasHiddenColumns())
1412 if (av.getColumnSelection() == null
1413 || av.getColumnSelection().getHiddenColumns() == null)
1415 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1419 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1422 int[] region = av.getColumnSelection().getHiddenColumns()
1424 HiddenColumns hc = new HiddenColumns();
1425 hc.setStart(region[0]);
1426 hc.setEnd(region[1]);
1427 view.addHiddenColumns(hc);
1431 if (calcIdSet.size() > 0)
1433 for (String calcId : calcIdSet)
1435 if (calcId.trim().length() > 0)
1437 CalcIdParam cidp = createCalcIdParam(calcId, av);
1438 // Some calcIds have no parameters.
1441 view.addCalcIdParam(cidp);
1447 jms.addViewport(view);
1449 object.setJalviewModelSequence(jms);
1450 object.getVamsasModel().addSequenceSet(vamsasSet);
1452 if (jout != null && fileName != null)
1454 // We may not want to write the object to disk,
1455 // eg we can copy the alignViewport to a new view object
1456 // using save and then load
1459 System.out.println("Writing jar entry " + fileName);
1460 JarEntry entry = new JarEntry(fileName);
1461 jout.putNextEntry(entry);
1462 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1464 Marshaller marshaller = new Marshaller(pout);
1465 marshaller.marshal(object);
1468 } catch (Exception ex)
1470 // TODO: raise error in GUI if marshalling failed.
1471 ex.printStackTrace();
1478 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1479 * for each viewer, with
1481 * <li>viewer geometry (position, size, split pane divider location)</li>
1482 * <li>index of the selected structure in the viewer (currently shows gapped
1484 * <li>the id of the annotation holding RNA secondary structure</li>
1485 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1487 * Varna viewer state is also written out (in native Varna XML) to separate
1488 * project jar entries. A separate entry is written for each RNA structure
1489 * displayed, with the naming convention
1491 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1499 * @param storeDataset
1501 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1502 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1503 boolean storeDataset)
1505 if (Desktop.desktop == null)
1509 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1510 for (int f = frames.length - 1; f > -1; f--)
1512 if (frames[f] instanceof AppVarna)
1514 AppVarna varna = (AppVarna) frames[f];
1516 * link the sequence to every viewer that is showing it and is linked to
1517 * its alignment panel
1519 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1521 String viewId = varna.getViewId();
1522 RnaViewer rna = new RnaViewer();
1523 rna.setViewId(viewId);
1524 rna.setTitle(varna.getTitle());
1525 rna.setXpos(varna.getX());
1526 rna.setYpos(varna.getY());
1527 rna.setWidth(varna.getWidth());
1528 rna.setHeight(varna.getHeight());
1529 rna.setDividerLocation(varna.getDividerLocation());
1530 rna.setSelectedRna(varna.getSelectedIndex());
1531 jseq.addRnaViewer(rna);
1534 * Store each Varna panel's state once in the project per sequence.
1535 * First time through only (storeDataset==false)
1537 // boolean storeSessions = false;
1538 // String sequenceViewId = viewId + seqsToIds.get(jds);
1539 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1541 // viewIds.add(sequenceViewId);
1542 // storeSessions = true;
1544 for (RnaModel model : varna.getModels())
1546 if (model.seq == jds)
1549 * VARNA saves each view (sequence or alignment secondary
1550 * structure, gapped or trimmed) as a separate XML file
1552 String jarEntryName = rnaSessions.get(model);
1553 if (jarEntryName == null)
1556 String varnaStateFile = varna.getStateInfo(model.rna);
1557 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1558 copyFileToJar(jout, varnaStateFile, jarEntryName);
1559 rnaSessions.put(model, jarEntryName);
1561 SecondaryStructure ss = new SecondaryStructure();
1562 String annotationId = varna.getAnnotation(jds).annotationId;
1563 ss.setAnnotationId(annotationId);
1564 ss.setViewerState(jarEntryName);
1565 ss.setGapped(model.gapped);
1566 ss.setTitle(model.title);
1567 rna.addSecondaryStructure(ss);
1576 * Copy the contents of a file to a new entry added to the output jar
1580 * @param jarEntryName
1582 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1583 String jarEntryName)
1585 DataInputStream dis = null;
1588 File file = new File(infilePath);
1589 if (file.exists() && jout != null)
1591 dis = new DataInputStream(new FileInputStream(file));
1592 byte[] data = new byte[(int) file.length()];
1593 dis.readFully(data);
1594 writeJarEntry(jout, jarEntryName, data);
1596 } catch (Exception ex)
1598 ex.printStackTrace();
1606 } catch (IOException e)
1615 * Write the data to a new entry of given name in the output jar file
1618 * @param jarEntryName
1620 * @throws IOException
1622 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1623 byte[] data) throws IOException
1627 System.out.println("Writing jar entry " + jarEntryName);
1628 jout.putNextEntry(new JarEntry(jarEntryName));
1629 DataOutputStream dout = new DataOutputStream(jout);
1630 dout.write(data, 0, data.length);
1637 * Save the state of a structure viewer
1642 * the archive XML element under which to save the state
1645 * @param matchedFile
1649 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1650 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1651 String matchedFile, StructureViewerBase viewFrame)
1653 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1656 * Look for any bindings for this viewer to the PDB file of interest
1657 * (including part matches excluding chain id)
1659 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1661 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1662 final String pdbId = pdbentry.getId();
1663 if (!pdbId.equals(entry.getId())
1664 && !(entry.getId().length() > 4 && entry.getId()
1665 .toLowerCase().startsWith(pdbId.toLowerCase())))
1668 * not interested in a binding to a different PDB entry here
1672 if (matchedFile == null)
1674 matchedFile = pdbentry.getFile();
1676 else if (!matchedFile.equals(pdbentry.getFile()))
1679 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1680 + pdbentry.getFile());
1684 // can get at it if the ID
1685 // match is ambiguous (e.g.
1688 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1690 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1691 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1693 StructureState state = new StructureState();
1694 state.setVisible(true);
1695 state.setXpos(viewFrame.getX());
1696 state.setYpos(viewFrame.getY());
1697 state.setWidth(viewFrame.getWidth());
1698 state.setHeight(viewFrame.getHeight());
1699 final String viewId = viewFrame.getViewId();
1700 state.setViewId(viewId);
1701 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1702 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1703 state.setColourByJmol(viewFrame.isColouredByViewer());
1704 state.setType(viewFrame.getViewerType().toString());
1705 pdb.addStructureState(state);
1712 private AnnotationColours constructAnnotationColours(
1713 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1714 JalviewModelSequence jms)
1716 AnnotationColours ac = new AnnotationColours();
1717 ac.setAboveThreshold(acg.getAboveThreshold());
1718 ac.setThreshold(acg.getAnnotationThreshold());
1719 // 2.10.2 save annotationId (unique) not annotation label
1720 ac.setAnnotation(acg.getAnnotation().annotationId);
1721 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1723 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1728 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1732 ac.setMaxColour(acg.getMaxColour().getRGB());
1733 ac.setMinColour(acg.getMinColour().getRGB());
1734 ac.setPerSequence(acg.isSeqAssociated());
1735 ac.setPredefinedColours(acg.isPredefinedColours());
1739 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1740 IdentityHashMap<SequenceGroup, String> groupRefs,
1741 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1742 SequenceSet vamsasSet)
1745 for (int i = 0; i < aa.length; i++)
1747 Annotation an = new Annotation();
1749 AlignmentAnnotation annotation = aa[i];
1750 if (annotation.annotationId != null)
1752 annotationIds.put(annotation.annotationId, annotation);
1755 an.setId(annotation.annotationId);
1757 an.setVisible(annotation.visible);
1759 an.setDescription(annotation.description);
1761 if (annotation.sequenceRef != null)
1763 // 2.9 JAL-1781 xref on sequence id rather than name
1764 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1766 if (annotation.groupRef != null)
1768 String groupIdr = groupRefs.get(annotation.groupRef);
1769 if (groupIdr == null)
1771 // make a locally unique String
1773 annotation.groupRef,
1774 groupIdr = ("" + System.currentTimeMillis()
1775 + annotation.groupRef.getName() + groupRefs
1778 an.setGroupRef(groupIdr.toString());
1781 // store all visualization attributes for annotation
1782 an.setGraphHeight(annotation.graphHeight);
1783 an.setCentreColLabels(annotation.centreColLabels);
1784 an.setScaleColLabels(annotation.scaleColLabel);
1785 an.setShowAllColLabels(annotation.showAllColLabels);
1786 an.setBelowAlignment(annotation.belowAlignment);
1788 if (annotation.graph > 0)
1791 an.setGraphType(annotation.graph);
1792 an.setGraphGroup(annotation.graphGroup);
1793 if (annotation.getThreshold() != null)
1795 ThresholdLine line = new ThresholdLine();
1796 line.setLabel(annotation.getThreshold().label);
1797 line.setValue(annotation.getThreshold().value);
1798 line.setColour(annotation.getThreshold().colour.getRGB());
1799 an.setThresholdLine(line);
1807 an.setLabel(annotation.label);
1809 if (annotation == av.getAlignmentQualityAnnot()
1810 || annotation == av.getAlignmentConservationAnnotation()
1811 || annotation == av.getAlignmentConsensusAnnotation()
1812 || annotation.autoCalculated)
1814 // new way of indicating autocalculated annotation -
1815 an.setAutoCalculated(annotation.autoCalculated);
1817 if (annotation.hasScore())
1819 an.setScore(annotation.getScore());
1822 if (annotation.getCalcId() != null)
1824 calcIdSet.add(annotation.getCalcId());
1825 an.setCalcId(annotation.getCalcId());
1827 if (annotation.hasProperties())
1829 for (String pr : annotation.getProperties())
1831 Property prop = new Property();
1833 prop.setValue(annotation.getProperty(pr));
1834 an.addProperty(prop);
1838 AnnotationElement ae;
1839 if (annotation.annotations != null)
1841 an.setScoreOnly(false);
1842 for (int a = 0; a < annotation.annotations.length; a++)
1844 if ((annotation == null) || (annotation.annotations[a] == null))
1849 ae = new AnnotationElement();
1850 if (annotation.annotations[a].description != null)
1852 ae.setDescription(annotation.annotations[a].description);
1854 if (annotation.annotations[a].displayCharacter != null)
1856 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1859 if (!Float.isNaN(annotation.annotations[a].value))
1861 ae.setValue(annotation.annotations[a].value);
1865 if (annotation.annotations[a].secondaryStructure > ' ')
1867 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1871 if (annotation.annotations[a].colour != null
1872 && annotation.annotations[a].colour != java.awt.Color.black)
1874 ae.setColour(annotation.annotations[a].colour.getRGB());
1877 an.addAnnotationElement(ae);
1878 if (annotation.autoCalculated)
1880 // only write one non-null entry into the annotation row -
1881 // sufficient to get the visualization attributes necessary to
1889 an.setScoreOnly(true);
1891 if (!storeDS || (storeDS && !annotation.autoCalculated))
1893 // skip autocalculated annotation - these are only provided for
1895 vamsasSet.addAnnotation(an);
1901 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1903 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1904 if (settings != null)
1906 CalcIdParam vCalcIdParam = new CalcIdParam();
1907 vCalcIdParam.setCalcId(calcId);
1908 vCalcIdParam.addServiceURL(settings.getServiceURI());
1909 // generic URI allowing a third party to resolve another instance of the
1910 // service used for this calculation
1911 for (String urls : settings.getServiceURLs())
1913 vCalcIdParam.addServiceURL(urls);
1915 vCalcIdParam.setVersion("1.0");
1916 if (settings.getPreset() != null)
1918 WsParamSetI setting = settings.getPreset();
1919 vCalcIdParam.setName(setting.getName());
1920 vCalcIdParam.setDescription(setting.getDescription());
1924 vCalcIdParam.setName("");
1925 vCalcIdParam.setDescription("Last used parameters");
1927 // need to be able to recover 1) settings 2) user-defined presets or
1928 // recreate settings from preset 3) predefined settings provided by
1929 // service - or settings that can be transferred (or discarded)
1930 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1932 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1933 // todo - decide if updateImmediately is needed for any projects.
1935 return vCalcIdParam;
1940 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1943 if (calcIdParam.getVersion().equals("1.0"))
1945 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1946 .getPreferredServiceFor(calcIdParam.getServiceURL());
1947 if (service != null)
1949 WsParamSetI parmSet = null;
1952 parmSet = service.getParamStore().parseServiceParameterFile(
1953 calcIdParam.getName(), calcIdParam.getDescription(),
1954 calcIdParam.getServiceURL(),
1955 calcIdParam.getParameters().replace("|\\n|", "\n"));
1956 } catch (IOException x)
1958 warn("Couldn't parse parameter data for "
1959 + calcIdParam.getCalcId(), x);
1962 List<ArgumentI> argList = null;
1963 if (calcIdParam.getName().length() > 0)
1965 parmSet = service.getParamStore()
1966 .getPreset(calcIdParam.getName());
1967 if (parmSet != null)
1969 // TODO : check we have a good match with settings in AACon -
1970 // otherwise we'll need to create a new preset
1975 argList = parmSet.getArguments();
1978 AAConSettings settings = new AAConSettings(
1979 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1980 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1981 calcIdParam.isNeedsUpdate());
1986 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1990 throw new Error(MessageManager.formatMessage(
1991 "error.unsupported_version_calcIdparam",
1992 new Object[] { calcIdParam.toString() }));
1996 * External mapping between jalview objects and objects yielding a valid and
1997 * unique object ID string. This is null for normal Jalview project IO, but
1998 * non-null when a jalview project is being read or written as part of a
2001 IdentityHashMap jv2vobj = null;
2004 * Construct a unique ID for jvobj using either existing bindings or if none
2005 * exist, the result of the hashcode call for the object.
2008 * jalview data object
2009 * @return unique ID for referring to jvobj
2011 private String makeHashCode(Object jvobj, String altCode)
2013 if (jv2vobj != null)
2015 Object id = jv2vobj.get(jvobj);
2018 return id.toString();
2020 // check string ID mappings
2021 if (jvids2vobj != null && jvobj instanceof String)
2023 id = jvids2vobj.get(jvobj);
2027 return id.toString();
2029 // give up and warn that something has gone wrong
2030 warn("Cannot find ID for object in external mapping : " + jvobj);
2036 * return local jalview object mapped to ID, if it exists
2040 * @return null or object bound to idcode
2042 private Object retrieveExistingObj(String idcode)
2044 if (idcode != null && vobj2jv != null)
2046 return vobj2jv.get(idcode);
2052 * binding from ID strings from external mapping table to jalview data model
2055 private Hashtable vobj2jv;
2057 private Sequence createVamsasSequence(String id, SequenceI jds)
2059 return createVamsasSequence(true, id, jds, null);
2062 private Sequence createVamsasSequence(boolean recurse, String id,
2063 SequenceI jds, SequenceI parentseq)
2065 Sequence vamsasSeq = new Sequence();
2066 vamsasSeq.setId(id);
2067 vamsasSeq.setName(jds.getName());
2068 vamsasSeq.setSequence(jds.getSequenceAsString());
2069 vamsasSeq.setDescription(jds.getDescription());
2070 jalview.datamodel.DBRefEntry[] dbrefs = null;
2071 if (jds.getDatasetSequence() != null)
2073 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2077 // seqId==dsseqid so we can tell which sequences really are
2078 // dataset sequences only
2079 vamsasSeq.setDsseqid(id);
2080 dbrefs = jds.getDBRefs();
2081 if (parentseq == null)
2088 for (int d = 0; d < dbrefs.length; d++)
2090 DBRef dbref = new DBRef();
2091 dbref.setSource(dbrefs[d].getSource());
2092 dbref.setVersion(dbrefs[d].getVersion());
2093 dbref.setAccessionId(dbrefs[d].getAccessionId());
2094 if (dbrefs[d].hasMap())
2096 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2098 dbref.setMapping(mp);
2100 vamsasSeq.addDBRef(dbref);
2106 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2107 SequenceI parentseq, SequenceI jds, boolean recurse)
2110 if (jmp.getMap() != null)
2114 jalview.util.MapList mlst = jmp.getMap();
2115 List<int[]> r = mlst.getFromRanges();
2116 for (int[] range : r)
2118 MapListFrom mfrom = new MapListFrom();
2119 mfrom.setStart(range[0]);
2120 mfrom.setEnd(range[1]);
2121 mp.addMapListFrom(mfrom);
2123 r = mlst.getToRanges();
2124 for (int[] range : r)
2126 MapListTo mto = new MapListTo();
2127 mto.setStart(range[0]);
2128 mto.setEnd(range[1]);
2129 mp.addMapListTo(mto);
2131 mp.setMapFromUnit(mlst.getFromRatio());
2132 mp.setMapToUnit(mlst.getToRatio());
2133 if (jmp.getTo() != null)
2135 MappingChoice mpc = new MappingChoice();
2137 // check/create ID for the sequence referenced by getTo()
2140 SequenceI ps = null;
2141 if (parentseq != jmp.getTo()
2142 && parentseq.getDatasetSequence() != jmp.getTo())
2144 // chaining dbref rather than a handshaking one
2145 jmpid = seqHash(ps = jmp.getTo());
2149 jmpid = seqHash(ps = parentseq);
2151 mpc.setDseqFor(jmpid);
2152 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2154 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2155 seqRefIds.put(mpc.getDseqFor(), ps);
2159 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2162 mp.setMappingChoice(mpc);
2168 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2169 List<UserColourScheme> userColours, JalviewModelSequence jms)
2172 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2173 boolean newucs = false;
2174 if (!userColours.contains(ucs))
2176 userColours.add(ucs);
2179 id = "ucs" + userColours.indexOf(ucs);
2182 // actually create the scheme's entry in the XML model
2183 java.awt.Color[] colours = ucs.getColours();
2184 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2185 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2187 for (int i = 0; i < colours.length; i++)
2189 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2190 col.setName(ResidueProperties.aa[i]);
2191 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2192 jbucs.addColour(col);
2194 if (ucs.getLowerCaseColours() != null)
2196 colours = ucs.getLowerCaseColours();
2197 for (int i = 0; i < colours.length; i++)
2199 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2200 col.setName(ResidueProperties.aa[i].toLowerCase());
2201 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2202 jbucs.addColour(col);
2207 uc.setUserColourScheme(jbucs);
2208 jms.addUserColours(uc);
2214 jalview.schemes.UserColourScheme getUserColourScheme(
2215 JalviewModelSequence jms, String id)
2217 UserColours[] uc = jms.getUserColours();
2218 UserColours colours = null;
2220 for (int i = 0; i < uc.length; i++)
2222 if (uc[i].getId().equals(id))
2230 java.awt.Color[] newColours = new java.awt.Color[24];
2232 for (int i = 0; i < 24; i++)
2234 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2235 .getUserColourScheme().getColour(i).getRGB(), 16));
2238 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2241 if (colours.getUserColourScheme().getColourCount() > 24)
2243 newColours = new java.awt.Color[23];
2244 for (int i = 0; i < 23; i++)
2246 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2247 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2249 ucs.setLowerCaseColours(newColours);
2256 * contains last error message (if any) encountered by XML loader.
2258 String errorMessage = null;
2261 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2262 * exceptions are raised during project XML parsing
2264 public boolean attemptversion1parse = true;
2267 * Load a jalview project archive from a jar file
2270 * - HTTP URL or filename
2272 public AlignFrame loadJalviewAlign(final String file)
2275 jalview.gui.AlignFrame af = null;
2279 // create list to store references for any new Jmol viewers created
2280 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2281 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2282 // Workaround is to make sure caller implements the JarInputStreamProvider
2284 // so we can re-open the jar input stream for each entry.
2286 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2287 af = loadJalviewAlign(jprovider);
2289 } catch (MalformedURLException e)
2291 errorMessage = "Invalid URL format for '" + file + "'";
2297 SwingUtilities.invokeAndWait(new Runnable()
2302 setLoadingFinishedForNewStructureViewers();
2305 } catch (Exception x)
2307 System.err.println("Error loading alignment: " + x.getMessage());
2313 private jarInputStreamProvider createjarInputStreamProvider(
2314 final String file) throws MalformedURLException
2317 errorMessage = null;
2318 uniqueSetSuffix = null;
2320 viewportsAdded.clear();
2321 frefedSequence = null;
2323 if (file.startsWith("http://"))
2325 url = new URL(file);
2327 final URL _url = url;
2328 return new jarInputStreamProvider()
2332 public JarInputStream getJarInputStream() throws IOException
2336 return new JarInputStream(_url.openStream());
2340 return new JarInputStream(new FileInputStream(file));
2345 public String getFilename()
2353 * Recover jalview session from a jalview project archive. Caller may
2354 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2355 * themselves. Any null fields will be initialised with default values,
2356 * non-null fields are left alone.
2361 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2363 errorMessage = null;
2364 if (uniqueSetSuffix == null)
2366 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2368 if (seqRefIds == null)
2372 AlignFrame af = null, _af = null;
2373 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2374 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2375 final String file = jprovider.getFilename();
2378 JarInputStream jin = null;
2379 JarEntry jarentry = null;
2384 jin = jprovider.getJarInputStream();
2385 for (int i = 0; i < entryCount; i++)
2387 jarentry = jin.getNextJarEntry();
2390 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2392 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2393 JalviewModel object = new JalviewModel();
2395 Unmarshaller unmar = new Unmarshaller(object);
2396 unmar.setValidation(false);
2397 object = (JalviewModel) unmar.unmarshal(in);
2398 if (true) // !skipViewport(object))
2400 _af = loadFromObject(object, file, true, jprovider);
2402 && object.getJalviewModelSequence().getViewportCount() > 0)
2406 // store a reference to the first view
2409 if (_af.viewport.isGatherViewsHere())
2411 // if this is a gathered view, keep its reference since
2412 // after gathering views, only this frame will remain
2414 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2416 // Save dataset to register mappings once all resolved
2417 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2418 af.viewport.getAlignment().getDataset());
2423 else if (jarentry != null)
2425 // Some other file here.
2428 } while (jarentry != null);
2429 resolveFrefedSequences();
2430 } catch (IOException ex)
2432 ex.printStackTrace();
2433 errorMessage = "Couldn't locate Jalview XML file : " + file;
2434 System.err.println("Exception whilst loading jalview XML file : "
2436 } catch (Exception ex)
2438 System.err.println("Parsing as Jalview Version 2 file failed.");
2439 ex.printStackTrace(System.err);
2440 if (attemptversion1parse)
2442 // Is Version 1 Jar file?
2445 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2446 } catch (Exception ex2)
2448 System.err.println("Exception whilst loading as jalviewXMLV1:");
2449 ex2.printStackTrace();
2453 if (Desktop.instance != null)
2455 Desktop.instance.stopLoading();
2459 System.out.println("Successfully loaded archive file");
2462 ex.printStackTrace();
2464 System.err.println("Exception whilst loading jalview XML file : "
2466 } catch (OutOfMemoryError e)
2468 // Don't use the OOM Window here
2469 errorMessage = "Out of memory loading jalview XML file";
2470 System.err.println("Out of memory whilst loading jalview XML file");
2471 e.printStackTrace();
2475 * Regather multiple views (with the same sequence set id) to the frame (if
2476 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2477 * views instead of separate frames. Note this doesn't restore a state where
2478 * some expanded views in turn have tabbed views - the last "first tab" read
2479 * in will play the role of gatherer for all.
2481 for (AlignFrame fr : gatherToThisFrame.values())
2483 Desktop.instance.gatherViews(fr);
2486 restoreSplitFrames();
2487 for (AlignmentI ds : importedDatasets.keySet())
2489 if (ds.getCodonFrames() != null)
2491 StructureSelectionManager.getStructureSelectionManager(
2492 Desktop.instance).registerMappings(ds.getCodonFrames());
2495 if (errorMessage != null)
2500 if (Desktop.instance != null)
2502 Desktop.instance.stopLoading();
2509 * Try to reconstruct and display SplitFrame windows, where each contains
2510 * complementary dna and protein alignments. Done by pairing up AlignFrame
2511 * objects (created earlier) which have complementary viewport ids associated.
2513 protected void restoreSplitFrames()
2515 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2516 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2517 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2520 * Identify the DNA alignments
2522 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2525 AlignFrame af = candidate.getValue();
2526 if (af.getViewport().getAlignment().isNucleotide())
2528 dna.put(candidate.getKey().getId(), af);
2533 * Try to match up the protein complements
2535 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2538 AlignFrame af = candidate.getValue();
2539 if (!af.getViewport().getAlignment().isNucleotide())
2541 String complementId = candidate.getKey().getComplementId();
2542 // only non-null complements should be in the Map
2543 if (complementId != null && dna.containsKey(complementId))
2545 final AlignFrame dnaFrame = dna.get(complementId);
2546 SplitFrame sf = createSplitFrame(dnaFrame, af);
2547 addedToSplitFrames.add(dnaFrame);
2548 addedToSplitFrames.add(af);
2549 dnaFrame.setMenusForViewport();
2550 af.setMenusForViewport();
2551 if (af.viewport.isGatherViewsHere())
2560 * Open any that we failed to pair up (which shouldn't happen!) as
2561 * standalone AlignFrame's.
2563 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2566 AlignFrame af = candidate.getValue();
2567 if (!addedToSplitFrames.contains(af))
2569 Viewport view = candidate.getKey();
2570 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2572 af.setMenusForViewport();
2573 System.err.println("Failed to restore view " + view.getTitle()
2574 + " to split frame");
2579 * Gather back into tabbed views as flagged.
2581 for (SplitFrame sf : gatherTo)
2583 Desktop.instance.gatherViews(sf);
2586 splitFrameCandidates.clear();
2590 * Construct and display one SplitFrame holding DNA and protein alignments.
2593 * @param proteinFrame
2596 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2597 AlignFrame proteinFrame)
2599 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2600 String title = MessageManager.getString("label.linked_view_title");
2601 int width = (int) dnaFrame.getBounds().getWidth();
2602 int height = (int) (dnaFrame.getBounds().getHeight()
2603 + proteinFrame.getBounds().getHeight() + 50);
2606 * SplitFrame location is saved to both enclosed frames
2608 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2609 Desktop.addInternalFrame(splitFrame, title, width, height);
2612 * And compute cDNA consensus (couldn't do earlier with consensus as
2613 * mappings were not yet present)
2615 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2621 * check errorMessage for a valid error message and raise an error box in the
2622 * GUI or write the current errorMessage to stderr and then clear the error
2625 protected void reportErrors()
2627 reportErrors(false);
2630 protected void reportErrors(final boolean saving)
2632 if (errorMessage != null)
2634 final String finalErrorMessage = errorMessage;
2637 javax.swing.SwingUtilities.invokeLater(new Runnable()
2643 .showInternalMessageDialog(Desktop.desktop,
2644 finalErrorMessage, "Error "
2645 + (saving ? "saving" : "loading")
2647 JvOptionPane.WARNING_MESSAGE);
2653 System.err.println("Problem loading Jalview file: " + errorMessage);
2656 errorMessage = null;
2659 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2662 * when set, local views will be updated from view stored in JalviewXML
2663 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2664 * sync if this is set to true.
2666 private final boolean updateLocalViews = false;
2669 * Returns the path to a temporary file holding the PDB file for the given PDB
2670 * id. The first time of asking, searches for a file of that name in the
2671 * Jalview project jar, and copies it to a new temporary file. Any repeat
2672 * requests just return the path to the file previously created.
2678 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2681 if (alreadyLoadedPDB.containsKey(pdbId))
2683 return alreadyLoadedPDB.get(pdbId).toString();
2686 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2688 if (tempFile != null)
2690 alreadyLoadedPDB.put(pdbId, tempFile);
2696 * Copies the jar entry of given name to a new temporary file and returns the
2697 * path to the file, or null if the entry is not found.
2700 * @param jarEntryName
2702 * a prefix for the temporary file name, must be at least three
2705 * null or original file - so new file can be given the same suffix
2709 protected String copyJarEntry(jarInputStreamProvider jprovider,
2710 String jarEntryName, String prefix, String origFile)
2712 BufferedReader in = null;
2713 PrintWriter out = null;
2714 String suffix = ".tmp";
2715 if (origFile == null)
2717 origFile = jarEntryName;
2719 int sfpos = origFile.lastIndexOf(".");
2720 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2722 suffix = "." + origFile.substring(sfpos + 1);
2726 JarInputStream jin = jprovider.getJarInputStream();
2728 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2729 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2730 * FileInputStream(jprovider)); }
2733 JarEntry entry = null;
2736 entry = jin.getNextJarEntry();
2737 } while (entry != null && !entry.getName().equals(jarEntryName));
2740 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2741 File outFile = File.createTempFile(prefix, suffix);
2742 outFile.deleteOnExit();
2743 out = new PrintWriter(new FileOutputStream(outFile));
2746 while ((data = in.readLine()) != null)
2751 String t = outFile.getAbsolutePath();
2756 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2758 } catch (Exception ex)
2760 ex.printStackTrace();
2768 } catch (IOException e)
2782 private class JvAnnotRow
2784 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2791 * persisted version of annotation row from which to take vis properties
2793 public jalview.datamodel.AlignmentAnnotation template;
2796 * original position of the annotation row in the alignment
2802 * Load alignment frame from jalview XML DOM object
2807 * filename source string
2808 * @param loadTreesAndStructures
2809 * when false only create Viewport
2811 * data source provider
2812 * @return alignment frame created from view stored in DOM
2814 AlignFrame loadFromObject(JalviewModel object, String file,
2815 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2817 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2818 Sequence[] vamsasSeq = vamsasSet.getSequence();
2820 JalviewModelSequence jms = object.getJalviewModelSequence();
2822 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2825 // ////////////////////////////////
2828 List<SequenceI> hiddenSeqs = null;
2830 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2832 boolean multipleView = false;
2833 SequenceI referenceseqForView = null;
2834 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2835 int vi = 0; // counter in vamsasSeq array
2836 for (int i = 0; i < jseqs.length; i++)
2838 String seqId = jseqs[i].getId();
2840 SequenceI tmpSeq = seqRefIds.get(seqId);
2843 if (!incompleteSeqs.containsKey(seqId))
2845 // may not need this check, but keep it for at least 2.9,1 release
2846 if (tmpSeq.getStart() != jseqs[i].getStart()
2847 || tmpSeq.getEnd() != jseqs[i].getEnd())
2850 .println("Warning JAL-2154 regression: updating start/end for sequence "
2851 + tmpSeq.toString() + " to " + jseqs[i]);
2856 incompleteSeqs.remove(seqId);
2858 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2860 // most likely we are reading a dataset XML document so
2861 // update from vamsasSeq section of XML for this sequence
2862 tmpSeq.setName(vamsasSeq[vi].getName());
2863 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2864 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2869 // reading multiple views, so vamsasSeq set is a subset of JSeq
2870 multipleView = true;
2872 tmpSeq.setStart(jseqs[i].getStart());
2873 tmpSeq.setEnd(jseqs[i].getEnd());
2874 tmpseqs.add(tmpSeq);
2878 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2879 vamsasSeq[vi].getSequence());
2880 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2881 tmpSeq.setStart(jseqs[i].getStart());
2882 tmpSeq.setEnd(jseqs[i].getEnd());
2883 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2884 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2885 tmpseqs.add(tmpSeq);
2889 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2891 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2894 if (jseqs[i].getHidden())
2896 if (hiddenSeqs == null)
2898 hiddenSeqs = new ArrayList<SequenceI>();
2901 hiddenSeqs.add(tmpSeq);
2906 // Create the alignment object from the sequence set
2907 // ///////////////////////////////
2908 SequenceI[] orderedSeqs = tmpseqs
2909 .toArray(new SequenceI[tmpseqs.size()]);
2911 AlignmentI al = null;
2912 // so we must create or recover the dataset alignment before going further
2913 // ///////////////////////////////
2914 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2916 // older jalview projects do not have a dataset - so creat alignment and
2918 al = new Alignment(orderedSeqs);
2919 al.setDataset(null);
2923 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2926 // we are importing a dataset record, so
2927 // recover reference to an alignment already materialsed as dataset
2928 al = getDatasetFor(vamsasSet.getDatasetId());
2932 // materialse the alignment
2933 al = new Alignment(orderedSeqs);
2937 addDatasetRef(vamsasSet.getDatasetId(), al);
2940 // finally, verify all data in vamsasSet is actually present in al
2941 // passing on flag indicating if it is actually a stored dataset
2942 recoverDatasetFor(vamsasSet, al, isdsal);
2945 if (referenceseqForView != null)
2947 al.setSeqrep(referenceseqForView);
2949 // / Add the alignment properties
2950 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2952 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2953 al.setProperty(ssp.getKey(), ssp.getValue());
2956 // ///////////////////////////////
2958 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2961 // load sequence features, database references and any associated PDB
2962 // structures for the alignment
2964 // prior to 2.10, this part would only be executed the first time a
2965 // sequence was encountered, but not afterwards.
2966 // now, for 2.10 projects, this is also done if the xml doc includes
2967 // dataset sequences not actually present in any particular view.
2969 for (int i = 0; i < vamsasSeq.length; i++)
2971 if (jseqs[i].getFeaturesCount() > 0)
2973 Features[] features = jseqs[i].getFeatures();
2974 for (int f = 0; f < features.length; f++)
2976 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2977 features[f].getType(), features[f].getDescription(),
2978 features[f].getStatus(), features[f].getBegin(),
2979 features[f].getEnd(), features[f].getFeatureGroup());
2981 sf.setScore(features[f].getScore());
2982 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2984 OtherData keyValue = features[f].getOtherData(od);
2985 if (keyValue.getKey().startsWith("LINK"))
2987 sf.addLink(keyValue.getValue());
2991 sf.setValue(keyValue.getKey(), keyValue.getValue());
2995 // adds feature to datasequence's feature set (since Jalview 2.10)
2996 al.getSequenceAt(i).addSequenceFeature(sf);
2999 if (vamsasSeq[i].getDBRefCount() > 0)
3001 // adds dbrefs to datasequence's set (since Jalview 2.10)
3003 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
3004 : al.getSequenceAt(i).getDatasetSequence(),
3007 if (jseqs[i].getPdbidsCount() > 0)
3009 Pdbids[] ids = jseqs[i].getPdbids();
3010 for (int p = 0; p < ids.length; p++)
3012 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
3013 entry.setId(ids[p].getId());
3014 if (ids[p].getType() != null)
3016 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3018 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3022 entry.setType(PDBEntry.Type.FILE);
3025 // jprovider is null when executing 'New View'
3026 if (ids[p].getFile() != null && jprovider != null)
3028 if (!pdbloaded.containsKey(ids[p].getFile()))
3030 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3035 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3038 if (ids[p].getPdbentryItem() != null)
3040 for (PdbentryItem item : ids[p].getPdbentryItem())
3042 for (Property pr : item.getProperty())
3044 entry.setProperty(pr.getName(), pr.getValue());
3048 StructureSelectionManager.getStructureSelectionManager(
3049 Desktop.instance).registerPDBEntry(entry);
3050 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3051 if (al.getSequenceAt(i).getDatasetSequence() != null)
3053 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3057 al.getSequenceAt(i).addPDBId(entry);
3062 } // end !multipleview
3064 // ///////////////////////////////
3065 // LOAD SEQUENCE MAPPINGS
3067 if (vamsasSet.getAlcodonFrameCount() > 0)
3069 // TODO Potentially this should only be done once for all views of an
3071 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3072 for (int i = 0; i < alc.length; i++)
3074 AlignedCodonFrame cf = new AlignedCodonFrame();
3075 if (alc[i].getAlcodMapCount() > 0)
3077 AlcodMap[] maps = alc[i].getAlcodMap();
3078 for (int m = 0; m < maps.length; m++)
3080 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3082 jalview.datamodel.Mapping mapping = null;
3083 // attach to dna sequence reference.
3084 if (maps[m].getMapping() != null)
3086 mapping = addMapping(maps[m].getMapping());
3087 if (dnaseq != null && mapping.getTo() != null)
3089 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3094 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3099 al.addCodonFrame(cf);
3104 // ////////////////////////////////
3106 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3109 * store any annotations which forward reference a group's ID
3111 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3113 if (vamsasSet.getAnnotationCount() > 0)
3115 Annotation[] an = vamsasSet.getAnnotation();
3117 for (int i = 0; i < an.length; i++)
3119 Annotation annotation = an[i];
3122 * test if annotation is automatically calculated for this view only
3124 boolean autoForView = false;
3125 if (annotation.getLabel().equals("Quality")
3126 || annotation.getLabel().equals("Conservation")
3127 || annotation.getLabel().equals("Consensus"))
3129 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3131 if (!annotation.hasAutoCalculated())
3133 annotation.setAutoCalculated(true);
3137 || (annotation.hasAutoCalculated() && annotation
3138 .isAutoCalculated()))
3140 // remove ID - we don't recover annotation from other views for
3141 // view-specific annotation
3142 annotation.setId(null);
3145 // set visiblity for other annotation in this view
3146 String annotationId = annotation.getId();
3147 if (annotationId != null && annotationIds.containsKey(annotationId))
3149 AlignmentAnnotation jda = annotationIds.get(annotationId);
3150 // in principle Visible should always be true for annotation displayed
3151 // in multiple views
3152 if (annotation.hasVisible())
3154 jda.visible = annotation.getVisible();
3157 al.addAnnotation(jda);
3161 // Construct new annotation from model.
3162 AnnotationElement[] ae = annotation.getAnnotationElement();
3163 jalview.datamodel.Annotation[] anot = null;
3164 java.awt.Color firstColour = null;
3166 if (!annotation.getScoreOnly())
3168 anot = new jalview.datamodel.Annotation[al.getWidth()];
3169 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3171 anpos = ae[aa].getPosition();
3173 if (anpos >= anot.length)
3178 anot[anpos] = new jalview.datamodel.Annotation(
3180 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3181 (ae[aa].getSecondaryStructure() == null || ae[aa]
3182 .getSecondaryStructure().length() == 0) ? ' '
3183 : ae[aa].getSecondaryStructure().charAt(0),
3187 // JBPNote: Consider verifying dataflow for IO of secondary
3188 // structure annotation read from Stockholm files
3189 // this was added to try to ensure that
3190 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3192 // anot[ae[aa].getPosition()].displayCharacter = "";
3194 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3195 if (firstColour == null)
3197 firstColour = anot[anpos].colour;
3201 jalview.datamodel.AlignmentAnnotation jaa = null;
3203 if (annotation.getGraph())
3205 float llim = 0, hlim = 0;
3206 // if (autoForView || an[i].isAutoCalculated()) {
3209 jaa = new jalview.datamodel.AlignmentAnnotation(
3210 annotation.getLabel(), annotation.getDescription(), anot,
3211 llim, hlim, annotation.getGraphType());
3213 jaa.graphGroup = annotation.getGraphGroup();
3214 jaa._linecolour = firstColour;
3215 if (annotation.getThresholdLine() != null)
3217 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3218 .getThresholdLine().getValue(), annotation
3219 .getThresholdLine().getLabel(), new java.awt.Color(
3220 annotation.getThresholdLine().getColour())));
3223 if (autoForView || annotation.isAutoCalculated())
3225 // Hardwire the symbol display line to ensure that labels for
3226 // histograms are displayed
3232 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3233 an[i].getDescription(), anot);
3234 jaa._linecolour = firstColour;
3236 // register new annotation
3237 if (an[i].getId() != null)
3239 annotationIds.put(an[i].getId(), jaa);
3240 jaa.annotationId = an[i].getId();
3242 // recover sequence association
3243 String sequenceRef = an[i].getSequenceRef();
3244 if (sequenceRef != null)
3246 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3247 SequenceI sequence = seqRefIds.get(sequenceRef);
3248 if (sequence == null)
3250 // in pre-2.9 projects sequence ref is to sequence name
3251 sequence = al.findName(sequenceRef);
3253 if (sequence != null)
3255 jaa.createSequenceMapping(sequence, 1, true);
3256 sequence.addAlignmentAnnotation(jaa);
3259 // and make a note of any group association
3260 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3262 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3263 .get(an[i].getGroupRef());
3266 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3267 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3272 if (an[i].hasScore())
3274 jaa.setScore(an[i].getScore());
3276 if (an[i].hasVisible())
3278 jaa.visible = an[i].getVisible();
3281 if (an[i].hasCentreColLabels())
3283 jaa.centreColLabels = an[i].getCentreColLabels();
3286 if (an[i].hasScaleColLabels())
3288 jaa.scaleColLabel = an[i].getScaleColLabels();
3290 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3292 // newer files have an 'autoCalculated' flag and store calculation
3293 // state in viewport properties
3294 jaa.autoCalculated = true; // means annotation will be marked for
3295 // update at end of load.
3297 if (an[i].hasGraphHeight())
3299 jaa.graphHeight = an[i].getGraphHeight();
3301 if (an[i].hasBelowAlignment())
3303 jaa.belowAlignment = an[i].isBelowAlignment();
3305 jaa.setCalcId(an[i].getCalcId());
3306 if (an[i].getPropertyCount() > 0)
3308 for (jalview.schemabinding.version2.Property prop : an[i]
3311 jaa.setProperty(prop.getName(), prop.getValue());
3314 if (jaa.autoCalculated)
3316 autoAlan.add(new JvAnnotRow(i, jaa));
3319 // if (!autoForView)
3321 // add autocalculated group annotation and any user created annotation
3323 al.addAnnotation(jaa);
3327 // ///////////////////////
3329 // Create alignment markup and styles for this view
3330 if (jms.getJGroupCount() > 0)
3332 JGroup[] groups = jms.getJGroup();
3333 boolean addAnnotSchemeGroup = false;
3334 for (int i = 0; i < groups.length; i++)
3336 JGroup jGroup = groups[i];
3337 ColourSchemeI cs = null;
3338 if (jGroup.getColour() != null)
3340 if (jGroup.getColour().startsWith("ucs"))
3342 cs = getUserColourScheme(jms, jGroup.getColour());
3344 else if (jGroup.getColour().equals("AnnotationColourGradient")
3345 && jGroup.getAnnotationColours() != null)
3347 addAnnotSchemeGroup = true;
3352 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3357 cs.setThreshold(jGroup.getPidThreshold(), true);
3361 Vector<SequenceI> seqs = new Vector<SequenceI>();
3363 for (int s = 0; s < jGroup.getSeqCount(); s++)
3365 String seqId = jGroup.getSeq(s) + "";
3366 SequenceI ts = seqRefIds.get(seqId);
3370 seqs.addElement(ts);
3374 if (seqs.size() < 1)
3379 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3380 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3381 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3383 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3385 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3386 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3387 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3388 .isShowUnconserved() : false);
3389 sg.thresholdTextColour = jGroup.getTextColThreshold();
3390 if (jGroup.hasShowConsensusHistogram())
3392 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3395 if (jGroup.hasShowSequenceLogo())
3397 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3399 if (jGroup.hasNormaliseSequenceLogo())
3401 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3403 if (jGroup.hasIgnoreGapsinConsensus())
3405 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3407 if (jGroup.getConsThreshold() != 0)
3409 Conservation c = new Conservation("All", sg.getSequences(null),
3410 0, sg.getWidth() - 1);
3412 c.verdict(false, 25);
3413 sg.cs.setConservation(c);
3416 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3418 // re-instate unique group/annotation row reference
3419 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3423 for (AlignmentAnnotation jaa : jaal)
3426 if (jaa.autoCalculated)
3428 // match up and try to set group autocalc alignment row for this
3430 if (jaa.label.startsWith("Consensus for "))
3432 sg.setConsensus(jaa);
3434 // match up and try to set group autocalc alignment row for this
3436 if (jaa.label.startsWith("Conservation for "))
3438 sg.setConservationRow(jaa);
3445 if (addAnnotSchemeGroup)
3447 // reconstruct the annotation colourscheme
3448 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3449 null, al, jms, false);
3455 // only dataset in this model, so just return.
3458 // ///////////////////////////////
3461 // If we just load in the same jar file again, the sequenceSetId
3462 // will be the same, and we end up with multiple references
3463 // to the same sequenceSet. We must modify this id on load
3464 // so that each load of the file gives a unique id
3465 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3466 String viewId = (view.getId() == null ? null : view.getId()
3468 AlignFrame af = null;
3469 AlignViewport av = null;
3470 // now check to see if we really need to create a new viewport.
3471 if (multipleView && viewportsAdded.size() == 0)
3473 // We recovered an alignment for which a viewport already exists.
3474 // TODO: fix up any settings necessary for overlaying stored state onto
3475 // state recovered from another document. (may not be necessary).
3476 // we may need a binding from a viewport in memory to one recovered from
3478 // and then recover its containing af to allow the settings to be applied.
3479 // TODO: fix for vamsas demo
3481 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3483 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3484 if (seqsetobj != null)
3486 if (seqsetobj instanceof String)
3488 uniqueSeqSetId = (String) seqsetobj;
3490 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3496 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3502 * indicate that annotation colours are applied across all groups (pre
3503 * Jalview 2.8.1 behaviour)
3505 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3506 "2.8.1", object.getVersion());
3508 AlignmentPanel ap = null;
3509 boolean isnewview = true;
3512 // Check to see if this alignment already has a view id == viewId
3513 jalview.gui.AlignmentPanel views[] = Desktop
3514 .getAlignmentPanels(uniqueSeqSetId);
3515 if (views != null && views.length > 0)
3517 for (int v = 0; v < views.length; v++)
3519 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3521 // recover the existing alignpanel, alignframe, viewport
3522 af = views[v].alignFrame;
3525 // TODO: could even skip resetting view settings if we don't want to
3526 // change the local settings from other jalview processes
3535 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3536 uniqueSeqSetId, viewId, autoAlan);
3542 * Load any trees, PDB structures and viewers
3544 * Not done if flag is false (when this method is used for New View)
3546 if (loadTreesAndStructures)
3548 loadTrees(jms, view, af, av, ap);
3549 loadPDBStructures(jprovider, jseqs, af, ap);
3550 loadRnaViewers(jprovider, jseqs, ap);
3552 // and finally return.
3557 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3558 * panel is restored from separate jar entries, two (gapped and trimmed) per
3559 * sequence and secondary structure.
3561 * Currently each viewer shows just one sequence and structure (gapped and
3562 * trimmed), however this method is designed to support multiple sequences or
3563 * structures in viewers if wanted in future.
3569 private void loadRnaViewers(jarInputStreamProvider jprovider,
3570 JSeq[] jseqs, AlignmentPanel ap)
3573 * scan the sequences for references to viewers; create each one the first
3574 * time it is referenced, add Rna models to existing viewers
3576 for (JSeq jseq : jseqs)
3578 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3580 RnaViewer viewer = jseq.getRnaViewer(i);
3581 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3582 uniqueSetSuffix, ap);
3584 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3586 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3587 SequenceI seq = seqRefIds.get(jseq.getId());
3588 AlignmentAnnotation ann = this.annotationIds.get(ss
3589 .getAnnotationId());
3592 * add the structure to the Varna display (with session state copied
3593 * from the jar to a temporary file)
3595 boolean gapped = ss.isGapped();
3596 String rnaTitle = ss.getTitle();
3597 String sessionState = ss.getViewerState();
3598 String tempStateFile = copyJarEntry(jprovider, sessionState,
3600 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3601 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3603 appVarna.setInitialSelection(viewer.getSelectedRna());
3609 * Locate and return an already instantiated matching AppVarna, or create one
3613 * @param viewIdSuffix
3617 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3618 String viewIdSuffix, AlignmentPanel ap)
3621 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3622 * if load is repeated
3624 String postLoadId = viewer.getViewId() + viewIdSuffix;
3625 for (JInternalFrame frame : getAllFrames())
3627 if (frame instanceof AppVarna)
3629 AppVarna varna = (AppVarna) frame;
3630 if (postLoadId.equals(varna.getViewId()))
3632 // this viewer is already instantiated
3633 // could in future here add ap as another 'parent' of the
3634 // AppVarna window; currently just 1-to-many
3641 * viewer not found - make it
3643 RnaViewerModel model = new RnaViewerModel(postLoadId,
3644 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3645 viewer.getWidth(), viewer.getHeight(),
3646 viewer.getDividerLocation());
3647 AppVarna varna = new AppVarna(model, ap);
3653 * Load any saved trees
3661 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3662 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3664 // TODO result of automated refactoring - are all these parameters needed?
3667 for (int t = 0; t < jms.getTreeCount(); t++)
3670 Tree tree = jms.getTree(t);
3672 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3675 tp = af.ShowNewickTree(
3676 new jalview.io.NewickFile(tree.getNewick()),
3677 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3678 tree.getXpos(), tree.getYpos());
3679 if (tree.getId() != null)
3681 // perhaps bind the tree id to something ?
3686 // update local tree attributes ?
3687 // TODO: should check if tp has been manipulated by user - if so its
3688 // settings shouldn't be modified
3689 tp.setTitle(tree.getTitle());
3690 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3691 .getWidth(), tree.getHeight()));
3692 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3695 tp.treeCanvas.av = av; // af.viewport;
3696 tp.treeCanvas.ap = ap; // af.alignPanel;
3701 warn("There was a problem recovering stored Newick tree: \n"
3702 + tree.getNewick());
3706 tp.fitToWindow.setState(tree.getFitToWindow());
3707 tp.fitToWindow_actionPerformed(null);
3709 if (tree.getFontName() != null)
3711 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3712 .getFontStyle(), tree.getFontSize()));
3716 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3717 .getFontStyle(), tree.getFontSize()));
3720 tp.showPlaceholders(tree.getMarkUnlinked());
3721 tp.showBootstrap(tree.getShowBootstrap());
3722 tp.showDistances(tree.getShowDistances());
3724 tp.treeCanvas.threshold = tree.getThreshold();
3726 if (tree.getCurrentTree())
3728 af.viewport.setCurrentTree(tp.getTree());
3732 } catch (Exception ex)
3734 ex.printStackTrace();
3739 * Load and link any saved structure viewers.
3746 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3747 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3750 * Run through all PDB ids on the alignment, and collect mappings between
3751 * distinct view ids and all sequences referring to that view.
3753 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3755 for (int i = 0; i < jseqs.length; i++)
3757 if (jseqs[i].getPdbidsCount() > 0)
3759 Pdbids[] ids = jseqs[i].getPdbids();
3760 for (int p = 0; p < ids.length; p++)
3762 final int structureStateCount = ids[p].getStructureStateCount();
3763 for (int s = 0; s < structureStateCount; s++)
3765 // check to see if we haven't already created this structure view
3766 final StructureState structureState = ids[p]
3767 .getStructureState(s);
3768 String sviewid = (structureState.getViewId() == null) ? null
3769 : structureState.getViewId() + uniqueSetSuffix;
3770 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3771 // Originally : ids[p].getFile()
3772 // : TODO: verify external PDB file recovery still works in normal
3773 // jalview project load
3774 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3776 jpdb.setId(ids[p].getId());
3778 int x = structureState.getXpos();
3779 int y = structureState.getYpos();
3780 int width = structureState.getWidth();
3781 int height = structureState.getHeight();
3783 // Probably don't need to do this anymore...
3784 // Desktop.desktop.getComponentAt(x, y);
3785 // TODO: NOW: check that this recovers the PDB file correctly.
3786 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3788 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3790 if (sviewid == null)
3792 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3795 if (!structureViewers.containsKey(sviewid))
3797 structureViewers.put(sviewid,
3798 new StructureViewerModel(x, y, width, height, false,
3799 false, true, structureState.getViewId(),
3800 structureState.getType()));
3801 // Legacy pre-2.7 conversion JAL-823 :
3802 // do not assume any view has to be linked for colour by
3806 // assemble String[] { pdb files }, String[] { id for each
3807 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3808 // seqs_file 2}, boolean[] {
3809 // linkAlignPanel,superposeWithAlignpanel}} from hash
3810 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3811 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3812 | (structureState.hasAlignwithAlignPanel() ? structureState
3813 .getAlignwithAlignPanel() : false));
3816 * Default colour by linked panel to false if not specified (e.g.
3817 * for pre-2.7 projects)
3819 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3820 colourWithAlignPanel |= (structureState
3821 .hasColourwithAlignPanel() ? structureState
3822 .getColourwithAlignPanel() : false);
3823 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3826 * Default colour by viewer to true if not specified (e.g. for
3829 boolean colourByViewer = jmoldat.isColourByViewer();
3830 colourByViewer &= structureState.hasColourByJmol() ? structureState
3831 .getColourByJmol() : true;
3832 jmoldat.setColourByViewer(colourByViewer);
3834 if (jmoldat.getStateData().length() < structureState
3835 .getContent().length())
3838 jmoldat.setStateData(structureState.getContent());
3841 if (ids[p].getFile() != null)
3843 File mapkey = new File(ids[p].getFile());
3844 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3845 if (seqstrmaps == null)
3847 jmoldat.getFileData().put(
3849 seqstrmaps = jmoldat.new StructureData(pdbFile,
3852 if (!seqstrmaps.getSeqList().contains(seq))
3854 seqstrmaps.getSeqList().add(seq);
3860 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");
3867 // Instantiate the associated structure views
3868 for (Entry<String, StructureViewerModel> entry : structureViewers
3873 createOrLinkStructureViewer(entry, af, ap, jprovider);
3874 } catch (Exception e)
3876 System.err.println("Error loading structure viewer: "
3878 // failed - try the next one
3890 protected void createOrLinkStructureViewer(
3891 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3892 AlignmentPanel ap, jarInputStreamProvider jprovider)
3894 final StructureViewerModel stateData = viewerData.getValue();
3897 * Search for any viewer windows already open from other alignment views
3898 * that exactly match the stored structure state
3900 StructureViewerBase comp = findMatchingViewer(viewerData);
3904 linkStructureViewer(ap, comp, stateData);
3909 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3910 * "viewer_"+stateData.viewId
3912 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3914 createChimeraViewer(viewerData, af, jprovider);
3919 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3921 createJmolViewer(viewerData, af, jprovider);
3926 * Create a new Chimera viewer.
3932 protected void createChimeraViewer(
3933 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3934 jarInputStreamProvider jprovider)
3936 StructureViewerModel data = viewerData.getValue();
3937 String chimeraSessionFile = data.getStateData();
3940 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3942 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3943 * 'uniquified' sviewid used to reconstruct the viewer here
3945 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3946 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3949 Set<Entry<File, StructureData>> fileData = data.getFileData()
3951 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3952 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3953 for (Entry<File, StructureData> pdb : fileData)
3955 String filePath = pdb.getValue().getFilePath();
3956 String pdbId = pdb.getValue().getPdbId();
3957 // pdbs.add(new PDBEntry(filePath, pdbId));
3958 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3959 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3960 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3964 boolean colourByChimera = data.isColourByViewer();
3965 boolean colourBySequence = data.isColourWithAlignPanel();
3967 // TODO use StructureViewer as a factory here, see JAL-1761
3968 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3969 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3971 String newViewId = viewerData.getKey();
3973 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3974 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3975 colourBySequence, newViewId);
3976 cvf.setSize(data.getWidth(), data.getHeight());
3977 cvf.setLocation(data.getX(), data.getY());
3981 * Create a new Jmol window. First parse the Jmol state to translate filenames
3982 * loaded into the view, and record the order in which files are shown in the
3983 * Jmol view, so we can add the sequence mappings in same order.
3989 protected void createJmolViewer(
3990 final Entry<String, StructureViewerModel> viewerData,
3991 AlignFrame af, jarInputStreamProvider jprovider)
3993 final StructureViewerModel svattrib = viewerData.getValue();
3994 String state = svattrib.getStateData();
3997 * Pre-2.9: state element value is the Jmol state string
3999 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
4002 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
4004 state = readJarEntry(jprovider,
4005 getViewerJarEntryName(svattrib.getViewId()));
4008 List<String> pdbfilenames = new ArrayList<String>();
4009 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
4010 List<String> pdbids = new ArrayList<String>();
4011 StringBuilder newFileLoc = new StringBuilder(64);
4012 int cp = 0, ncp, ecp;
4013 Map<File, StructureData> oldFiles = svattrib.getFileData();
4014 while ((ncp = state.indexOf("load ", cp)) > -1)
4018 // look for next filename in load statement
4019 newFileLoc.append(state.substring(cp,
4020 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4021 String oldfilenam = state.substring(ncp,
4022 ecp = state.indexOf("\"", ncp));
4023 // recover the new mapping data for this old filename
4024 // have to normalize filename - since Jmol and jalview do
4026 // translation differently.
4027 StructureData filedat = oldFiles.get(new File(oldfilenam));
4028 if (filedat == null)
4030 String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
4031 filedat = oldFiles.get(new File(reformatedOldFilename));
4033 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4034 pdbfilenames.add(filedat.getFilePath());
4035 pdbids.add(filedat.getPdbId());
4036 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4037 newFileLoc.append("\"");
4038 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4039 // look for next file statement.
4040 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4044 // just append rest of state
4045 newFileLoc.append(state.substring(cp));
4049 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4050 newFileLoc = new StringBuilder(state);
4051 newFileLoc.append("; load append ");
4052 for (File id : oldFiles.keySet())
4054 // add this and any other pdb files that should be present in
4056 StructureData filedat = oldFiles.get(id);
4057 newFileLoc.append(filedat.getFilePath());
4058 pdbfilenames.add(filedat.getFilePath());
4059 pdbids.add(filedat.getPdbId());
4060 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4061 newFileLoc.append(" \"");
4062 newFileLoc.append(filedat.getFilePath());
4063 newFileLoc.append("\"");
4066 newFileLoc.append(";");
4069 if (newFileLoc.length() == 0)
4073 int histbug = newFileLoc.indexOf("history = ");
4077 * change "history = [true|false];" to "history = [1|0];"
4080 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4081 String val = (diff == -1) ? null : newFileLoc
4082 .substring(histbug, diff);
4083 if (val != null && val.length() >= 4)
4085 if (val.contains("e")) // eh? what can it be?
4087 if (val.trim().equals("true"))
4095 newFileLoc.replace(histbug, diff, val);
4100 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4102 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4103 final SequenceI[][] sq = seqmaps
4104 .toArray(new SequenceI[seqmaps.size()][]);
4105 final String fileloc = newFileLoc.toString();
4106 final String sviewid = viewerData.getKey();
4107 final AlignFrame alf = af;
4108 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4109 svattrib.getWidth(), svattrib.getHeight());
4112 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4117 JalviewStructureDisplayI sview = null;
4120 sview = new StructureViewer(alf.alignPanel
4121 .getStructureSelectionManager()).createView(
4122 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4123 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4124 addNewStructureViewer(sview);
4125 } catch (OutOfMemoryError ex)
4127 new OOMWarning("restoring structure view for PDB id " + id,
4128 (OutOfMemoryError) ex.getCause());
4129 if (sview != null && sview.isVisible())
4131 sview.closeViewer(false);
4132 sview.setVisible(false);
4138 } catch (InvocationTargetException ex)
4140 warn("Unexpected error when opening Jmol view.", ex);
4142 } catch (InterruptedException e)
4144 // e.printStackTrace();
4150 * Generates a name for the entry in the project jar file to hold state
4151 * information for a structure viewer
4156 protected String getViewerJarEntryName(String viewId)
4158 return VIEWER_PREFIX + viewId;
4162 * Returns any open frame that matches given structure viewer data. The match
4163 * is based on the unique viewId, or (for older project versions) the frame's
4169 protected StructureViewerBase findMatchingViewer(
4170 Entry<String, StructureViewerModel> viewerData)
4172 final String sviewid = viewerData.getKey();
4173 final StructureViewerModel svattrib = viewerData.getValue();
4174 StructureViewerBase comp = null;
4175 JInternalFrame[] frames = getAllFrames();
4176 for (JInternalFrame frame : frames)
4178 if (frame instanceof StructureViewerBase)
4181 * Post jalview 2.4 schema includes structure view id
4184 && ((StructureViewerBase) frame).getViewId()
4187 comp = (StructureViewerBase) frame;
4188 break; // break added in 2.9
4191 * Otherwise test for matching position and size of viewer frame
4193 else if (frame.getX() == svattrib.getX()
4194 && frame.getY() == svattrib.getY()
4195 && frame.getHeight() == svattrib.getHeight()
4196 && frame.getWidth() == svattrib.getWidth())
4198 comp = (StructureViewerBase) frame;
4199 // no break in faint hope of an exact match on viewId
4207 * Link an AlignmentPanel to an existing structure viewer.
4212 * @param useinViewerSuperpos
4213 * @param usetoColourbyseq
4214 * @param viewerColouring
4216 protected void linkStructureViewer(AlignmentPanel ap,
4217 StructureViewerBase viewer, StructureViewerModel stateData)
4219 // NOTE: if the jalview project is part of a shared session then
4220 // view synchronization should/could be done here.
4222 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4223 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4224 final boolean viewerColouring = stateData.isColourByViewer();
4225 Map<File, StructureData> oldFiles = stateData.getFileData();
4228 * Add mapping for sequences in this view to an already open viewer
4230 final AAStructureBindingModel binding = viewer.getBinding();
4231 for (File id : oldFiles.keySet())
4233 // add this and any other pdb files that should be present in the
4235 StructureData filedat = oldFiles.get(id);
4236 String pdbFile = filedat.getFilePath();
4237 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4238 binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE);
4239 binding.addSequenceForStructFile(pdbFile, seq);
4241 // and add the AlignmentPanel's reference to the view panel
4242 viewer.addAlignmentPanel(ap);
4243 if (useinViewerSuperpos)
4245 viewer.useAlignmentPanelForSuperposition(ap);
4249 viewer.excludeAlignmentPanelForSuperposition(ap);
4251 if (usetoColourbyseq)
4253 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4257 viewer.excludeAlignmentPanelForColourbyseq(ap);
4262 * Get all frames within the Desktop.
4266 protected JInternalFrame[] getAllFrames()
4268 JInternalFrame[] frames = null;
4269 // TODO is this necessary - is it safe - risk of hanging?
4274 frames = Desktop.desktop.getAllFrames();
4275 } catch (ArrayIndexOutOfBoundsException e)
4277 // occasional No such child exceptions are thrown here...
4281 } catch (InterruptedException f)
4285 } while (frames == null);
4290 * Answers true if 'version' is equal to or later than 'supported', where each
4291 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4292 * changes. Development and test values for 'version' are leniently treated
4296 * - minimum version we are comparing against
4298 * - version of data being processsed
4301 public static boolean isVersionStringLaterThan(String supported,
4304 if (supported == null || version == null
4305 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4306 || version.equalsIgnoreCase("Test")
4307 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4309 System.err.println("Assuming project file with "
4310 + (version == null ? "null" : version)
4311 + " is compatible with Jalview version " + supported);
4316 return StringUtils.compareVersions(version, supported, "b") >= 0;
4320 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4322 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4324 if (newStructureViewers != null)
4326 sview.getBinding().setFinishedLoadingFromArchive(false);
4327 newStructureViewers.add(sview);
4331 protected void setLoadingFinishedForNewStructureViewers()
4333 if (newStructureViewers != null)
4335 for (JalviewStructureDisplayI sview : newStructureViewers)
4337 sview.getBinding().setFinishedLoadingFromArchive(true);
4339 newStructureViewers.clear();
4340 newStructureViewers = null;
4344 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4345 List<SequenceI> hiddenSeqs, AlignmentI al,
4346 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4347 String viewId, List<JvAnnotRow> autoAlan)
4349 AlignFrame af = null;
4350 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4351 uniqueSeqSetId, viewId);
4353 af.setFileName(file, FileFormat.Jalview);
4355 for (int i = 0; i < JSEQ.length; i++)
4357 af.viewport.setSequenceColour(af.viewport.getAlignment()
4358 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4363 af.getViewport().setColourByReferenceSeq(true);
4364 af.getViewport().setDisplayReferenceSeq(true);
4367 af.viewport.setGatherViewsHere(view.getGatheredViews());
4369 if (view.getSequenceSetId() != null)
4371 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4373 af.viewport.setSequenceSetId(uniqueSeqSetId);
4376 // propagate shared settings to this new view
4377 af.viewport.setHistoryList(av.getHistoryList());
4378 af.viewport.setRedoList(av.getRedoList());
4382 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4384 // TODO: check if this method can be called repeatedly without
4385 // side-effects if alignpanel already registered.
4386 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4388 // apply Hidden regions to view.
4389 if (hiddenSeqs != null)
4391 for (int s = 0; s < JSEQ.length; s++)
4393 SequenceGroup hidden = new SequenceGroup();
4394 boolean isRepresentative = false;
4395 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4397 isRepresentative = true;
4398 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4399 .getHiddenSequences(r));
4400 hidden.addSequence(sequenceToHide, false);
4401 // remove from hiddenSeqs list so we don't try to hide it twice
4402 hiddenSeqs.remove(sequenceToHide);
4404 if (isRepresentative)
4406 SequenceI representativeSequence = al.getSequenceAt(s);
4407 hidden.addSequence(representativeSequence, false);
4408 af.viewport.hideRepSequences(representativeSequence, hidden);
4412 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4414 af.viewport.hideSequence(hseqs);
4417 // recover view properties and display parameters
4418 if (view.getViewName() != null)
4420 af.viewport.viewName = view.getViewName();
4421 af.setInitialTabVisible();
4423 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4426 af.viewport.setShowAnnotation(view.getShowAnnotation());
4427 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4429 af.viewport.setColourText(view.getShowColourText());
4431 af.viewport.setConservationSelected(view.getConservationSelected());
4432 af.viewport.setShowJVSuffix(view.getShowFullId());
4433 af.viewport.setRightAlignIds(view.getRightAlignIds());
4434 af.viewport.setFont(
4435 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4436 .getFontSize()), true);
4437 ViewStyleI vs = af.viewport.getViewStyle();
4438 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4439 af.viewport.setViewStyle(vs);
4440 // TODO: allow custom charWidth/Heights to be restored by updating them
4441 // after setting font - which means set above to false
4442 af.viewport.setRenderGaps(view.getRenderGaps());
4443 af.viewport.setWrapAlignment(view.getWrapAlignment());
4444 af.viewport.setShowAnnotation(view.getShowAnnotation());
4446 af.viewport.setShowBoxes(view.getShowBoxes());
4448 af.viewport.setShowText(view.getShowText());
4450 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4451 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4452 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4453 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4454 .isShowUnconserved() : false);
4455 af.viewport.setStartRes(view.getStartRes());
4456 af.viewport.setStartSeq(view.getStartSeq());
4457 af.alignPanel.updateLayout();
4458 ColourSchemeI cs = null;
4459 // apply colourschemes
4460 if (view.getBgColour() != null)
4462 if (view.getBgColour().startsWith("ucs"))
4464 cs = getUserColourScheme(jms, view.getBgColour());
4466 else if (view.getBgColour().startsWith("Annotation"))
4468 AnnotationColours viewAnnColour = view.getAnnotationColours();
4469 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4476 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4481 cs.setThreshold(view.getPidThreshold(), true);
4482 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4486 af.viewport.setGlobalColourScheme(cs);
4487 af.viewport.setColourAppliesToAllGroups(false);
4489 if (view.getConservationSelected() && cs != null)
4491 cs.setConservationInc(view.getConsThreshold());
4494 af.changeColour(cs);
4496 af.viewport.setColourAppliesToAllGroups(true);
4498 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4500 if (view.hasCentreColumnLabels())
4502 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4504 if (view.hasIgnoreGapsinConsensus())
4506 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4509 if (view.hasFollowHighlight())
4511 af.viewport.setFollowHighlight(view.getFollowHighlight());
4513 if (view.hasFollowSelection())
4515 af.viewport.followSelection = view.getFollowSelection();
4517 if (view.hasShowConsensusHistogram())
4519 af.viewport.setShowConsensusHistogram(view
4520 .getShowConsensusHistogram());
4524 af.viewport.setShowConsensusHistogram(true);
4526 if (view.hasShowSequenceLogo())
4528 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4532 af.viewport.setShowSequenceLogo(false);
4534 if (view.hasNormaliseSequenceLogo())
4536 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4538 if (view.hasShowDbRefTooltip())
4540 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4542 if (view.hasShowNPfeatureTooltip())
4544 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4546 if (view.hasShowGroupConsensus())
4548 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4552 af.viewport.setShowGroupConsensus(false);
4554 if (view.hasShowGroupConservation())
4556 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4560 af.viewport.setShowGroupConservation(false);
4563 // recover featre settings
4564 if (jms.getFeatureSettings() != null)
4566 FeaturesDisplayed fdi;
4567 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4568 String[] renderOrder = new String[jms.getFeatureSettings()
4569 .getSettingCount()];
4570 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4571 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4573 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4575 Setting setting = jms.getFeatureSettings().getSetting(fs);
4576 if (setting.hasMincolour())
4578 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4579 new Color(setting.getMincolour()), new Color(
4580 setting.getColour()), setting.getMin(),
4581 setting.getMax()) : new FeatureColour(new Color(
4582 setting.getMincolour()), new Color(setting.getColour()),
4584 if (setting.hasThreshold())
4586 gc.setThreshold(setting.getThreshold());
4587 int threshstate = setting.getThreshstate();
4588 // -1 = None, 0 = Below, 1 = Above threshold
4589 if (threshstate == 0)
4591 gc.setBelowThreshold(true);
4593 else if (threshstate == 1)
4595 gc.setAboveThreshold(true);
4598 gc.setAutoScaled(true); // default
4599 if (setting.hasAutoScale())
4601 gc.setAutoScaled(setting.getAutoScale());
4603 if (setting.hasColourByLabel())
4605 gc.setColourByLabel(setting.getColourByLabel());
4607 // and put in the feature colour table.
4608 featureColours.put(setting.getType(), gc);
4612 featureColours.put(setting.getType(), new FeatureColour(
4613 new Color(setting.getColour())));
4615 renderOrder[fs] = setting.getType();
4616 if (setting.hasOrder())
4618 featureOrder.put(setting.getType(), setting.getOrder());
4622 featureOrder.put(setting.getType(), new Float(fs
4623 / jms.getFeatureSettings().getSettingCount()));
4625 if (setting.getDisplay())
4627 fdi.setVisible(setting.getType());
4630 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4631 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4633 Group grp = jms.getFeatureSettings().getGroup(gs);
4634 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4636 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4637 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4638 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4639 FeatureRendererSettings frs = new FeatureRendererSettings(
4640 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4641 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4642 .transferSettings(frs);
4646 if (view.getHiddenColumnsCount() > 0)
4648 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4650 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4651 .getHiddenColumns(c).getEnd() // +1
4655 if (view.getCalcIdParam() != null)
4657 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4659 if (calcIdParam != null)
4661 if (recoverCalcIdParam(calcIdParam, af.viewport))
4666 warn("Couldn't recover parameters for "
4667 + calcIdParam.getCalcId());
4672 af.setMenusFromViewport(af.viewport);
4673 af.setTitle(view.getTitle());
4674 // TODO: we don't need to do this if the viewport is aready visible.
4676 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4677 * has a 'cdna/protein complement' view, in which case save it in order to
4678 * populate a SplitFrame once all views have been read in.
4680 String complementaryViewId = view.getComplementId();
4681 if (complementaryViewId == null)
4683 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4685 // recompute any autoannotation
4686 af.alignPanel.updateAnnotation(false, true);
4687 reorderAutoannotation(af, al, autoAlan);
4688 af.alignPanel.alignmentChanged();
4692 splitFrameCandidates.put(view, af);
4697 private ColourSchemeI constructAnnotationColour(
4698 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4699 JalviewModelSequence jms, boolean checkGroupAnnColour)
4701 boolean propagateAnnColour = false;
4702 AnnotationColourGradient cs = null;
4703 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4704 if (checkGroupAnnColour && al.getGroups() != null
4705 && al.getGroups().size() > 0)
4707 // pre 2.8.1 behaviour
4708 // check to see if we should transfer annotation colours
4709 propagateAnnColour = true;
4710 for (SequenceGroup sg : al.getGroups())
4712 if (sg.cs instanceof AnnotationColourGradient)
4714 propagateAnnColour = false;
4720 * pre 2.10.2: annotationId is AlignmentAnnotation.label
4721 * 2.10.2- : annotationId is AlignmentAnnotation.annotationId
4723 String annotationId = viewAnnColour.getAnnotation();
4724 AlignmentAnnotation annotation = annotationIds.get(annotationId);
4726 if (annotation == null && annAlignment.getAlignmentAnnotation() != null)
4728 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4731 .equals(annAlignment.getAlignmentAnnotation()[i].label))
4733 annotation = annAlignment.getAlignmentAnnotation()[i];
4738 if (annotation == null)
4740 System.err.println("Failed to match annotation colour scheme for "
4744 if (annotation.getThreshold() == null)
4746 annotation.setThreshold(new GraphLine(viewAnnColour.getThreshold(),
4747 "Threshold", Color.black));
4750 if (viewAnnColour.getColourScheme().equals("None"))
4752 cs = new AnnotationColourGradient(annotation, new Color(
4753 viewAnnColour.getMinColour()), new Color(
4754 viewAnnColour.getMaxColour()),
4755 viewAnnColour.getAboveThreshold());
4757 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4759 cs = new AnnotationColourGradient(annotation, getUserColourScheme(
4760 jms, viewAnnColour.getColourScheme()),
4761 viewAnnColour.getAboveThreshold());
4765 cs = new AnnotationColourGradient(annotation,
4766 ColourSchemeProperty.getColour(al,
4767 viewAnnColour.getColourScheme()),
4768 viewAnnColour.getAboveThreshold());
4770 if (viewAnnColour.hasPerSequence())
4772 cs.setSeqAssociated(viewAnnColour.isPerSequence());
4774 if (viewAnnColour.hasPredefinedColours())
4776 cs.setPredefinedColours(viewAnnColour.isPredefinedColours());
4778 if (propagateAnnColour && al.getGroups() != null)
4780 // Also use these settings for all the groups
4781 for (int g = 0; g < al.getGroups().size(); g++)
4783 SequenceGroup sg = al.getGroups().get(g);
4791 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4792 * new AnnotationColourGradient(
4793 * annAlignment.getAlignmentAnnotation()[i], new
4794 * java.awt.Color(viewAnnColour. getMinColour()), new
4795 * java.awt.Color(viewAnnColour. getMaxColour()),
4796 * viewAnnColour.getAboveThreshold()); } else
4799 sg.cs = new AnnotationColourGradient(annotation, sg.cs,
4800 viewAnnColour.getAboveThreshold());
4801 if (cs instanceof AnnotationColourGradient)
4803 if (viewAnnColour.hasPerSequence())
4805 cs.setSeqAssociated(viewAnnColour.isPerSequence());
4807 if (viewAnnColour.hasPredefinedColours())
4809 cs.setPredefinedColours(viewAnnColour.isPredefinedColours());
4817 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4818 List<JvAnnotRow> autoAlan)
4820 // copy over visualization settings for autocalculated annotation in the
4822 if (al.getAlignmentAnnotation() != null)
4825 * Kludge for magic autoannotation names (see JAL-811)
4827 String[] magicNames = new String[] { "Consensus", "Quality",
4829 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4830 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4831 for (String nm : magicNames)
4833 visan.put(nm, nullAnnot);
4835 for (JvAnnotRow auan : autoAlan)
4837 visan.put(auan.template.label
4838 + (auan.template.getCalcId() == null ? "" : "\t"
4839 + auan.template.getCalcId()), auan);
4841 int hSize = al.getAlignmentAnnotation().length;
4842 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4843 // work through any autoCalculated annotation already on the view
4844 // removing it if it should be placed in a different location on the
4845 // annotation panel.
4846 List<String> remains = new ArrayList<String>(visan.keySet());
4847 for (int h = 0; h < hSize; h++)
4849 jalview.datamodel.AlignmentAnnotation jalan = al
4850 .getAlignmentAnnotation()[h];
4851 if (jalan.autoCalculated)
4854 JvAnnotRow valan = visan.get(k = jalan.label);
4855 if (jalan.getCalcId() != null)
4857 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4862 // delete the auto calculated row from the alignment
4863 al.deleteAnnotation(jalan, false);
4867 if (valan != nullAnnot)
4869 if (jalan != valan.template)
4871 // newly created autoannotation row instance
4872 // so keep a reference to the visible annotation row
4873 // and copy over all relevant attributes
4874 if (valan.template.graphHeight >= 0)
4877 jalan.graphHeight = valan.template.graphHeight;
4879 jalan.visible = valan.template.visible;
4881 reorder.add(new JvAnnotRow(valan.order, jalan));
4886 // Add any (possibly stale) autocalculated rows that were not appended to
4887 // the view during construction
4888 for (String other : remains)
4890 JvAnnotRow othera = visan.get(other);
4891 if (othera != nullAnnot && othera.template.getCalcId() != null
4892 && othera.template.getCalcId().length() > 0)
4894 reorder.add(othera);
4897 // now put the automatic annotation in its correct place
4898 int s = 0, srt[] = new int[reorder.size()];
4899 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4900 for (JvAnnotRow jvar : reorder)
4903 srt[s++] = jvar.order;
4906 jalview.util.QuickSort.sort(srt, rws);
4907 // and re-insert the annotation at its correct position
4908 for (JvAnnotRow jvar : rws)
4910 al.addAnnotation(jvar.template, jvar.order);
4912 af.alignPanel.adjustAnnotationHeight();
4916 Hashtable skipList = null;
4919 * TODO remove this method
4922 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4923 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4924 * throw new Error("Implementation Error. No skipList defined for this
4925 * Jalview2XML instance."); } return (AlignFrame)
4926 * skipList.get(view.getSequenceSetId()); }
4930 * Check if the Jalview view contained in object should be skipped or not.
4933 * @return true if view's sequenceSetId is a key in skipList
4935 private boolean skipViewport(JalviewModel object)
4937 if (skipList == null)
4942 if (skipList.containsKey(id = object.getJalviewModelSequence()
4943 .getViewport()[0].getSequenceSetId()))
4945 if (Cache.log != null && Cache.log.isDebugEnabled())
4947 Cache.log.debug("Skipping seuqence set id " + id);
4954 public void addToSkipList(AlignFrame af)
4956 if (skipList == null)
4958 skipList = new Hashtable();
4960 skipList.put(af.getViewport().getSequenceSetId(), af);
4963 public void clearSkipList()
4965 if (skipList != null)
4972 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4973 boolean ignoreUnrefed)
4975 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4977 Vector dseqs = null;
4980 // create a list of new dataset sequences
4981 dseqs = new Vector();
4983 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4985 Sequence vamsasSeq = vamsasSet.getSequence(i);
4986 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4988 // create a new dataset
4991 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4992 dseqs.copyInto(dsseqs);
4993 ds = new jalview.datamodel.Alignment(dsseqs);
4994 debug("Created new dataset " + vamsasSet.getDatasetId()
4995 + " for alignment " + System.identityHashCode(al));
4996 addDatasetRef(vamsasSet.getDatasetId(), ds);
4998 // set the dataset for the newly imported alignment.
4999 if (al.getDataset() == null && !ignoreUnrefed)
5008 * sequence definition to create/merge dataset sequence for
5012 * vector to add new dataset sequence to
5013 * @param ignoreUnrefed
5014 * - when true, don't create new sequences from vamsasSeq if it's id
5015 * doesn't already have an asssociated Jalview sequence.
5017 * - used to reorder the sequence in the alignment according to the
5018 * vamsasSeq array ordering, to preserve ordering of dataset
5020 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5021 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5023 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5025 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5026 boolean reorder = false;
5027 SequenceI dsq = null;
5028 if (sq != null && sq.getDatasetSequence() != null)
5030 dsq = sq.getDatasetSequence();
5036 if (sq == null && ignoreUnrefed)
5040 String sqid = vamsasSeq.getDsseqid();
5043 // need to create or add a new dataset sequence reference to this sequence
5046 dsq = seqRefIds.get(sqid);
5051 // make a new dataset sequence
5052 dsq = sq.createDatasetSequence();
5055 // make up a new dataset reference for this sequence
5056 sqid = seqHash(dsq);
5058 dsq.setVamsasId(uniqueSetSuffix + sqid);
5059 seqRefIds.put(sqid, dsq);
5064 dseqs.addElement(dsq);
5069 ds.addSequence(dsq);
5075 { // make this dataset sequence sq's dataset sequence
5076 sq.setDatasetSequence(dsq);
5077 // and update the current dataset alignment
5082 if (!dseqs.contains(dsq))
5089 if (ds.findIndex(dsq) < 0)
5091 ds.addSequence(dsq);
5098 // TODO: refactor this as a merge dataset sequence function
5099 // now check that sq (the dataset sequence) sequence really is the union of
5100 // all references to it
5101 // boolean pre = sq.getStart() < dsq.getStart();
5102 // boolean post = sq.getEnd() > dsq.getEnd();
5106 // StringBuffer sb = new StringBuffer();
5107 String newres = jalview.analysis.AlignSeq.extractGaps(
5108 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5109 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5110 && newres.length() > dsq.getLength())
5112 // Update with the longer sequence.
5116 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5117 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5118 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5119 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5121 dsq.setSequence(newres);
5123 // TODO: merges will never happen if we 'know' we have the real dataset
5124 // sequence - this should be detected when id==dssid
5126 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5127 // + (pre ? "prepended" : "") + " "
5128 // + (post ? "appended" : ""));
5133 // sequence refs are identical. We may need to update the existing dataset
5134 // alignment with this one, though.
5135 if (ds != null && dseqs == null)
5137 int opos = ds.findIndex(dsq);
5138 SequenceI tseq = null;
5139 if (opos != -1 && vseqpos != opos)
5141 // remove from old position
5142 ds.deleteSequence(dsq);
5144 if (vseqpos < ds.getHeight())
5146 if (vseqpos != opos)
5148 // save sequence at destination position
5149 tseq = ds.getSequenceAt(vseqpos);
5150 ds.replaceSequenceAt(vseqpos, dsq);
5151 ds.addSequence(tseq);
5156 ds.addSequence(dsq);
5163 * TODO use AlignmentI here and in related methods - needs
5164 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5166 Hashtable<String, AlignmentI> datasetIds = null;
5168 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5170 private AlignmentI getDatasetFor(String datasetId)
5172 if (datasetIds == null)
5174 datasetIds = new Hashtable<String, AlignmentI>();
5177 if (datasetIds.containsKey(datasetId))
5179 return datasetIds.get(datasetId);
5184 private void addDatasetRef(String datasetId, AlignmentI dataset)
5186 if (datasetIds == null)
5188 datasetIds = new Hashtable<String, AlignmentI>();
5190 datasetIds.put(datasetId, dataset);
5194 * make a new dataset ID for this jalview dataset alignment
5199 private String getDatasetIdRef(AlignmentI dataset)
5201 if (dataset.getDataset() != null)
5203 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5205 String datasetId = makeHashCode(dataset, null);
5206 if (datasetId == null)
5208 // make a new datasetId and record it
5209 if (dataset2Ids == null)
5211 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5215 datasetId = dataset2Ids.get(dataset);
5217 if (datasetId == null)
5219 datasetId = "ds" + dataset2Ids.size() + 1;
5220 dataset2Ids.put(dataset, datasetId);
5226 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5228 for (int d = 0; d < sequence.getDBRefCount(); d++)
5230 DBRef dr = sequence.getDBRef(d);
5231 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5232 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5233 .getVersion(), sequence.getDBRef(d).getAccessionId());
5234 if (dr.getMapping() != null)
5236 entry.setMap(addMapping(dr.getMapping()));
5238 datasetSequence.addDBRef(entry);
5242 private jalview.datamodel.Mapping addMapping(Mapping m)
5244 SequenceI dsto = null;
5245 // Mapping m = dr.getMapping();
5246 int fr[] = new int[m.getMapListFromCount() * 2];
5247 Enumeration f = m.enumerateMapListFrom();
5248 for (int _i = 0; f.hasMoreElements(); _i += 2)
5250 MapListFrom mf = (MapListFrom) f.nextElement();
5251 fr[_i] = mf.getStart();
5252 fr[_i + 1] = mf.getEnd();
5254 int fto[] = new int[m.getMapListToCount() * 2];
5255 f = m.enumerateMapListTo();
5256 for (int _i = 0; f.hasMoreElements(); _i += 2)
5258 MapListTo mf = (MapListTo) f.nextElement();
5259 fto[_i] = mf.getStart();
5260 fto[_i + 1] = mf.getEnd();
5262 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5263 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5264 if (m.getMappingChoice() != null)
5266 MappingChoice mc = m.getMappingChoice();
5267 if (mc.getDseqFor() != null)
5269 String dsfor = "" + mc.getDseqFor();
5270 if (seqRefIds.containsKey(dsfor))
5275 jmap.setTo(seqRefIds.get(dsfor));
5279 frefedSequence.add(newMappingRef(dsfor, jmap));
5285 * local sequence definition
5287 Sequence ms = mc.getSequence();
5288 SequenceI djs = null;
5289 String sqid = ms.getDsseqid();
5290 if (sqid != null && sqid.length() > 0)
5293 * recover dataset sequence
5295 djs = seqRefIds.get(sqid);
5300 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5301 sqid = ((Object) ms).toString(); // make up a new hascode for
5302 // undefined dataset sequence hash
5303 // (unlikely to happen)
5309 * make a new dataset sequence and add it to refIds hash
5311 djs = new jalview.datamodel.Sequence(ms.getName(),
5313 djs.setStart(jmap.getMap().getToLowest());
5314 djs.setEnd(jmap.getMap().getToHighest());
5315 djs.setVamsasId(uniqueSetSuffix + sqid);
5317 incompleteSeqs.put(sqid, djs);
5318 seqRefIds.put(sqid, djs);
5321 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5330 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5331 boolean keepSeqRefs)
5334 JalviewModel jm = saveState(ap, null, null, null);
5339 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5343 uniqueSetSuffix = "";
5344 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5349 if (this.frefedSequence == null)
5351 frefedSequence = new Vector();
5354 viewportsAdded.clear();
5356 AlignFrame af = loadFromObject(jm, null, false, null);
5357 af.alignPanels.clear();
5358 af.closeMenuItem_actionPerformed(true);
5361 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5362 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5363 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5364 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5365 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5368 return af.alignPanel;
5372 * flag indicating if hashtables should be cleared on finalization TODO this
5373 * flag may not be necessary
5375 private final boolean _cleartables = true;
5377 private Hashtable jvids2vobj;
5382 * @see java.lang.Object#finalize()
5385 protected void finalize() throws Throwable
5387 // really make sure we have no buried refs left.
5392 this.seqRefIds = null;
5393 this.seqsToIds = null;
5397 private void warn(String msg)
5402 private void warn(String msg, Exception e)
5404 if (Cache.log != null)
5408 Cache.log.warn(msg, e);
5412 Cache.log.warn(msg);
5417 System.err.println("Warning: " + msg);
5420 e.printStackTrace();
5425 private void debug(String string)
5427 debug(string, null);
5430 private void debug(String msg, Exception e)
5432 if (Cache.log != null)
5436 Cache.log.debug(msg, e);
5440 Cache.log.debug(msg);
5445 System.err.println("Warning: " + msg);
5448 e.printStackTrace();
5454 * set the object to ID mapping tables used to write/recover objects and XML
5455 * ID strings for the jalview project. If external tables are provided then
5456 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5457 * object goes out of scope. - also populates the datasetIds hashtable with
5458 * alignment objects containing dataset sequences
5461 * Map from ID strings to jalview datamodel
5463 * Map from jalview datamodel to ID strings
5467 public void setObjectMappingTables(Hashtable vobj2jv,
5468 IdentityHashMap jv2vobj)
5470 this.jv2vobj = jv2vobj;
5471 this.vobj2jv = vobj2jv;
5472 Iterator ds = jv2vobj.keySet().iterator();
5474 while (ds.hasNext())
5476 Object jvobj = ds.next();
5477 id = jv2vobj.get(jvobj).toString();
5478 if (jvobj instanceof jalview.datamodel.Alignment)
5480 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5482 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5485 else if (jvobj instanceof jalview.datamodel.Sequence)
5487 // register sequence object so the XML parser can recover it.
5488 if (seqRefIds == null)
5490 seqRefIds = new HashMap<String, SequenceI>();
5492 if (seqsToIds == null)
5494 seqsToIds = new IdentityHashMap<SequenceI, String>();
5496 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5497 seqsToIds.put((SequenceI) jvobj, id);
5499 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5502 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5503 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5504 if (jvann.annotationId == null)
5506 jvann.annotationId = anid;
5508 if (!jvann.annotationId.equals(anid))
5510 // TODO verify that this is the correct behaviour
5511 this.warn("Overriding Annotation ID for " + anid
5512 + " from different id : " + jvann.annotationId);
5513 jvann.annotationId = anid;
5516 else if (jvobj instanceof String)
5518 if (jvids2vobj == null)
5520 jvids2vobj = new Hashtable();
5521 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5526 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5532 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5533 * objects created from the project archive. If string is null (default for
5534 * construction) then suffix will be set automatically.
5538 public void setUniqueSetSuffix(String string)
5540 uniqueSetSuffix = string;
5545 * uses skipList2 as the skipList for skipping views on sequence sets
5546 * associated with keys in the skipList
5550 public void setSkipList(Hashtable skipList2)
5552 skipList = skipList2;
5556 * Reads the jar entry of given name and returns its contents, or null if the
5557 * entry is not found.
5560 * @param jarEntryName
5563 protected String readJarEntry(jarInputStreamProvider jprovider,
5564 String jarEntryName)
5566 String result = null;
5567 BufferedReader in = null;
5572 * Reopen the jar input stream and traverse its entries to find a matching
5575 JarInputStream jin = jprovider.getJarInputStream();
5576 JarEntry entry = null;
5579 entry = jin.getNextJarEntry();
5580 } while (entry != null && !entry.getName().equals(jarEntryName));
5584 StringBuilder out = new StringBuilder(256);
5585 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5588 while ((data = in.readLine()) != null)
5592 result = out.toString();
5596 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5598 } catch (Exception ex)
5600 ex.printStackTrace();
5608 } catch (IOException e)
5619 * Returns an incrementing counter (0, 1, 2...)
5623 private synchronized int nextCounter()