2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.FeatureColourI;
24 import jalview.api.ViewStyleI;
25 import jalview.api.structures.JalviewStructureDisplayI;
26 import jalview.bin.Cache;
27 import jalview.datamodel.AlignedCodonFrame;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.PDBEntry;
32 import jalview.datamodel.RnaViewerModel;
33 import jalview.datamodel.SequenceGroup;
34 import jalview.datamodel.SequenceI;
35 import jalview.datamodel.StructureViewerModel;
36 import jalview.datamodel.StructureViewerModel.StructureData;
37 import jalview.ext.varna.RnaModel;
38 import jalview.gui.StructureViewer.ViewerType;
39 import jalview.io.DataSourceType;
40 import jalview.io.FileFormat;
41 import jalview.schemabinding.version2.AlcodMap;
42 import jalview.schemabinding.version2.AlcodonFrame;
43 import jalview.schemabinding.version2.Annotation;
44 import jalview.schemabinding.version2.AnnotationColours;
45 import jalview.schemabinding.version2.AnnotationElement;
46 import jalview.schemabinding.version2.CalcIdParam;
47 import jalview.schemabinding.version2.DBRef;
48 import jalview.schemabinding.version2.Features;
49 import jalview.schemabinding.version2.Group;
50 import jalview.schemabinding.version2.HiddenColumns;
51 import jalview.schemabinding.version2.JGroup;
52 import jalview.schemabinding.version2.JSeq;
53 import jalview.schemabinding.version2.JalviewModel;
54 import jalview.schemabinding.version2.JalviewModelSequence;
55 import jalview.schemabinding.version2.MapListFrom;
56 import jalview.schemabinding.version2.MapListTo;
57 import jalview.schemabinding.version2.Mapping;
58 import jalview.schemabinding.version2.MappingChoice;
59 import jalview.schemabinding.version2.OtherData;
60 import jalview.schemabinding.version2.PdbentryItem;
61 import jalview.schemabinding.version2.Pdbids;
62 import jalview.schemabinding.version2.Property;
63 import jalview.schemabinding.version2.RnaViewer;
64 import jalview.schemabinding.version2.SecondaryStructure;
65 import jalview.schemabinding.version2.Sequence;
66 import jalview.schemabinding.version2.SequenceSet;
67 import jalview.schemabinding.version2.SequenceSetProperties;
68 import jalview.schemabinding.version2.Setting;
69 import jalview.schemabinding.version2.StructureState;
70 import jalview.schemabinding.version2.ThresholdLine;
71 import jalview.schemabinding.version2.Tree;
72 import jalview.schemabinding.version2.UserColours;
73 import jalview.schemabinding.version2.Viewport;
74 import jalview.schemes.AnnotationColourGradient;
75 import jalview.schemes.ColourSchemeI;
76 import jalview.schemes.ColourSchemeProperty;
77 import jalview.schemes.FeatureColour;
78 import jalview.schemes.ResidueColourScheme;
79 import jalview.schemes.ResidueProperties;
80 import jalview.schemes.UserColourScheme;
81 import jalview.structure.StructureSelectionManager;
82 import jalview.structures.models.AAStructureBindingModel;
83 import jalview.util.MessageManager;
84 import jalview.util.Platform;
85 import jalview.util.StringUtils;
86 import jalview.util.jarInputStreamProvider;
87 import jalview.viewmodel.AlignmentViewport;
88 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
89 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
90 import jalview.ws.jws2.Jws2Discoverer;
91 import jalview.ws.jws2.dm.AAConSettings;
92 import jalview.ws.jws2.jabaws2.Jws2Instance;
93 import jalview.ws.params.ArgumentI;
94 import jalview.ws.params.AutoCalcSetting;
95 import jalview.ws.params.WsParamSetI;
97 import java.awt.Color;
98 import java.awt.Rectangle;
99 import java.io.BufferedReader;
100 import java.io.DataInputStream;
101 import java.io.DataOutputStream;
103 import java.io.FileInputStream;
104 import java.io.FileOutputStream;
105 import java.io.IOException;
106 import java.io.InputStreamReader;
107 import java.io.OutputStreamWriter;
108 import java.io.PrintWriter;
109 import java.lang.reflect.InvocationTargetException;
110 import java.net.MalformedURLException;
112 import java.util.ArrayList;
113 import java.util.Arrays;
114 import java.util.Enumeration;
115 import java.util.HashMap;
116 import java.util.HashSet;
117 import java.util.Hashtable;
118 import java.util.IdentityHashMap;
119 import java.util.Iterator;
120 import java.util.LinkedHashMap;
121 import java.util.List;
122 import java.util.Map;
123 import java.util.Map.Entry;
124 import java.util.Set;
125 import java.util.Vector;
126 import java.util.jar.JarEntry;
127 import java.util.jar.JarInputStream;
128 import java.util.jar.JarOutputStream;
130 import javax.swing.JInternalFrame;
131 import javax.swing.JOptionPane;
132 import javax.swing.SwingUtilities;
134 import org.exolab.castor.xml.Marshaller;
135 import org.exolab.castor.xml.Unmarshaller;
138 * Write out the current jalview desktop state as a Jalview XML stream.
140 * Note: the vamsas objects referred to here are primitive versions of the
141 * VAMSAS project schema elements - they are not the same and most likely never
145 * @version $Revision: 1.134 $
147 public class Jalview2XML
149 private static final String VIEWER_PREFIX = "viewer_";
151 private static final String RNA_PREFIX = "rna_";
153 private static final String UTF_8 = "UTF-8";
155 // use this with nextCounter() to make unique names for entities
156 private int counter = 0;
159 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
160 * of sequence objects are created.
162 IdentityHashMap<SequenceI, String> seqsToIds = null;
165 * jalview XML Sequence ID to jalview sequence object reference (both dataset
166 * and alignment sequences. Populated as XML reps of sequence objects are
169 Map<String, SequenceI> seqRefIds = null;
171 Map<String, SequenceI> incompleteSeqs = null;
173 List<SeqFref> frefedSequence = null;
175 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
178 * Map of reconstructed AlignFrame objects that appear to have come from
179 * SplitFrame objects (have a dna/protein complement view).
181 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
184 * Map from displayed rna structure models to their saved session state jar
187 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
190 * create/return unique hash string for sq
193 * @return new or existing unique string for sq
195 String seqHash(SequenceI sq)
197 if (seqsToIds == null)
201 if (seqsToIds.containsKey(sq))
203 return seqsToIds.get(sq);
207 // create sequential key
208 String key = "sq" + (seqsToIds.size() + 1);
209 key = makeHashCode(sq, key); // check we don't have an external reference
211 seqsToIds.put(sq, key);
220 if (seqRefIds != null)
224 if (seqsToIds != null)
228 if (incompleteSeqs != null)
230 incompleteSeqs.clear();
238 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
239 // seqRefIds = new Hashtable();
240 // seqsToIds = new IdentityHashMap();
246 if (seqsToIds == null)
248 seqsToIds = new IdentityHashMap<SequenceI, String>();
250 if (seqRefIds == null)
252 seqRefIds = new HashMap<String, SequenceI>();
254 if (incompleteSeqs == null)
256 incompleteSeqs = new HashMap<String, SequenceI>();
258 if (frefedSequence == null)
260 frefedSequence = new ArrayList<SeqFref>();
268 public Jalview2XML(boolean raiseGUI)
270 this.raiseGUI = raiseGUI;
274 * base class for resolving forward references to sequences by their ID
279 abstract class SeqFref
285 public SeqFref(String _sref, String type)
291 public String getSref()
296 public SequenceI getSrefSeq()
298 return seqRefIds.get(sref);
301 public boolean isResolvable()
303 return seqRefIds.get(sref) != null;
306 public SequenceI getSrefDatasetSeq()
308 SequenceI sq = seqRefIds.get(sref);
311 while (sq.getDatasetSequence() != null)
313 sq = sq.getDatasetSequence();
319 * @return true if the forward reference was fully resolved
321 abstract boolean resolve();
324 public String toString()
326 return type + " reference to " + sref;
331 * create forward reference for a mapping
337 public SeqFref newMappingRef(final String sref,
338 final jalview.datamodel.Mapping _jmap)
340 SeqFref fref = new SeqFref(sref, "Mapping")
342 public jalview.datamodel.Mapping jmap = _jmap;
347 SequenceI seq = getSrefDatasetSeq();
359 public SeqFref newAlcodMapRef(final String sref,
360 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
363 SeqFref fref = new SeqFref(sref, "Codon Frame")
365 AlignedCodonFrame cf = _cf;
367 public jalview.datamodel.Mapping mp = _jmap;
372 SequenceI seq = getSrefDatasetSeq();
377 cf.addMap(seq, mp.getTo(), mp.getMap());
384 public void resolveFrefedSequences()
386 Iterator<SeqFref> nextFref=frefedSequence.iterator();
387 int toresolve=frefedSequence.size();
388 int unresolved=0,failedtoresolve=0;
389 while (nextFref.hasNext()) {
390 SeqFref ref = nextFref.next();
391 if (ref.isResolvable())
400 } catch (Exception x) {
401 System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
411 System.err.println("Jalview Project Import: There were " + unresolved
412 + " forward references left unresolved on the stack.");
414 if (failedtoresolve>0)
416 System.err.println("SERIOUS! " + failedtoresolve
417 + " resolvable forward references failed to resolve.");
419 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
421 System.err.println("Jalview Project Import: There are "
422 + incompleteSeqs.size()
423 + " sequences which may have incomplete metadata.");
424 if (incompleteSeqs.size() < 10)
426 for (SequenceI s : incompleteSeqs.values())
428 System.err.println(s.toString());
434 .println("Too many to report. Skipping output of incomplete sequences.");
440 * This maintains a map of viewports, the key being the seqSetId. Important to
441 * set historyItem and redoList for multiple views
443 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
445 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
447 String uniqueSetSuffix = "";
450 * List of pdbfiles added to Jar
452 List<String> pdbfiles = null;
454 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
455 public void saveState(File statefile)
457 FileOutputStream fos = null;
460 fos = new FileOutputStream(statefile);
461 JarOutputStream jout = new JarOutputStream(fos);
464 } catch (Exception e)
466 // TODO: inform user of the problem - they need to know if their data was
468 if (errorMessage == null)
470 errorMessage = "Couldn't write Jalview Archive to output file '"
471 + statefile + "' - See console error log for details";
475 errorMessage += "(output file was '" + statefile + "')";
485 } catch (IOException e)
495 * Writes a jalview project archive to the given Jar output stream.
499 public void saveState(JarOutputStream jout)
501 AlignFrame[] frames = Desktop.getAlignFrames();
507 saveAllFrames(Arrays.asList(frames), jout);
511 * core method for storing state for a set of AlignFrames.
514 * - frames involving all data to be exported (including containing
517 * - project output stream
519 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
521 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
524 * ensure cached data is clear before starting
526 // todo tidy up seqRefIds, seqsToIds initialisation / reset
528 splitFrameCandidates.clear();
533 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
534 // //////////////////////////////////////////////////
536 List<String> shortNames = new ArrayList<String>();
537 List<String> viewIds = new ArrayList<String>();
540 for (int i = frames.size() - 1; i > -1; i--)
542 AlignFrame af = frames.get(i);
546 .containsKey(af.getViewport().getSequenceSetId()))
551 String shortName = makeFilename(af, shortNames);
553 int ap, apSize = af.alignPanels.size();
555 for (ap = 0; ap < apSize; ap++)
557 AlignmentPanel apanel = af.alignPanels.get(ap);
558 String fileName = apSize == 1 ? shortName : ap + shortName;
559 if (!fileName.endsWith(".xml"))
561 fileName = fileName + ".xml";
564 saveState(apanel, fileName, jout, viewIds);
566 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
568 if (!dsses.containsKey(dssid))
570 dsses.put(dssid, af);
575 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
581 } catch (Exception foo)
586 } catch (Exception ex)
588 // TODO: inform user of the problem - they need to know if their data was
590 if (errorMessage == null)
592 errorMessage = "Couldn't write Jalview Archive - see error output for details";
594 ex.printStackTrace();
599 * Generates a distinct file name, based on the title of the AlignFrame, by
600 * appending _n for increasing n until an unused name is generated. The new
601 * name (without its extension) is added to the list.
605 * @return the generated name, with .xml extension
607 protected String makeFilename(AlignFrame af, List<String> namesUsed)
609 String shortName = af.getTitle();
611 if (shortName.indexOf(File.separatorChar) > -1)
613 shortName = shortName.substring(shortName
614 .lastIndexOf(File.separatorChar) + 1);
619 while (namesUsed.contains(shortName))
621 if (shortName.endsWith("_" + (count - 1)))
623 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
626 shortName = shortName.concat("_" + count);
630 namesUsed.add(shortName);
632 if (!shortName.endsWith(".xml"))
634 shortName = shortName + ".xml";
639 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
640 public boolean saveAlignment(AlignFrame af, String jarFile,
645 FileOutputStream fos = new FileOutputStream(jarFile);
646 JarOutputStream jout = new JarOutputStream(fos);
647 List<AlignFrame> frames = new ArrayList<AlignFrame>();
649 // resolve splitframes
650 if (af.getViewport().getCodingComplement() != null)
652 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
658 saveAllFrames(frames, jout);
662 } catch (Exception foo)
668 } catch (Exception ex)
670 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
671 ex.printStackTrace();
676 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
677 String fileName, JarOutputStream jout)
680 for (String dssids : dsses.keySet())
682 AlignFrame _af = dsses.get(dssids);
683 String jfileName = fileName + " Dataset for " + _af.getTitle();
684 if (!jfileName.endsWith(".xml"))
686 jfileName = jfileName + ".xml";
688 saveState(_af.alignPanel, jfileName, true, jout, null);
693 * create a JalviewModel from an alignment view and marshall it to a
697 * panel to create jalview model for
699 * name of alignment panel written to output stream
706 public JalviewModel saveState(AlignmentPanel ap, String fileName,
707 JarOutputStream jout, List<String> viewIds)
709 return saveState(ap, fileName, false, jout, viewIds);
713 * create a JalviewModel from an alignment view and marshall it to a
717 * panel to create jalview model for
719 * name of alignment panel written to output stream
721 * when true, only write the dataset for the alignment, not the data
722 * associated with the view.
728 public JalviewModel saveState(AlignmentPanel ap, String fileName,
729 boolean storeDS, JarOutputStream jout, List<String> viewIds)
733 viewIds = new ArrayList<String>();
738 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
740 AlignViewport av = ap.av;
742 JalviewModel object = new JalviewModel();
743 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
745 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
746 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
747 "Development Build"));
750 * rjal is full height alignment, jal is actual alignment with full metadata
751 * but excludes hidden sequences.
753 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
755 if (av.hasHiddenRows())
757 rjal = jal.getHiddenSequences().getFullAlignment();
760 SequenceSet vamsasSet = new SequenceSet();
762 JalviewModelSequence jms = new JalviewModelSequence();
764 vamsasSet.setGapChar(jal.getGapCharacter() + "");
766 if (jal.getDataset() != null)
768 // dataset id is the dataset's hashcode
769 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
772 // switch jal and the dataset
773 jal = jal.getDataset();
777 if (jal.getProperties() != null)
779 Enumeration en = jal.getProperties().keys();
780 while (en.hasMoreElements())
782 String key = en.nextElement().toString();
783 SequenceSetProperties ssp = new SequenceSetProperties();
785 ssp.setValue(jal.getProperties().get(key).toString());
786 vamsasSet.addSequenceSetProperties(ssp);
791 Set<String> calcIdSet = new HashSet<String>();
794 for (final SequenceI jds : rjal.getSequences())
796 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
797 : jds.getDatasetSequence();
798 String id = seqHash(jds);
800 if (seqRefIds.get(id) != null)
802 // This happens for two reasons: 1. multiple views are being serialised.
803 // 2. the hashCode has collided with another sequence's code. This DOES
804 // HAPPEN! (PF00072.15.stk does this)
805 // JBPNote: Uncomment to debug writing out of files that do not read
806 // back in due to ArrayOutOfBoundExceptions.
807 // System.err.println("vamsasSeq backref: "+id+"");
808 // System.err.println(jds.getName()+"
809 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
810 // System.err.println("Hashcode: "+seqHash(jds));
811 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
812 // System.err.println(rsq.getName()+"
813 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
814 // System.err.println("Hashcode: "+seqHash(rsq));
818 vamsasSeq = createVamsasSequence(id, jds);
819 vamsasSet.addSequence(vamsasSeq);
820 seqRefIds.put(id, jds);
824 jseq.setStart(jds.getStart());
825 jseq.setEnd(jds.getEnd());
826 jseq.setColour(av.getSequenceColour(jds).getRGB());
828 jseq.setId(id); // jseq id should be a string not a number
831 // Store any sequences this sequence represents
832 if (av.hasHiddenRows())
834 // use rjal, contains the full height alignment
835 jseq.setHidden(av.getAlignment().getHiddenSequences()
838 if (av.isHiddenRepSequence(jds))
840 jalview.datamodel.SequenceI[] reps = av
841 .getRepresentedSequences(jds)
842 .getSequencesInOrder(rjal);
844 for (int h = 0; h < reps.length; h++)
848 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
853 // mark sequence as reference - if it is the reference for this view
856 jseq.setViewreference(jds == jal.getSeqrep());
860 // TODO: omit sequence features from each alignment view's XML dump if we
861 // are storing dataset
862 if (jds.getSequenceFeatures() != null)
864 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
866 while (index < sf.length)
868 Features features = new Features();
870 features.setBegin(sf[index].getBegin());
871 features.setEnd(sf[index].getEnd());
872 features.setDescription(sf[index].getDescription());
873 features.setType(sf[index].getType());
874 features.setFeatureGroup(sf[index].getFeatureGroup());
875 features.setScore(sf[index].getScore());
876 if (sf[index].links != null)
878 for (int l = 0; l < sf[index].links.size(); l++)
880 OtherData keyValue = new OtherData();
881 keyValue.setKey("LINK_" + l);
882 keyValue.setValue(sf[index].links.elementAt(l).toString());
883 features.addOtherData(keyValue);
886 if (sf[index].otherDetails != null)
889 Iterator<String> keys = sf[index].otherDetails.keySet()
891 while (keys.hasNext())
894 OtherData keyValue = new OtherData();
895 keyValue.setKey(key);
896 keyValue.setValue(sf[index].otherDetails.get(key).toString());
897 features.addOtherData(keyValue);
901 jseq.addFeatures(features);
906 if (jdatasq.getAllPDBEntries() != null)
908 Enumeration en = jdatasq.getAllPDBEntries().elements();
909 while (en.hasMoreElements())
911 Pdbids pdb = new Pdbids();
912 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
915 String pdbId = entry.getId();
917 pdb.setType(entry.getType());
920 * Store any structure views associated with this sequence. This
921 * section copes with duplicate entries in the project, so a dataset
922 * only view *should* be coped with sensibly.
924 // This must have been loaded, is it still visible?
925 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
926 String matchedFile = null;
927 for (int f = frames.length - 1; f > -1; f--)
929 if (frames[f] instanceof StructureViewerBase)
931 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
932 matchedFile = saveStructureState(ap, jds, pdb, entry,
933 viewIds, matchedFile, viewFrame);
935 * Only store each structure viewer's state once in the project
936 * jar. First time through only (storeDS==false)
938 String viewId = viewFrame.getViewId();
939 if (!storeDS && !viewIds.contains(viewId))
944 String viewerState = viewFrame.getStateInfo();
945 writeJarEntry(jout, getViewerJarEntryName(viewId),
946 viewerState.getBytes());
947 } catch (IOException e)
949 System.err.println("Error saving viewer state: "
956 if (matchedFile != null || entry.getFile() != null)
958 if (entry.getFile() != null)
961 matchedFile = entry.getFile();
963 pdb.setFile(matchedFile); // entry.getFile());
964 if (pdbfiles == null)
966 pdbfiles = new ArrayList<String>();
969 if (!pdbfiles.contains(pdbId))
972 copyFileToJar(jout, matchedFile, pdbId);
976 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
978 PdbentryItem item = new PdbentryItem();
979 Hashtable<String, String> properties = entry.getProperty();
980 Enumeration<String> en2 = properties.keys();
981 while (en2.hasMoreElements())
983 Property prop = new Property();
984 String key = en2.nextElement();
986 prop.setValue(properties.get(key));
987 item.addProperty(prop);
989 pdb.addPdbentryItem(item);
996 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1001 if (!storeDS && av.hasHiddenRows())
1003 jal = av.getAlignment();
1007 if (storeDS && jal.getCodonFrames() != null)
1009 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1010 for (AlignedCodonFrame acf : jac)
1012 AlcodonFrame alc = new AlcodonFrame();
1013 if (acf.getProtMappings() != null
1014 && acf.getProtMappings().length > 0)
1016 boolean hasMap = false;
1017 SequenceI[] dnas = acf.getdnaSeqs();
1018 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1019 for (int m = 0; m < pmaps.length; m++)
1021 AlcodMap alcmap = new AlcodMap();
1022 alcmap.setDnasq(seqHash(dnas[m]));
1023 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1025 alc.addAlcodMap(alcmap);
1030 vamsasSet.addAlcodonFrame(alc);
1033 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1035 // AlcodonFrame alc = new AlcodonFrame();
1036 // vamsasSet.addAlcodonFrame(alc);
1037 // for (int p = 0; p < acf.aaWidth; p++)
1039 // Alcodon cmap = new Alcodon();
1040 // if (acf.codons[p] != null)
1042 // // Null codons indicate a gapped column in the translated peptide
1044 // cmap.setPos1(acf.codons[p][0]);
1045 // cmap.setPos2(acf.codons[p][1]);
1046 // cmap.setPos3(acf.codons[p][2]);
1048 // alc.addAlcodon(cmap);
1050 // if (acf.getProtMappings() != null
1051 // && acf.getProtMappings().length > 0)
1053 // SequenceI[] dnas = acf.getdnaSeqs();
1054 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1055 // for (int m = 0; m < pmaps.length; m++)
1057 // AlcodMap alcmap = new AlcodMap();
1058 // alcmap.setDnasq(seqHash(dnas[m]));
1059 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1061 // alc.addAlcodMap(alcmap);
1068 // /////////////////////////////////
1069 if (!storeDS && av.currentTree != null)
1071 // FIND ANY ASSOCIATED TREES
1072 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1073 if (Desktop.desktop != null)
1075 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1077 for (int t = 0; t < frames.length; t++)
1079 if (frames[t] instanceof TreePanel)
1081 TreePanel tp = (TreePanel) frames[t];
1083 if (tp.treeCanvas.av.getAlignment() == jal)
1085 Tree tree = new Tree();
1086 tree.setTitle(tp.getTitle());
1087 tree.setCurrentTree((av.currentTree == tp.getTree()));
1088 tree.setNewick(tp.getTree().toString());
1089 tree.setThreshold(tp.treeCanvas.threshold);
1091 tree.setFitToWindow(tp.fitToWindow.getState());
1092 tree.setFontName(tp.getTreeFont().getName());
1093 tree.setFontSize(tp.getTreeFont().getSize());
1094 tree.setFontStyle(tp.getTreeFont().getStyle());
1095 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1097 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1098 tree.setShowDistances(tp.distanceMenu.getState());
1100 tree.setHeight(tp.getHeight());
1101 tree.setWidth(tp.getWidth());
1102 tree.setXpos(tp.getX());
1103 tree.setYpos(tp.getY());
1104 tree.setId(makeHashCode(tp, null));
1114 * store forward refs from an annotationRow to any groups
1116 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1119 for (SequenceI sq : jal.getSequences())
1121 // Store annotation on dataset sequences only
1122 AlignmentAnnotation[] aa = sq.getAnnotation();
1123 if (aa != null && aa.length > 0)
1125 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1132 if (jal.getAlignmentAnnotation() != null)
1134 // Store the annotation shown on the alignment.
1135 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1136 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1141 if (jal.getGroups() != null)
1143 JGroup[] groups = new JGroup[jal.getGroups().size()];
1145 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1147 JGroup jGroup = new JGroup();
1148 groups[++i] = jGroup;
1150 jGroup.setStart(sg.getStartRes());
1151 jGroup.setEnd(sg.getEndRes());
1152 jGroup.setName(sg.getName());
1153 if (groupRefs.containsKey(sg))
1155 // group has references so set its ID field
1156 jGroup.setId(groupRefs.get(sg));
1160 if (sg.cs.conservationApplied())
1162 jGroup.setConsThreshold(sg.cs.getConservationInc());
1164 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1166 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1170 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1173 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1175 jGroup.setColour("AnnotationColourGradient");
1176 jGroup.setAnnotationColours(constructAnnotationColours(
1177 (jalview.schemes.AnnotationColourGradient) sg.cs,
1180 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1182 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1186 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1189 jGroup.setPidThreshold(sg.cs.getThreshold());
1192 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1193 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1194 jGroup.setDisplayText(sg.getDisplayText());
1195 jGroup.setColourText(sg.getColourText());
1196 jGroup.setTextCol1(sg.textColour.getRGB());
1197 jGroup.setTextCol2(sg.textColour2.getRGB());
1198 jGroup.setTextColThreshold(sg.thresholdTextColour);
1199 jGroup.setShowUnconserved(sg.getShowNonconserved());
1200 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1201 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1202 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1203 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1204 for (SequenceI seq : sg.getSequences())
1206 jGroup.addSeq(seqHash(seq));
1210 jms.setJGroup(groups);
1214 // /////////SAVE VIEWPORT
1215 Viewport view = new Viewport();
1216 view.setTitle(ap.alignFrame.getTitle());
1217 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1218 av.getSequenceSetId()));
1219 view.setId(av.getViewId());
1220 if (av.getCodingComplement() != null)
1222 view.setComplementId(av.getCodingComplement().getViewId());
1224 view.setViewName(av.viewName);
1225 view.setGatheredViews(av.isGatherViewsHere());
1227 Rectangle size = ap.av.getExplodedGeometry();
1228 Rectangle position = size;
1231 size = ap.alignFrame.getBounds();
1232 if (av.getCodingComplement() != null)
1234 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1242 view.setXpos(position.x);
1243 view.setYpos(position.y);
1245 view.setWidth(size.width);
1246 view.setHeight(size.height);
1248 view.setStartRes(av.startRes);
1249 view.setStartSeq(av.startSeq);
1251 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1253 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1256 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1258 AnnotationColours ac = constructAnnotationColours(
1259 (jalview.schemes.AnnotationColourGradient) av
1260 .getGlobalColourScheme(),
1263 view.setAnnotationColours(ac);
1264 view.setBgColour("AnnotationColourGradient");
1268 view.setBgColour(ColourSchemeProperty.getColourName(av
1269 .getGlobalColourScheme()));
1272 ColourSchemeI cs = av.getGlobalColourScheme();
1276 if (cs.conservationApplied())
1278 view.setConsThreshold(cs.getConservationInc());
1279 if (cs instanceof jalview.schemes.UserColourScheme)
1281 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1285 if (cs instanceof ResidueColourScheme)
1287 view.setPidThreshold(cs.getThreshold());
1291 view.setConservationSelected(av.getConservationSelected());
1292 view.setPidSelected(av.getAbovePIDThreshold());
1293 view.setFontName(av.font.getName());
1294 view.setFontSize(av.font.getSize());
1295 view.setFontStyle(av.font.getStyle());
1296 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1297 view.setRenderGaps(av.isRenderGaps());
1298 view.setShowAnnotation(av.isShowAnnotation());
1299 view.setShowBoxes(av.getShowBoxes());
1300 view.setShowColourText(av.getColourText());
1301 view.setShowFullId(av.getShowJVSuffix());
1302 view.setRightAlignIds(av.isRightAlignIds());
1303 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1304 view.setShowText(av.getShowText());
1305 view.setShowUnconserved(av.getShowUnconserved());
1306 view.setWrapAlignment(av.getWrapAlignment());
1307 view.setTextCol1(av.getTextColour().getRGB());
1308 view.setTextCol2(av.getTextColour2().getRGB());
1309 view.setTextColThreshold(av.getThresholdTextColour());
1310 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1311 view.setShowSequenceLogo(av.isShowSequenceLogo());
1312 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1313 view.setShowGroupConsensus(av.isShowGroupConsensus());
1314 view.setShowGroupConservation(av.isShowGroupConservation());
1315 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1316 view.setShowDbRefTooltip(av.isShowDBRefs());
1317 view.setFollowHighlight(av.isFollowHighlight());
1318 view.setFollowSelection(av.followSelection);
1319 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1320 if (av.getFeaturesDisplayed() != null)
1322 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1324 String[] renderOrder = ap.getSeqPanel().seqCanvas
1325 .getFeatureRenderer().getRenderOrder()
1326 .toArray(new String[0]);
1328 Vector<String> settingsAdded = new Vector<String>();
1329 if (renderOrder != null)
1331 for (String featureType : renderOrder)
1333 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1334 .getFeatureRenderer()
1335 .getFeatureStyle(featureType);
1336 Setting setting = new Setting();
1337 setting.setType(featureType);
1338 if (!fcol.isSimpleColour())
1340 setting.setColour(fcol.getMaxColour().getRGB());
1341 setting.setMincolour(fcol.getMinColour().getRGB());
1342 setting.setMin(fcol.getMin());
1343 setting.setMax(fcol.getMax());
1344 setting.setColourByLabel(fcol.isColourByLabel());
1345 setting.setAutoScale(fcol.isAutoScaled());
1346 setting.setThreshold(fcol.getThreshold());
1347 // -1 = No threshold, 0 = Below, 1 = Above
1348 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1349 : (fcol.isBelowThreshold() ? 0 : -1));
1353 setting.setColour(fcol.getColour().getRGB());
1356 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1358 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1359 .getOrder(featureType);
1362 setting.setOrder(rorder);
1364 fs.addSetting(setting);
1365 settingsAdded.addElement(featureType);
1369 // is groups actually supposed to be a map here ?
1370 Iterator<String> en = ap.getSeqPanel().seqCanvas
1371 .getFeatureRenderer()
1372 .getFeatureGroups().iterator();
1373 Vector<String> groupsAdded = new Vector<String>();
1374 while (en.hasNext())
1376 String grp = en.next();
1377 if (groupsAdded.contains(grp))
1381 Group g = new Group();
1383 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1384 .getFeatureRenderer().checkGroupVisibility(grp, false))
1387 groupsAdded.addElement(grp);
1389 jms.setFeatureSettings(fs);
1392 if (av.hasHiddenColumns())
1394 if (av.getColumnSelection() == null
1395 || av.getColumnSelection().getHiddenColumns() == null)
1397 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1401 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1404 int[] region = av.getColumnSelection().getHiddenColumns()
1406 HiddenColumns hc = new HiddenColumns();
1407 hc.setStart(region[0]);
1408 hc.setEnd(region[1]);
1409 view.addHiddenColumns(hc);
1413 if (calcIdSet.size() > 0)
1415 for (String calcId : calcIdSet)
1417 if (calcId.trim().length() > 0)
1419 CalcIdParam cidp = createCalcIdParam(calcId, av);
1420 // Some calcIds have no parameters.
1423 view.addCalcIdParam(cidp);
1429 jms.addViewport(view);
1431 object.setJalviewModelSequence(jms);
1432 object.getVamsasModel().addSequenceSet(vamsasSet);
1434 if (jout != null && fileName != null)
1436 // We may not want to write the object to disk,
1437 // eg we can copy the alignViewport to a new view object
1438 // using save and then load
1441 System.out.println("Writing jar entry " + fileName);
1442 JarEntry entry = new JarEntry(fileName);
1443 jout.putNextEntry(entry);
1444 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1446 Marshaller marshaller = new Marshaller(pout);
1447 marshaller.marshal(object);
1450 } catch (Exception ex)
1452 // TODO: raise error in GUI if marshalling failed.
1453 ex.printStackTrace();
1460 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1461 * for each viewer, with
1463 * <li>viewer geometry (position, size, split pane divider location)</li>
1464 * <li>index of the selected structure in the viewer (currently shows gapped
1466 * <li>the id of the annotation holding RNA secondary structure</li>
1467 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1469 * Varna viewer state is also written out (in native Varna XML) to separate
1470 * project jar entries. A separate entry is written for each RNA structure
1471 * displayed, with the naming convention
1473 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1481 * @param storeDataset
1483 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1484 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1485 boolean storeDataset)
1487 if (Desktop.desktop == null)
1491 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1492 for (int f = frames.length - 1; f > -1; f--)
1494 if (frames[f] instanceof AppVarna)
1496 AppVarna varna = (AppVarna) frames[f];
1498 * link the sequence to every viewer that is showing it and is linked to
1499 * its alignment panel
1501 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1503 String viewId = varna.getViewId();
1504 RnaViewer rna = new RnaViewer();
1505 rna.setViewId(viewId);
1506 rna.setTitle(varna.getTitle());
1507 rna.setXpos(varna.getX());
1508 rna.setYpos(varna.getY());
1509 rna.setWidth(varna.getWidth());
1510 rna.setHeight(varna.getHeight());
1511 rna.setDividerLocation(varna.getDividerLocation());
1512 rna.setSelectedRna(varna.getSelectedIndex());
1513 jseq.addRnaViewer(rna);
1516 * Store each Varna panel's state once in the project per sequence.
1517 * First time through only (storeDataset==false)
1519 // boolean storeSessions = false;
1520 // String sequenceViewId = viewId + seqsToIds.get(jds);
1521 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1523 // viewIds.add(sequenceViewId);
1524 // storeSessions = true;
1526 for (RnaModel model : varna.getModels())
1528 if (model.seq == jds)
1531 * VARNA saves each view (sequence or alignment secondary
1532 * structure, gapped or trimmed) as a separate XML file
1534 String jarEntryName = rnaSessions.get(model);
1535 if (jarEntryName == null)
1538 String varnaStateFile = varna.getStateInfo(model.rna);
1539 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1540 copyFileToJar(jout, varnaStateFile, jarEntryName);
1541 rnaSessions.put(model, jarEntryName);
1543 SecondaryStructure ss = new SecondaryStructure();
1544 String annotationId = varna.getAnnotation(jds).annotationId;
1545 ss.setAnnotationId(annotationId);
1546 ss.setViewerState(jarEntryName);
1547 ss.setGapped(model.gapped);
1548 ss.setTitle(model.title);
1549 rna.addSecondaryStructure(ss);
1558 * Copy the contents of a file to a new entry added to the output jar
1562 * @param jarEntryName
1564 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1565 String jarEntryName)
1567 DataInputStream dis = null;
1570 File file = new File(infilePath);
1571 if (file.exists() && jout != null)
1573 dis = new DataInputStream(new FileInputStream(file));
1574 byte[] data = new byte[(int) file.length()];
1575 dis.readFully(data);
1576 writeJarEntry(jout, jarEntryName, data);
1578 } catch (Exception ex)
1580 ex.printStackTrace();
1588 } catch (IOException e)
1597 * Write the data to a new entry of given name in the output jar file
1600 * @param jarEntryName
1602 * @throws IOException
1604 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1605 byte[] data) throws IOException
1609 System.out.println("Writing jar entry " + jarEntryName);
1610 jout.putNextEntry(new JarEntry(jarEntryName));
1611 DataOutputStream dout = new DataOutputStream(jout);
1612 dout.write(data, 0, data.length);
1619 * Save the state of a structure viewer
1624 * the archive XML element under which to save the state
1627 * @param matchedFile
1631 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1632 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1633 String matchedFile, StructureViewerBase viewFrame)
1635 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1638 * Look for any bindings for this viewer to the PDB file of interest
1639 * (including part matches excluding chain id)
1641 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1643 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1644 final String pdbId = pdbentry.getId();
1645 if (!pdbId.equals(entry.getId())
1646 && !(entry.getId().length() > 4 && entry.getId()
1647 .toLowerCase().startsWith(pdbId.toLowerCase())))
1650 * not interested in a binding to a different PDB entry here
1654 if (matchedFile == null)
1656 matchedFile = pdbentry.getFile();
1658 else if (!matchedFile.equals(pdbentry.getFile()))
1661 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1662 + pdbentry.getFile());
1666 // can get at it if the ID
1667 // match is ambiguous (e.g.
1670 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1672 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1673 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1675 StructureState state = new StructureState();
1676 state.setVisible(true);
1677 state.setXpos(viewFrame.getX());
1678 state.setYpos(viewFrame.getY());
1679 state.setWidth(viewFrame.getWidth());
1680 state.setHeight(viewFrame.getHeight());
1681 final String viewId = viewFrame.getViewId();
1682 state.setViewId(viewId);
1683 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1684 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1685 state.setColourByJmol(viewFrame.isColouredByViewer());
1686 state.setType(viewFrame.getViewerType().toString());
1687 pdb.addStructureState(state);
1694 private AnnotationColours constructAnnotationColours(
1695 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1696 JalviewModelSequence jms)
1698 AnnotationColours ac = new AnnotationColours();
1699 ac.setAboveThreshold(acg.getAboveThreshold());
1700 ac.setThreshold(acg.getAnnotationThreshold());
1701 ac.setAnnotation(acg.getAnnotation());
1702 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1704 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1709 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1713 ac.setMaxColour(acg.getMaxColour().getRGB());
1714 ac.setMinColour(acg.getMinColour().getRGB());
1715 ac.setPerSequence(acg.isSeqAssociated());
1716 ac.setPredefinedColours(acg.isPredefinedColours());
1720 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1721 IdentityHashMap<SequenceGroup, String> groupRefs,
1722 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1723 SequenceSet vamsasSet)
1726 for (int i = 0; i < aa.length; i++)
1728 Annotation an = new Annotation();
1730 AlignmentAnnotation annotation = aa[i];
1731 if (annotation.annotationId != null)
1733 annotationIds.put(annotation.annotationId, annotation);
1736 an.setId(annotation.annotationId);
1738 an.setVisible(annotation.visible);
1740 an.setDescription(annotation.description);
1742 if (annotation.sequenceRef != null)
1744 // 2.9 JAL-1781 xref on sequence id rather than name
1745 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1747 if (annotation.groupRef != null)
1749 String groupIdr = groupRefs.get(annotation.groupRef);
1750 if (groupIdr == null)
1752 // make a locally unique String
1754 annotation.groupRef,
1755 groupIdr = ("" + System.currentTimeMillis()
1756 + annotation.groupRef.getName() + groupRefs
1759 an.setGroupRef(groupIdr.toString());
1762 // store all visualization attributes for annotation
1763 an.setGraphHeight(annotation.graphHeight);
1764 an.setCentreColLabels(annotation.centreColLabels);
1765 an.setScaleColLabels(annotation.scaleColLabel);
1766 an.setShowAllColLabels(annotation.showAllColLabels);
1767 an.setBelowAlignment(annotation.belowAlignment);
1769 if (annotation.graph > 0)
1772 an.setGraphType(annotation.graph);
1773 an.setGraphGroup(annotation.graphGroup);
1774 if (annotation.getThreshold() != null)
1776 ThresholdLine line = new ThresholdLine();
1777 line.setLabel(annotation.getThreshold().label);
1778 line.setValue(annotation.getThreshold().value);
1779 line.setColour(annotation.getThreshold().colour.getRGB());
1780 an.setThresholdLine(line);
1788 an.setLabel(annotation.label);
1790 if (annotation == av.getAlignmentQualityAnnot()
1791 || annotation == av.getAlignmentConservationAnnotation()
1792 || annotation == av.getAlignmentConsensusAnnotation()
1793 || annotation.autoCalculated)
1795 // new way of indicating autocalculated annotation -
1796 an.setAutoCalculated(annotation.autoCalculated);
1798 if (annotation.hasScore())
1800 an.setScore(annotation.getScore());
1803 if (annotation.getCalcId() != null)
1805 calcIdSet.add(annotation.getCalcId());
1806 an.setCalcId(annotation.getCalcId());
1808 if (annotation.hasProperties())
1810 for (String pr : annotation.getProperties())
1812 Property prop = new Property();
1814 prop.setValue(annotation.getProperty(pr));
1815 an.addProperty(prop);
1819 AnnotationElement ae;
1820 if (annotation.annotations != null)
1822 an.setScoreOnly(false);
1823 for (int a = 0; a < annotation.annotations.length; a++)
1825 if ((annotation == null) || (annotation.annotations[a] == null))
1830 ae = new AnnotationElement();
1831 if (annotation.annotations[a].description != null)
1833 ae.setDescription(annotation.annotations[a].description);
1835 if (annotation.annotations[a].displayCharacter != null)
1837 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1840 if (!Float.isNaN(annotation.annotations[a].value))
1842 ae.setValue(annotation.annotations[a].value);
1846 if (annotation.annotations[a].secondaryStructure > ' ')
1848 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1852 if (annotation.annotations[a].colour != null
1853 && annotation.annotations[a].colour != java.awt.Color.black)
1855 ae.setColour(annotation.annotations[a].colour.getRGB());
1858 an.addAnnotationElement(ae);
1859 if (annotation.autoCalculated)
1861 // only write one non-null entry into the annotation row -
1862 // sufficient to get the visualization attributes necessary to
1870 an.setScoreOnly(true);
1872 if (!storeDS || (storeDS && !annotation.autoCalculated))
1874 // skip autocalculated annotation - these are only provided for
1876 vamsasSet.addAnnotation(an);
1882 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1884 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1885 if (settings != null)
1887 CalcIdParam vCalcIdParam = new CalcIdParam();
1888 vCalcIdParam.setCalcId(calcId);
1889 vCalcIdParam.addServiceURL(settings.getServiceURI());
1890 // generic URI allowing a third party to resolve another instance of the
1891 // service used for this calculation
1892 for (String urls : settings.getServiceURLs())
1894 vCalcIdParam.addServiceURL(urls);
1896 vCalcIdParam.setVersion("1.0");
1897 if (settings.getPreset() != null)
1899 WsParamSetI setting = settings.getPreset();
1900 vCalcIdParam.setName(setting.getName());
1901 vCalcIdParam.setDescription(setting.getDescription());
1905 vCalcIdParam.setName("");
1906 vCalcIdParam.setDescription("Last used parameters");
1908 // need to be able to recover 1) settings 2) user-defined presets or
1909 // recreate settings from preset 3) predefined settings provided by
1910 // service - or settings that can be transferred (or discarded)
1911 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1913 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1914 // todo - decide if updateImmediately is needed for any projects.
1916 return vCalcIdParam;
1921 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1924 if (calcIdParam.getVersion().equals("1.0"))
1926 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1927 .getPreferredServiceFor(calcIdParam.getServiceURL());
1928 if (service != null)
1930 WsParamSetI parmSet = null;
1933 parmSet = service.getParamStore().parseServiceParameterFile(
1934 calcIdParam.getName(), calcIdParam.getDescription(),
1935 calcIdParam.getServiceURL(),
1936 calcIdParam.getParameters().replace("|\\n|", "\n"));
1937 } catch (IOException x)
1939 warn("Couldn't parse parameter data for "
1940 + calcIdParam.getCalcId(), x);
1943 List<ArgumentI> argList = null;
1944 if (calcIdParam.getName().length() > 0)
1946 parmSet = service.getParamStore()
1947 .getPreset(calcIdParam.getName());
1948 if (parmSet != null)
1950 // TODO : check we have a good match with settings in AACon -
1951 // otherwise we'll need to create a new preset
1956 argList = parmSet.getArguments();
1959 AAConSettings settings = new AAConSettings(
1960 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1961 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1962 calcIdParam.isNeedsUpdate());
1967 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1971 throw new Error(MessageManager.formatMessage(
1972 "error.unsupported_version_calcIdparam",
1973 new Object[] { calcIdParam.toString() }));
1977 * External mapping between jalview objects and objects yielding a valid and
1978 * unique object ID string. This is null for normal Jalview project IO, but
1979 * non-null when a jalview project is being read or written as part of a
1982 IdentityHashMap jv2vobj = null;
1985 * Construct a unique ID for jvobj using either existing bindings or if none
1986 * exist, the result of the hashcode call for the object.
1989 * jalview data object
1990 * @return unique ID for referring to jvobj
1992 private String makeHashCode(Object jvobj, String altCode)
1994 if (jv2vobj != null)
1996 Object id = jv2vobj.get(jvobj);
1999 return id.toString();
2001 // check string ID mappings
2002 if (jvids2vobj != null && jvobj instanceof String)
2004 id = jvids2vobj.get(jvobj);
2008 return id.toString();
2010 // give up and warn that something has gone wrong
2011 warn("Cannot find ID for object in external mapping : " + jvobj);
2017 * return local jalview object mapped to ID, if it exists
2021 * @return null or object bound to idcode
2023 private Object retrieveExistingObj(String idcode)
2025 if (idcode != null && vobj2jv != null)
2027 return vobj2jv.get(idcode);
2033 * binding from ID strings from external mapping table to jalview data model
2036 private Hashtable vobj2jv;
2038 private Sequence createVamsasSequence(String id, SequenceI jds)
2040 return createVamsasSequence(true, id, jds, null);
2043 private Sequence createVamsasSequence(boolean recurse, String id,
2044 SequenceI jds, SequenceI parentseq)
2046 Sequence vamsasSeq = new Sequence();
2047 vamsasSeq.setId(id);
2048 vamsasSeq.setName(jds.getName());
2049 vamsasSeq.setSequence(jds.getSequenceAsString());
2050 vamsasSeq.setDescription(jds.getDescription());
2051 jalview.datamodel.DBRefEntry[] dbrefs = null;
2052 if (jds.getDatasetSequence() != null)
2054 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2058 // seqId==dsseqid so we can tell which sequences really are
2059 // dataset sequences only
2060 vamsasSeq.setDsseqid(id);
2061 dbrefs = jds.getDBRefs();
2062 if (parentseq == null)
2069 for (int d = 0; d < dbrefs.length; d++)
2071 DBRef dbref = new DBRef();
2072 dbref.setSource(dbrefs[d].getSource());
2073 dbref.setVersion(dbrefs[d].getVersion());
2074 dbref.setAccessionId(dbrefs[d].getAccessionId());
2075 if (dbrefs[d].hasMap())
2077 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2079 dbref.setMapping(mp);
2081 vamsasSeq.addDBRef(dbref);
2087 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2088 SequenceI parentseq, SequenceI jds, boolean recurse)
2091 if (jmp.getMap() != null)
2095 jalview.util.MapList mlst = jmp.getMap();
2096 List<int[]> r = mlst.getFromRanges();
2097 for (int[] range : r)
2099 MapListFrom mfrom = new MapListFrom();
2100 mfrom.setStart(range[0]);
2101 mfrom.setEnd(range[1]);
2102 mp.addMapListFrom(mfrom);
2104 r = mlst.getToRanges();
2105 for (int[] range : r)
2107 MapListTo mto = new MapListTo();
2108 mto.setStart(range[0]);
2109 mto.setEnd(range[1]);
2110 mp.addMapListTo(mto);
2112 mp.setMapFromUnit(mlst.getFromRatio());
2113 mp.setMapToUnit(mlst.getToRatio());
2114 if (jmp.getTo() != null)
2116 MappingChoice mpc = new MappingChoice();
2118 // check/create ID for the sequence referenced by getTo()
2121 SequenceI ps = null;
2122 if (parentseq != jmp.getTo()
2123 && parentseq.getDatasetSequence() != jmp.getTo())
2125 // chaining dbref rather than a handshaking one
2126 jmpid = seqHash(ps = jmp.getTo());
2130 jmpid = seqHash(ps = parentseq);
2132 mpc.setDseqFor(jmpid);
2133 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2135 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2136 seqRefIds.put(mpc.getDseqFor(), ps);
2140 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2143 mp.setMappingChoice(mpc);
2149 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2150 List<UserColourScheme> userColours, JalviewModelSequence jms)
2153 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2154 boolean newucs = false;
2155 if (!userColours.contains(ucs))
2157 userColours.add(ucs);
2160 id = "ucs" + userColours.indexOf(ucs);
2163 // actually create the scheme's entry in the XML model
2164 java.awt.Color[] colours = ucs.getColours();
2165 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2166 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2168 for (int i = 0; i < colours.length; i++)
2170 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2171 col.setName(ResidueProperties.aa[i]);
2172 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2173 jbucs.addColour(col);
2175 if (ucs.getLowerCaseColours() != null)
2177 colours = ucs.getLowerCaseColours();
2178 for (int i = 0; i < colours.length; i++)
2180 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2181 col.setName(ResidueProperties.aa[i].toLowerCase());
2182 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2183 jbucs.addColour(col);
2188 uc.setUserColourScheme(jbucs);
2189 jms.addUserColours(uc);
2195 jalview.schemes.UserColourScheme getUserColourScheme(
2196 JalviewModelSequence jms, String id)
2198 UserColours[] uc = jms.getUserColours();
2199 UserColours colours = null;
2201 for (int i = 0; i < uc.length; i++)
2203 if (uc[i].getId().equals(id))
2211 java.awt.Color[] newColours = new java.awt.Color[24];
2213 for (int i = 0; i < 24; i++)
2215 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2216 .getUserColourScheme().getColour(i).getRGB(), 16));
2219 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2222 if (colours.getUserColourScheme().getColourCount() > 24)
2224 newColours = new java.awt.Color[23];
2225 for (int i = 0; i < 23; i++)
2227 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2228 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2230 ucs.setLowerCaseColours(newColours);
2237 * contains last error message (if any) encountered by XML loader.
2239 String errorMessage = null;
2242 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2243 * exceptions are raised during project XML parsing
2245 public boolean attemptversion1parse = true;
2248 * Load a jalview project archive from a jar file
2251 * - HTTP URL or filename
2253 public AlignFrame loadJalviewAlign(final String file)
2256 jalview.gui.AlignFrame af = null;
2260 // create list to store references for any new Jmol viewers created
2261 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2262 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2263 // Workaround is to make sure caller implements the JarInputStreamProvider
2265 // so we can re-open the jar input stream for each entry.
2267 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2268 af = loadJalviewAlign(jprovider);
2270 } catch (MalformedURLException e)
2272 errorMessage = "Invalid URL format for '" + file + "'";
2278 SwingUtilities.invokeAndWait(new Runnable()
2283 setLoadingFinishedForNewStructureViewers();
2286 } catch (Exception x)
2288 System.err.println("Error loading alignment: " + x.getMessage());
2294 private jarInputStreamProvider createjarInputStreamProvider(
2295 final String file) throws MalformedURLException
2298 errorMessage = null;
2299 uniqueSetSuffix = null;
2301 viewportsAdded.clear();
2302 frefedSequence = null;
2304 if (file.startsWith("http://"))
2306 url = new URL(file);
2308 final URL _url = url;
2309 return new jarInputStreamProvider()
2313 public JarInputStream getJarInputStream() throws IOException
2317 return new JarInputStream(_url.openStream());
2321 return new JarInputStream(new FileInputStream(file));
2326 public String getFilename()
2334 * Recover jalview session from a jalview project archive. Caller may
2335 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2336 * themselves. Any null fields will be initialised with default values,
2337 * non-null fields are left alone.
2342 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2344 errorMessage = null;
2345 if (uniqueSetSuffix == null)
2347 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2349 if (seqRefIds == null)
2353 AlignFrame af = null, _af = null;
2354 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2355 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2356 final String file = jprovider.getFilename();
2359 JarInputStream jin = null;
2360 JarEntry jarentry = null;
2365 jin = jprovider.getJarInputStream();
2366 for (int i = 0; i < entryCount; i++)
2368 jarentry = jin.getNextJarEntry();
2371 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2373 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2374 JalviewModel object = new JalviewModel();
2376 Unmarshaller unmar = new Unmarshaller(object);
2377 unmar.setValidation(false);
2378 object = (JalviewModel) unmar.unmarshal(in);
2379 if (true) // !skipViewport(object))
2381 _af = loadFromObject(object, file, true, jprovider);
2383 && object.getJalviewModelSequence().getViewportCount() > 0)
2387 // store a reference to the first view
2390 if (_af.viewport.isGatherViewsHere())
2392 // if this is a gathered view, keep its reference since
2393 // after gathering views, only this frame will remain
2395 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2397 // Save dataset to register mappings once all resolved
2398 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2399 af.viewport.getAlignment().getDataset());
2404 else if (jarentry != null)
2406 // Some other file here.
2409 } while (jarentry != null);
2410 resolveFrefedSequences();
2411 } catch (IOException ex)
2413 ex.printStackTrace();
2414 errorMessage = "Couldn't locate Jalview XML file : " + file;
2415 System.err.println("Exception whilst loading jalview XML file : "
2417 } catch (Exception ex)
2419 System.err.println("Parsing as Jalview Version 2 file failed.");
2420 ex.printStackTrace(System.err);
2421 if (attemptversion1parse)
2423 // Is Version 1 Jar file?
2426 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2427 } catch (Exception ex2)
2429 System.err.println("Exception whilst loading as jalviewXMLV1:");
2430 ex2.printStackTrace();
2434 if (Desktop.instance != null)
2436 Desktop.instance.stopLoading();
2440 System.out.println("Successfully loaded archive file");
2443 ex.printStackTrace();
2445 System.err.println("Exception whilst loading jalview XML file : "
2447 } catch (OutOfMemoryError e)
2449 // Don't use the OOM Window here
2450 errorMessage = "Out of memory loading jalview XML file";
2451 System.err.println("Out of memory whilst loading jalview XML file");
2452 e.printStackTrace();
2456 * Regather multiple views (with the same sequence set id) to the frame (if
2457 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2458 * views instead of separate frames. Note this doesn't restore a state where
2459 * some expanded views in turn have tabbed views - the last "first tab" read
2460 * in will play the role of gatherer for all.
2462 for (AlignFrame fr : gatherToThisFrame.values())
2464 Desktop.instance.gatherViews(fr);
2467 restoreSplitFrames();
2468 for (AlignmentI ds : importedDatasets.keySet())
2470 if (ds.getCodonFrames() != null)
2472 StructureSelectionManager.getStructureSelectionManager(
2473 Desktop.instance).registerMappings(ds.getCodonFrames());
2476 if (errorMessage != null)
2481 if (Desktop.instance != null)
2483 Desktop.instance.stopLoading();
2490 * Try to reconstruct and display SplitFrame windows, where each contains
2491 * complementary dna and protein alignments. Done by pairing up AlignFrame
2492 * objects (created earlier) which have complementary viewport ids associated.
2494 protected void restoreSplitFrames()
2496 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2497 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2498 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2501 * Identify the DNA alignments
2503 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2506 AlignFrame af = candidate.getValue();
2507 if (af.getViewport().getAlignment().isNucleotide())
2509 dna.put(candidate.getKey().getId(), af);
2514 * Try to match up the protein complements
2516 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2519 AlignFrame af = candidate.getValue();
2520 if (!af.getViewport().getAlignment().isNucleotide())
2522 String complementId = candidate.getKey().getComplementId();
2523 // only non-null complements should be in the Map
2524 if (complementId != null && dna.containsKey(complementId))
2526 final AlignFrame dnaFrame = dna.get(complementId);
2527 SplitFrame sf = createSplitFrame(dnaFrame, af);
2528 addedToSplitFrames.add(dnaFrame);
2529 addedToSplitFrames.add(af);
2530 if (af.viewport.isGatherViewsHere())
2539 * Open any that we failed to pair up (which shouldn't happen!) as
2540 * standalone AlignFrame's.
2542 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2545 AlignFrame af = candidate.getValue();
2546 if (!addedToSplitFrames.contains(af))
2548 Viewport view = candidate.getKey();
2549 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2551 System.err.println("Failed to restore view " + view.getTitle()
2552 + " to split frame");
2557 * Gather back into tabbed views as flagged.
2559 for (SplitFrame sf : gatherTo)
2561 Desktop.instance.gatherViews(sf);
2564 splitFrameCandidates.clear();
2568 * Construct and display one SplitFrame holding DNA and protein alignments.
2571 * @param proteinFrame
2574 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2575 AlignFrame proteinFrame)
2577 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2578 String title = MessageManager.getString("label.linked_view_title");
2579 int width = (int) dnaFrame.getBounds().getWidth();
2580 int height = (int) (dnaFrame.getBounds().getHeight()
2581 + proteinFrame.getBounds().getHeight() + 50);
2584 * SplitFrame location is saved to both enclosed frames
2586 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2587 Desktop.addInternalFrame(splitFrame, title, width, height);
2590 * And compute cDNA consensus (couldn't do earlier with consensus as
2591 * mappings were not yet present)
2593 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2599 * check errorMessage for a valid error message and raise an error box in the
2600 * GUI or write the current errorMessage to stderr and then clear the error
2603 protected void reportErrors()
2605 reportErrors(false);
2608 protected void reportErrors(final boolean saving)
2610 if (errorMessage != null)
2612 final String finalErrorMessage = errorMessage;
2615 javax.swing.SwingUtilities.invokeLater(new Runnable()
2620 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2621 finalErrorMessage, "Error "
2622 + (saving ? "saving" : "loading")
2623 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2629 System.err.println("Problem loading Jalview file: " + errorMessage);
2632 errorMessage = null;
2635 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2638 * when set, local views will be updated from view stored in JalviewXML
2639 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2640 * sync if this is set to true.
2642 private final boolean updateLocalViews = false;
2645 * Returns the path to a temporary file holding the PDB file for the given PDB
2646 * id. The first time of asking, searches for a file of that name in the
2647 * Jalview project jar, and copies it to a new temporary file. Any repeat
2648 * requests just return the path to the file previously created.
2654 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2656 if (alreadyLoadedPDB.containsKey(pdbId))
2658 return alreadyLoadedPDB.get(pdbId).toString();
2661 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2662 if (tempFile != null)
2664 alreadyLoadedPDB.put(pdbId, tempFile);
2670 * Copies the jar entry of given name to a new temporary file and returns the
2671 * path to the file, or null if the entry is not found.
2674 * @param jarEntryName
2676 * a prefix for the temporary file name, must be at least three
2680 protected String copyJarEntry(jarInputStreamProvider jprovider,
2681 String jarEntryName, String prefix)
2683 BufferedReader in = null;
2684 PrintWriter out = null;
2688 JarInputStream jin = jprovider.getJarInputStream();
2690 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2691 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2692 * FileInputStream(jprovider)); }
2695 JarEntry entry = null;
2698 entry = jin.getNextJarEntry();
2699 } while (entry != null && !entry.getName().equals(jarEntryName));
2702 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2703 File outFile = File.createTempFile(prefix, ".tmp");
2704 outFile.deleteOnExit();
2705 out = new PrintWriter(new FileOutputStream(outFile));
2708 while ((data = in.readLine()) != null)
2713 String t = outFile.getAbsolutePath();
2718 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2720 } catch (Exception ex)
2722 ex.printStackTrace();
2730 } catch (IOException e)
2744 private class JvAnnotRow
2746 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2753 * persisted version of annotation row from which to take vis properties
2755 public jalview.datamodel.AlignmentAnnotation template;
2758 * original position of the annotation row in the alignment
2764 * Load alignment frame from jalview XML DOM object
2769 * filename source string
2770 * @param loadTreesAndStructures
2771 * when false only create Viewport
2773 * data source provider
2774 * @return alignment frame created from view stored in DOM
2776 AlignFrame loadFromObject(JalviewModel object, String file,
2777 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2779 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2780 Sequence[] vamsasSeq = vamsasSet.getSequence();
2782 JalviewModelSequence jms = object.getJalviewModelSequence();
2784 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2787 // ////////////////////////////////
2790 List<SequenceI> hiddenSeqs = null;
2793 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2795 boolean multipleView = false;
2796 SequenceI referenceseqForView = null;
2797 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2798 int vi = 0; // counter in vamsasSeq array
2799 for (int i = 0; i < jseqs.length; i++)
2801 String seqId = jseqs[i].getId();
2803 SequenceI tmpSeq = seqRefIds.get(seqId);
2806 if (!incompleteSeqs.containsKey(seqId))
2808 // may not need this check, but keep it for at least 2.9,1 release
2809 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2812 .println("Warning JAL-2154 regression: updating start/end for sequence "
2813 + tmpSeq.toString());
2816 incompleteSeqs.remove(seqId);
2818 tmpSeq.setStart(jseqs[i].getStart());
2819 tmpSeq.setEnd(jseqs[i].getEnd());
2820 tmpseqs.add(tmpSeq);
2821 multipleView = true;
2825 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2826 vamsasSeq[vi].getSequence());
2827 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2828 tmpSeq.setStart(jseqs[i].getStart());
2829 tmpSeq.setEnd(jseqs[i].getEnd());
2830 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2831 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2832 tmpseqs.add(tmpSeq);
2836 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2838 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2841 if (jseqs[i].getHidden())
2843 if (hiddenSeqs == null)
2845 hiddenSeqs = new ArrayList<SequenceI>();
2848 hiddenSeqs.add(tmpSeq);
2853 // Create the alignment object from the sequence set
2854 // ///////////////////////////////
2855 SequenceI[] orderedSeqs = tmpseqs
2856 .toArray(new SequenceI[tmpseqs.size()]);
2858 AlignmentI al = null;
2859 // so we must create or recover the dataset alignment before going further
2860 // ///////////////////////////////
2861 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2863 // older jalview projects do not have a dataset - so creat alignment and
2865 al = new Alignment(orderedSeqs);
2866 al.setDataset(null);
2870 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2873 // we are importing a dataset record, so
2874 // recover reference to an alignment already materialsed as dataset
2875 al = getDatasetFor(vamsasSet.getDatasetId());
2879 // materialse the alignment
2880 al = new Alignment(orderedSeqs);
2884 addDatasetRef(vamsasSet.getDatasetId(), al);
2887 // finally, verify all data in vamsasSet is actually present in al
2888 // passing on flag indicating if it is actually a stored dataset
2889 recoverDatasetFor(vamsasSet, al, isdsal);
2892 if (referenceseqForView != null)
2894 al.setSeqrep(referenceseqForView);
2896 // / Add the alignment properties
2897 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2899 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2900 al.setProperty(ssp.getKey(), ssp.getValue());
2903 // ///////////////////////////////
2905 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2908 // load sequence features, database references and any associated PDB
2909 // structures for the alignment
2910 for (int i = 0; i < vamsasSeq.length; i++)
2912 if (jseqs[i].getFeaturesCount() > 0)
2914 Features[] features = jseqs[i].getFeatures();
2915 for (int f = 0; f < features.length; f++)
2917 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2918 features[f].getType(), features[f].getDescription(),
2919 features[f].getStatus(), features[f].getBegin(),
2920 features[f].getEnd(), features[f].getFeatureGroup());
2922 sf.setScore(features[f].getScore());
2923 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2925 OtherData keyValue = features[f].getOtherData(od);
2926 if (keyValue.getKey().startsWith("LINK"))
2928 sf.addLink(keyValue.getValue());
2932 sf.setValue(keyValue.getKey(), keyValue.getValue());
2937 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2940 if (vamsasSeq[i].getDBRefCount() > 0)
2942 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2944 if (jseqs[i].getPdbidsCount() > 0)
2946 Pdbids[] ids = jseqs[i].getPdbids();
2947 for (int p = 0; p < ids.length; p++)
2949 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2950 entry.setId(ids[p].getId());
2951 if (ids[p].getType() != null)
2953 if (ids[p].getType().equalsIgnoreCase("PDB"))
2955 entry.setType(PDBEntry.Type.PDB);
2959 entry.setType(PDBEntry.Type.FILE);
2962 if (ids[p].getFile() != null)
2964 if (!pdbloaded.containsKey(ids[p].getFile()))
2966 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2970 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2973 StructureSelectionManager.getStructureSelectionManager(
2974 Desktop.instance).registerPDBEntry(entry);
2975 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2979 } // end !multipleview
2981 // ///////////////////////////////
2982 // LOAD SEQUENCE MAPPINGS
2984 if (vamsasSet.getAlcodonFrameCount() > 0)
2986 // TODO Potentially this should only be done once for all views of an
2988 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2989 for (int i = 0; i < alc.length; i++)
2991 AlignedCodonFrame cf = new AlignedCodonFrame();
2992 if (alc[i].getAlcodMapCount() > 0)
2994 AlcodMap[] maps = alc[i].getAlcodMap();
2995 for (int m = 0; m < maps.length; m++)
2997 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2999 jalview.datamodel.Mapping mapping = null;
3000 // attach to dna sequence reference.
3001 if (maps[m].getMapping() != null)
3003 mapping = addMapping(maps[m].getMapping());
3005 if (dnaseq != null && mapping.getTo() != null)
3007 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3012 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3016 al.addCodonFrame(cf);
3021 // ////////////////////////////////
3023 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3026 * store any annotations which forward reference a group's ID
3028 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3030 if (vamsasSet.getAnnotationCount() > 0)
3032 Annotation[] an = vamsasSet.getAnnotation();
3034 for (int i = 0; i < an.length; i++)
3036 Annotation annotation = an[i];
3039 * test if annotation is automatically calculated for this view only
3041 boolean autoForView = false;
3042 if (annotation.getLabel().equals("Quality")
3043 || annotation.getLabel().equals("Conservation")
3044 || annotation.getLabel().equals("Consensus"))
3046 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3048 if (!annotation.hasAutoCalculated())
3050 annotation.setAutoCalculated(true);
3054 || (annotation.hasAutoCalculated() && annotation
3055 .isAutoCalculated()))
3057 // remove ID - we don't recover annotation from other views for
3058 // view-specific annotation
3059 annotation.setId(null);
3062 // set visiblity for other annotation in this view
3063 String annotationId = annotation.getId();
3064 if (annotationId != null && annotationIds.containsKey(annotationId))
3066 AlignmentAnnotation jda = annotationIds.get(annotationId);
3067 // in principle Visible should always be true for annotation displayed
3068 // in multiple views
3069 if (annotation.hasVisible())
3071 jda.visible = annotation.getVisible();
3074 al.addAnnotation(jda);
3078 // Construct new annotation from model.
3079 AnnotationElement[] ae = annotation.getAnnotationElement();
3080 jalview.datamodel.Annotation[] anot = null;
3081 java.awt.Color firstColour = null;
3083 if (!annotation.getScoreOnly())
3085 anot = new jalview.datamodel.Annotation[al.getWidth()];
3086 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3088 anpos = ae[aa].getPosition();
3090 if (anpos >= anot.length)
3095 anot[anpos] = new jalview.datamodel.Annotation(
3097 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3098 (ae[aa].getSecondaryStructure() == null || ae[aa]
3099 .getSecondaryStructure().length() == 0) ? ' '
3100 : ae[aa].getSecondaryStructure().charAt(0),
3104 // JBPNote: Consider verifying dataflow for IO of secondary
3105 // structure annotation read from Stockholm files
3106 // this was added to try to ensure that
3107 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3109 // anot[ae[aa].getPosition()].displayCharacter = "";
3111 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3112 if (firstColour == null)
3114 firstColour = anot[anpos].colour;
3118 jalview.datamodel.AlignmentAnnotation jaa = null;
3120 if (annotation.getGraph())
3122 float llim = 0, hlim = 0;
3123 // if (autoForView || an[i].isAutoCalculated()) {
3126 jaa = new jalview.datamodel.AlignmentAnnotation(
3127 annotation.getLabel(), annotation.getDescription(), anot,
3128 llim, hlim, annotation.getGraphType());
3130 jaa.graphGroup = annotation.getGraphGroup();
3131 jaa._linecolour = firstColour;
3132 if (annotation.getThresholdLine() != null)
3134 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3135 .getThresholdLine().getValue(), annotation
3136 .getThresholdLine().getLabel(), new java.awt.Color(
3137 annotation.getThresholdLine().getColour())));
3140 if (autoForView || annotation.isAutoCalculated())
3142 // Hardwire the symbol display line to ensure that labels for
3143 // histograms are displayed
3149 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3150 an[i].getDescription(), anot);
3151 jaa._linecolour = firstColour;
3153 // register new annotation
3154 if (an[i].getId() != null)
3156 annotationIds.put(an[i].getId(), jaa);
3157 jaa.annotationId = an[i].getId();
3159 // recover sequence association
3160 String sequenceRef = an[i].getSequenceRef();
3161 if (sequenceRef != null)
3163 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3164 SequenceI sequence = seqRefIds.get(sequenceRef);
3165 if (sequence == null)
3167 // in pre-2.9 projects sequence ref is to sequence name
3168 sequence = al.findName(sequenceRef);
3170 if (sequence != null)
3172 jaa.createSequenceMapping(sequence, 1, true);
3173 sequence.addAlignmentAnnotation(jaa);
3176 // and make a note of any group association
3177 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3179 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3180 .get(an[i].getGroupRef());
3183 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3184 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3189 if (an[i].hasScore())
3191 jaa.setScore(an[i].getScore());
3193 if (an[i].hasVisible())
3195 jaa.visible = an[i].getVisible();
3198 if (an[i].hasCentreColLabels())
3200 jaa.centreColLabels = an[i].getCentreColLabels();
3203 if (an[i].hasScaleColLabels())
3205 jaa.scaleColLabel = an[i].getScaleColLabels();
3207 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3209 // newer files have an 'autoCalculated' flag and store calculation
3210 // state in viewport properties
3211 jaa.autoCalculated = true; // means annotation will be marked for
3212 // update at end of load.
3214 if (an[i].hasGraphHeight())
3216 jaa.graphHeight = an[i].getGraphHeight();
3218 if (an[i].hasBelowAlignment())
3220 jaa.belowAlignment = an[i].isBelowAlignment();
3222 jaa.setCalcId(an[i].getCalcId());
3223 if (an[i].getPropertyCount() > 0)
3225 for (jalview.schemabinding.version2.Property prop : an[i]
3228 jaa.setProperty(prop.getName(), prop.getValue());
3231 if (jaa.autoCalculated)
3233 autoAlan.add(new JvAnnotRow(i, jaa));
3236 // if (!autoForView)
3238 // add autocalculated group annotation and any user created annotation
3240 al.addAnnotation(jaa);
3244 // ///////////////////////
3246 // Create alignment markup and styles for this view
3247 if (jms.getJGroupCount() > 0)
3249 JGroup[] groups = jms.getJGroup();
3250 boolean addAnnotSchemeGroup = false;
3251 for (int i = 0; i < groups.length; i++)
3253 JGroup jGroup = groups[i];
3254 ColourSchemeI cs = null;
3255 if (jGroup.getColour() != null)
3257 if (jGroup.getColour().startsWith("ucs"))
3259 cs = getUserColourScheme(jms, jGroup.getColour());
3261 else if (jGroup.getColour().equals("AnnotationColourGradient")
3262 && jGroup.getAnnotationColours() != null)
3264 addAnnotSchemeGroup = true;
3269 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3274 cs.setThreshold(jGroup.getPidThreshold(), true);
3278 Vector<SequenceI> seqs = new Vector<SequenceI>();
3280 for (int s = 0; s < jGroup.getSeqCount(); s++)
3282 String seqId = jGroup.getSeq(s) + "";
3283 SequenceI ts = seqRefIds.get(seqId);
3287 seqs.addElement(ts);
3291 if (seqs.size() < 1)
3296 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3297 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3298 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3300 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3302 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3303 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3304 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3305 .isShowUnconserved() : false);
3306 sg.thresholdTextColour = jGroup.getTextColThreshold();
3307 if (jGroup.hasShowConsensusHistogram())
3309 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3312 if (jGroup.hasShowSequenceLogo())
3314 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3316 if (jGroup.hasNormaliseSequenceLogo())
3318 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3320 if (jGroup.hasIgnoreGapsinConsensus())
3322 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3324 if (jGroup.getConsThreshold() != 0)
3326 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3327 "All", ResidueProperties.propHash, 3,
3328 sg.getSequences(null), 0, sg.getWidth() - 1);
3330 c.verdict(false, 25);
3331 sg.cs.setConservation(c);
3334 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3336 // re-instate unique group/annotation row reference
3337 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3341 for (AlignmentAnnotation jaa : jaal)
3344 if (jaa.autoCalculated)
3346 // match up and try to set group autocalc alignment row for this
3348 if (jaa.label.startsWith("Consensus for "))
3350 sg.setConsensus(jaa);
3352 // match up and try to set group autocalc alignment row for this
3354 if (jaa.label.startsWith("Conservation for "))
3356 sg.setConservationRow(jaa);
3363 if (addAnnotSchemeGroup)
3365 // reconstruct the annotation colourscheme
3366 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3367 null, al, jms, false);
3373 // only dataset in this model, so just return.
3376 // ///////////////////////////////
3379 // If we just load in the same jar file again, the sequenceSetId
3380 // will be the same, and we end up with multiple references
3381 // to the same sequenceSet. We must modify this id on load
3382 // so that each load of the file gives a unique id
3383 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3384 String viewId = (view.getId() == null ? null : view.getId()
3386 AlignFrame af = null;
3387 AlignViewport av = null;
3388 // now check to see if we really need to create a new viewport.
3389 if (multipleView && viewportsAdded.size() == 0)
3391 // We recovered an alignment for which a viewport already exists.
3392 // TODO: fix up any settings necessary for overlaying stored state onto
3393 // state recovered from another document. (may not be necessary).
3394 // we may need a binding from a viewport in memory to one recovered from
3396 // and then recover its containing af to allow the settings to be applied.
3397 // TODO: fix for vamsas demo
3399 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3401 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3402 if (seqsetobj != null)
3404 if (seqsetobj instanceof String)
3406 uniqueSeqSetId = (String) seqsetobj;
3408 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3414 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3420 * indicate that annotation colours are applied across all groups (pre
3421 * Jalview 2.8.1 behaviour)
3423 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3424 "2.8.1", object.getVersion());
3426 AlignmentPanel ap = null;
3427 boolean isnewview = true;
3430 // Check to see if this alignment already has a view id == viewId
3431 jalview.gui.AlignmentPanel views[] = Desktop
3432 .getAlignmentPanels(uniqueSeqSetId);
3433 if (views != null && views.length > 0)
3435 for (int v = 0; v < views.length; v++)
3437 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3439 // recover the existing alignpanel, alignframe, viewport
3440 af = views[v].alignFrame;
3443 // TODO: could even skip resetting view settings if we don't want to
3444 // change the local settings from other jalview processes
3453 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3454 uniqueSeqSetId, viewId, autoAlan);
3460 * Load any trees, PDB structures and viewers
3462 * Not done if flag is false (when this method is used for New View)
3464 if (loadTreesAndStructures)
3466 loadTrees(jms, view, af, av, ap);
3467 loadPDBStructures(jprovider, jseqs, af, ap);
3468 loadRnaViewers(jprovider, jseqs, ap);
3470 // and finally return.
3475 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3476 * panel is restored from separate jar entries, two (gapped and trimmed) per
3477 * sequence and secondary structure.
3479 * Currently each viewer shows just one sequence and structure (gapped and
3480 * trimmed), however this method is designed to support multiple sequences or
3481 * structures in viewers if wanted in future.
3487 private void loadRnaViewers(jarInputStreamProvider jprovider,
3488 JSeq[] jseqs, AlignmentPanel ap)
3491 * scan the sequences for references to viewers; create each one the first
3492 * time it is referenced, add Rna models to existing viewers
3494 for (JSeq jseq : jseqs)
3496 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3498 RnaViewer viewer = jseq.getRnaViewer(i);
3499 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3500 uniqueSetSuffix, ap);
3502 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3504 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3505 SequenceI seq = seqRefIds.get(jseq.getId());
3506 AlignmentAnnotation ann = this.annotationIds.get(ss
3507 .getAnnotationId());
3510 * add the structure to the Varna display (with session state copied
3511 * from the jar to a temporary file)
3513 boolean gapped = ss.isGapped();
3514 String rnaTitle = ss.getTitle();
3515 String sessionState = ss.getViewerState();
3516 String tempStateFile = copyJarEntry(jprovider, sessionState,
3518 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3519 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3521 appVarna.setInitialSelection(viewer.getSelectedRna());
3527 * Locate and return an already instantiated matching AppVarna, or create one
3531 * @param viewIdSuffix
3535 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3536 String viewIdSuffix, AlignmentPanel ap)
3539 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3540 * if load is repeated
3542 String postLoadId = viewer.getViewId() + viewIdSuffix;
3543 for (JInternalFrame frame : getAllFrames())
3545 if (frame instanceof AppVarna)
3547 AppVarna varna = (AppVarna) frame;
3548 if (postLoadId.equals(varna.getViewId()))
3550 // this viewer is already instantiated
3551 // could in future here add ap as another 'parent' of the
3552 // AppVarna window; currently just 1-to-many
3559 * viewer not found - make it
3561 RnaViewerModel model = new RnaViewerModel(postLoadId,
3562 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3563 viewer.getWidth(), viewer.getHeight(),
3564 viewer.getDividerLocation());
3565 AppVarna varna = new AppVarna(model, ap);
3571 * Load any saved trees
3579 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3580 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3582 // TODO result of automated refactoring - are all these parameters needed?
3585 for (int t = 0; t < jms.getTreeCount(); t++)
3588 Tree tree = jms.getTree(t);
3590 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3593 tp = af.ShowNewickTree(
3594 new jalview.io.NewickFile(tree.getNewick()),
3595 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3596 tree.getXpos(), tree.getYpos());
3597 if (tree.getId() != null)
3599 // perhaps bind the tree id to something ?
3604 // update local tree attributes ?
3605 // TODO: should check if tp has been manipulated by user - if so its
3606 // settings shouldn't be modified
3607 tp.setTitle(tree.getTitle());
3608 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3609 .getWidth(), tree.getHeight()));
3610 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3613 tp.treeCanvas.av = av; // af.viewport;
3614 tp.treeCanvas.ap = ap; // af.alignPanel;
3619 warn("There was a problem recovering stored Newick tree: \n"
3620 + tree.getNewick());
3624 tp.fitToWindow.setState(tree.getFitToWindow());
3625 tp.fitToWindow_actionPerformed(null);
3627 if (tree.getFontName() != null)
3629 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3630 .getFontStyle(), tree.getFontSize()));
3634 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3635 .getFontStyle(), tree.getFontSize()));
3638 tp.showPlaceholders(tree.getMarkUnlinked());
3639 tp.showBootstrap(tree.getShowBootstrap());
3640 tp.showDistances(tree.getShowDistances());
3642 tp.treeCanvas.threshold = tree.getThreshold();
3644 if (tree.getCurrentTree())
3646 af.viewport.setCurrentTree(tp.getTree());
3650 } catch (Exception ex)
3652 ex.printStackTrace();
3657 * Load and link any saved structure viewers.
3664 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3665 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3668 * Run through all PDB ids on the alignment, and collect mappings between
3669 * distinct view ids and all sequences referring to that view.
3671 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3673 for (int i = 0; i < jseqs.length; i++)
3675 if (jseqs[i].getPdbidsCount() > 0)
3677 Pdbids[] ids = jseqs[i].getPdbids();
3678 for (int p = 0; p < ids.length; p++)
3680 final int structureStateCount = ids[p].getStructureStateCount();
3681 for (int s = 0; s < structureStateCount; s++)
3683 // check to see if we haven't already created this structure view
3684 final StructureState structureState = ids[p]
3685 .getStructureState(s);
3686 String sviewid = (structureState.getViewId() == null) ? null
3687 : structureState.getViewId() + uniqueSetSuffix;
3688 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3689 // Originally : ids[p].getFile()
3690 // : TODO: verify external PDB file recovery still works in normal
3691 // jalview project load
3692 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3693 jpdb.setId(ids[p].getId());
3695 int x = structureState.getXpos();
3696 int y = structureState.getYpos();
3697 int width = structureState.getWidth();
3698 int height = structureState.getHeight();
3700 // Probably don't need to do this anymore...
3701 // Desktop.desktop.getComponentAt(x, y);
3702 // TODO: NOW: check that this recovers the PDB file correctly.
3703 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3704 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3706 if (sviewid == null)
3708 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3711 if (!structureViewers.containsKey(sviewid))
3713 structureViewers.put(sviewid,
3714 new StructureViewerModel(x, y, width, height, false,
3715 false, true, structureState.getViewId(),
3716 structureState.getType()));
3717 // Legacy pre-2.7 conversion JAL-823 :
3718 // do not assume any view has to be linked for colour by
3722 // assemble String[] { pdb files }, String[] { id for each
3723 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3724 // seqs_file 2}, boolean[] {
3725 // linkAlignPanel,superposeWithAlignpanel}} from hash
3726 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3727 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3728 | (structureState.hasAlignwithAlignPanel() ? structureState
3729 .getAlignwithAlignPanel() : false));
3732 * Default colour by linked panel to false if not specified (e.g.
3733 * for pre-2.7 projects)
3735 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3736 colourWithAlignPanel |= (structureState
3737 .hasColourwithAlignPanel() ? structureState
3738 .getColourwithAlignPanel() : false);
3739 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3742 * Default colour by viewer to true if not specified (e.g. for
3745 boolean colourByViewer = jmoldat.isColourByViewer();
3746 colourByViewer &= structureState.hasColourByJmol() ? structureState
3747 .getColourByJmol() : true;
3748 jmoldat.setColourByViewer(colourByViewer);
3750 if (jmoldat.getStateData().length() < structureState
3751 .getContent().length())
3754 jmoldat.setStateData(structureState.getContent());
3757 if (ids[p].getFile() != null)
3759 File mapkey = new File(ids[p].getFile());
3760 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3761 if (seqstrmaps == null)
3763 jmoldat.getFileData().put(
3765 seqstrmaps = jmoldat.new StructureData(pdbFile,
3768 if (!seqstrmaps.getSeqList().contains(seq))
3770 seqstrmaps.getSeqList().add(seq);
3776 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");
3783 // Instantiate the associated structure views
3784 for (Entry<String, StructureViewerModel> entry : structureViewers
3789 createOrLinkStructureViewer(entry, af, ap, jprovider);
3790 } catch (Exception e)
3792 System.err.println("Error loading structure viewer: "
3794 // failed - try the next one
3806 protected void createOrLinkStructureViewer(
3807 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3808 AlignmentPanel ap, jarInputStreamProvider jprovider)
3810 final StructureViewerModel stateData = viewerData.getValue();
3813 * Search for any viewer windows already open from other alignment views
3814 * that exactly match the stored structure state
3816 StructureViewerBase comp = findMatchingViewer(viewerData);
3820 linkStructureViewer(ap, comp, stateData);
3825 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3826 * "viewer_"+stateData.viewId
3828 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3830 createChimeraViewer(viewerData, af, jprovider);
3835 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3837 createJmolViewer(viewerData, af, jprovider);
3842 * Create a new Chimera viewer.
3848 protected void createChimeraViewer(
3849 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3850 jarInputStreamProvider jprovider)
3852 StructureViewerModel data = viewerData.getValue();
3853 String chimeraSessionFile = data.getStateData();
3856 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3858 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3859 * 'uniquified' sviewid used to reconstruct the viewer here
3861 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3862 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3865 Set<Entry<File, StructureData>> fileData = data.getFileData()
3867 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3868 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3869 for (Entry<File, StructureData> pdb : fileData)
3871 String filePath = pdb.getValue().getFilePath();
3872 String pdbId = pdb.getValue().getPdbId();
3873 // pdbs.add(new PDBEntry(filePath, pdbId));
3874 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3875 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3876 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3880 boolean colourByChimera = data.isColourByViewer();
3881 boolean colourBySequence = data.isColourWithAlignPanel();
3883 // TODO use StructureViewer as a factory here, see JAL-1761
3884 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3885 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3887 String newViewId = viewerData.getKey();
3889 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3890 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3891 colourBySequence, newViewId);
3892 cvf.setSize(data.getWidth(), data.getHeight());
3893 cvf.setLocation(data.getX(), data.getY());
3897 * Create a new Jmol window. First parse the Jmol state to translate filenames
3898 * loaded into the view, and record the order in which files are shown in the
3899 * Jmol view, so we can add the sequence mappings in same order.
3905 protected void createJmolViewer(
3906 final Entry<String, StructureViewerModel> viewerData,
3907 AlignFrame af, jarInputStreamProvider jprovider)
3909 final StructureViewerModel svattrib = viewerData.getValue();
3910 String state = svattrib.getStateData();
3913 * Pre-2.9: state element value is the Jmol state string
3915 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3918 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3920 state = readJarEntry(jprovider,
3921 getViewerJarEntryName(svattrib.getViewId()));
3924 List<String> pdbfilenames = new ArrayList<String>();
3925 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3926 List<String> pdbids = new ArrayList<String>();
3927 StringBuilder newFileLoc = new StringBuilder(64);
3928 int cp = 0, ncp, ecp;
3929 Map<File, StructureData> oldFiles = svattrib.getFileData();
3930 while ((ncp = state.indexOf("load ", cp)) > -1)
3934 // look for next filename in load statement
3935 newFileLoc.append(state.substring(cp,
3936 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3937 String oldfilenam = state.substring(ncp,
3938 ecp = state.indexOf("\"", ncp));
3939 // recover the new mapping data for this old filename
3940 // have to normalize filename - since Jmol and jalview do
3942 // translation differently.
3943 StructureData filedat = oldFiles.get(new File(oldfilenam));
3944 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3945 pdbfilenames.add(filedat.getFilePath());
3946 pdbids.add(filedat.getPdbId());
3947 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3948 newFileLoc.append("\"");
3949 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3950 // look for next file statement.
3951 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3955 // just append rest of state
3956 newFileLoc.append(state.substring(cp));
3960 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3961 newFileLoc = new StringBuilder(state);
3962 newFileLoc.append("; load append ");
3963 for (File id : oldFiles.keySet())
3965 // add this and any other pdb files that should be present in
3967 StructureData filedat = oldFiles.get(id);
3968 newFileLoc.append(filedat.getFilePath());
3969 pdbfilenames.add(filedat.getFilePath());
3970 pdbids.add(filedat.getPdbId());
3971 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3972 newFileLoc.append(" \"");
3973 newFileLoc.append(filedat.getFilePath());
3974 newFileLoc.append("\"");
3977 newFileLoc.append(";");
3980 if (newFileLoc.length() == 0)
3984 int histbug = newFileLoc.indexOf("history = ");
3988 * change "history = [true|false];" to "history = [1|0];"
3991 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3992 String val = (diff == -1) ? null : newFileLoc
3993 .substring(histbug, diff);
3994 if (val != null && val.length() >= 4)
3996 if (val.contains("e")) // eh? what can it be?
3998 if (val.trim().equals("true"))
4006 newFileLoc.replace(histbug, diff, val);
4011 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4013 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4014 final SequenceI[][] sq = seqmaps
4015 .toArray(new SequenceI[seqmaps.size()][]);
4016 final String fileloc = newFileLoc.toString();
4017 final String sviewid = viewerData.getKey();
4018 final AlignFrame alf = af;
4019 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4020 svattrib.getWidth(), svattrib.getHeight());
4023 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4028 JalviewStructureDisplayI sview = null;
4031 sview = new StructureViewer(alf.alignPanel
4032 .getStructureSelectionManager()).createView(
4033 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4034 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4035 addNewStructureViewer(sview);
4036 } catch (OutOfMemoryError ex)
4038 new OOMWarning("restoring structure view for PDB id " + id,
4039 (OutOfMemoryError) ex.getCause());
4040 if (sview != null && sview.isVisible())
4042 sview.closeViewer(false);
4043 sview.setVisible(false);
4049 } catch (InvocationTargetException ex)
4051 warn("Unexpected error when opening Jmol view.", ex);
4053 } catch (InterruptedException e)
4055 // e.printStackTrace();
4061 * Generates a name for the entry in the project jar file to hold state
4062 * information for a structure viewer
4067 protected String getViewerJarEntryName(String viewId)
4069 return VIEWER_PREFIX + viewId;
4073 * Returns any open frame that matches given structure viewer data. The match
4074 * is based on the unique viewId, or (for older project versions) the frame's
4080 protected StructureViewerBase findMatchingViewer(
4081 Entry<String, StructureViewerModel> viewerData)
4083 final String sviewid = viewerData.getKey();
4084 final StructureViewerModel svattrib = viewerData.getValue();
4085 StructureViewerBase comp = null;
4086 JInternalFrame[] frames = getAllFrames();
4087 for (JInternalFrame frame : frames)
4089 if (frame instanceof StructureViewerBase)
4092 * Post jalview 2.4 schema includes structure view id
4095 && ((StructureViewerBase) frame).getViewId()
4098 comp = (StructureViewerBase) frame;
4099 break; // break added in 2.9
4102 * Otherwise test for matching position and size of viewer frame
4104 else if (frame.getX() == svattrib.getX()
4105 && frame.getY() == svattrib.getY()
4106 && frame.getHeight() == svattrib.getHeight()
4107 && frame.getWidth() == svattrib.getWidth())
4109 comp = (StructureViewerBase) frame;
4110 // no break in faint hope of an exact match on viewId
4118 * Link an AlignmentPanel to an existing structure viewer.
4123 * @param useinViewerSuperpos
4124 * @param usetoColourbyseq
4125 * @param viewerColouring
4127 protected void linkStructureViewer(AlignmentPanel ap,
4128 StructureViewerBase viewer, StructureViewerModel stateData)
4130 // NOTE: if the jalview project is part of a shared session then
4131 // view synchronization should/could be done here.
4133 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4134 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4135 final boolean viewerColouring = stateData.isColourByViewer();
4136 Map<File, StructureData> oldFiles = stateData.getFileData();
4139 * Add mapping for sequences in this view to an already open viewer
4141 final AAStructureBindingModel binding = viewer.getBinding();
4142 for (File id : oldFiles.keySet())
4144 // add this and any other pdb files that should be present in the
4146 StructureData filedat = oldFiles.get(id);
4147 String pdbFile = filedat.getFilePath();
4148 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4149 binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE);
4150 binding.addSequenceForStructFile(pdbFile, seq);
4152 // and add the AlignmentPanel's reference to the view panel
4153 viewer.addAlignmentPanel(ap);
4154 if (useinViewerSuperpos)
4156 viewer.useAlignmentPanelForSuperposition(ap);
4160 viewer.excludeAlignmentPanelForSuperposition(ap);
4162 if (usetoColourbyseq)
4164 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4168 viewer.excludeAlignmentPanelForColourbyseq(ap);
4173 * Get all frames within the Desktop.
4177 protected JInternalFrame[] getAllFrames()
4179 JInternalFrame[] frames = null;
4180 // TODO is this necessary - is it safe - risk of hanging?
4185 frames = Desktop.desktop.getAllFrames();
4186 } catch (ArrayIndexOutOfBoundsException e)
4188 // occasional No such child exceptions are thrown here...
4192 } catch (InterruptedException f)
4196 } while (frames == null);
4201 * Answers true if 'version' is equal to or later than 'supported', where each
4202 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4203 * changes. Development and test values for 'version' are leniently treated
4207 * - minimum version we are comparing against
4209 * - version of data being processsed
4212 public static boolean isVersionStringLaterThan(String supported,
4215 if (supported == null || version == null
4216 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4217 || version.equalsIgnoreCase("Test")
4218 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4220 System.err.println("Assuming project file with "
4221 + (version == null ? "null" : version)
4222 + " is compatible with Jalview version " + supported);
4227 return StringUtils.compareVersions(version, supported, "b") >= 0;
4231 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4233 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4235 if (newStructureViewers != null)
4237 sview.getBinding().setFinishedLoadingFromArchive(false);
4238 newStructureViewers.add(sview);
4242 protected void setLoadingFinishedForNewStructureViewers()
4244 if (newStructureViewers != null)
4246 for (JalviewStructureDisplayI sview : newStructureViewers)
4248 sview.getBinding().setFinishedLoadingFromArchive(true);
4250 newStructureViewers.clear();
4251 newStructureViewers = null;
4255 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4256 List<SequenceI> hiddenSeqs, AlignmentI al,
4257 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4258 String viewId, List<JvAnnotRow> autoAlan)
4260 AlignFrame af = null;
4261 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4262 uniqueSeqSetId, viewId);
4264 af.setFileName(file, FileFormat.Jalview);
4266 for (int i = 0; i < JSEQ.length; i++)
4268 af.viewport.setSequenceColour(af.viewport.getAlignment()
4269 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4274 af.getViewport().setColourByReferenceSeq(true);
4275 af.getViewport().setDisplayReferenceSeq(true);
4278 af.viewport.setGatherViewsHere(view.getGatheredViews());
4280 if (view.getSequenceSetId() != null)
4282 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4284 af.viewport.setSequenceSetId(uniqueSeqSetId);
4287 // propagate shared settings to this new view
4288 af.viewport.setHistoryList(av.getHistoryList());
4289 af.viewport.setRedoList(av.getRedoList());
4293 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4295 // TODO: check if this method can be called repeatedly without
4296 // side-effects if alignpanel already registered.
4297 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4299 // apply Hidden regions to view.
4300 if (hiddenSeqs != null)
4302 for (int s = 0; s < JSEQ.length; s++)
4304 SequenceGroup hidden = new SequenceGroup();
4305 boolean isRepresentative = false;
4306 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4308 isRepresentative = true;
4309 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4310 .getHiddenSequences(r));
4311 hidden.addSequence(sequenceToHide, false);
4312 // remove from hiddenSeqs list so we don't try to hide it twice
4313 hiddenSeqs.remove(sequenceToHide);
4315 if (isRepresentative)
4317 SequenceI representativeSequence = al.getSequenceAt(s);
4318 hidden.addSequence(representativeSequence, false);
4319 af.viewport.hideRepSequences(representativeSequence, hidden);
4323 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4325 af.viewport.hideSequence(hseqs);
4328 // recover view properties and display parameters
4329 if (view.getViewName() != null)
4331 af.viewport.viewName = view.getViewName();
4332 af.setInitialTabVisible();
4334 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4337 af.viewport.setShowAnnotation(view.getShowAnnotation());
4338 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4340 af.viewport.setColourText(view.getShowColourText());
4342 af.viewport.setConservationSelected(view.getConservationSelected());
4343 af.viewport.setShowJVSuffix(view.getShowFullId());
4344 af.viewport.setRightAlignIds(view.getRightAlignIds());
4345 af.viewport.setFont(
4346 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4347 .getFontSize()), true);
4348 ViewStyleI vs = af.viewport.getViewStyle();
4349 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4350 af.viewport.setViewStyle(vs);
4351 // TODO: allow custom charWidth/Heights to be restored by updating them
4352 // after setting font - which means set above to false
4353 af.viewport.setRenderGaps(view.getRenderGaps());
4354 af.viewport.setWrapAlignment(view.getWrapAlignment());
4355 af.viewport.setShowAnnotation(view.getShowAnnotation());
4357 af.viewport.setShowBoxes(view.getShowBoxes());
4359 af.viewport.setShowText(view.getShowText());
4361 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4362 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4363 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4364 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4365 .isShowUnconserved() : false);
4366 af.viewport.setStartRes(view.getStartRes());
4367 af.viewport.setStartSeq(view.getStartSeq());
4368 af.alignPanel.updateLayout();
4369 ColourSchemeI cs = null;
4370 // apply colourschemes
4371 if (view.getBgColour() != null)
4373 if (view.getBgColour().startsWith("ucs"))
4375 cs = getUserColourScheme(jms, view.getBgColour());
4377 else if (view.getBgColour().startsWith("Annotation"))
4379 AnnotationColours viewAnnColour = view.getAnnotationColours();
4380 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4387 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4392 cs.setThreshold(view.getPidThreshold(), true);
4393 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4397 af.viewport.setGlobalColourScheme(cs);
4398 af.viewport.setColourAppliesToAllGroups(false);
4400 if (view.getConservationSelected() && cs != null)
4402 cs.setConservationInc(view.getConsThreshold());
4405 af.changeColour(cs);
4407 af.viewport.setColourAppliesToAllGroups(true);
4409 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4411 if (view.hasCentreColumnLabels())
4413 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4415 if (view.hasIgnoreGapsinConsensus())
4417 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4420 if (view.hasFollowHighlight())
4422 af.viewport.setFollowHighlight(view.getFollowHighlight());
4424 if (view.hasFollowSelection())
4426 af.viewport.followSelection = view.getFollowSelection();
4428 if (view.hasShowConsensusHistogram())
4430 af.viewport.setShowConsensusHistogram(view
4431 .getShowConsensusHistogram());
4435 af.viewport.setShowConsensusHistogram(true);
4437 if (view.hasShowSequenceLogo())
4439 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4443 af.viewport.setShowSequenceLogo(false);
4445 if (view.hasNormaliseSequenceLogo())
4447 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4449 if (view.hasShowDbRefTooltip())
4451 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4453 if (view.hasShowNPfeatureTooltip())
4455 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4457 if (view.hasShowGroupConsensus())
4459 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4463 af.viewport.setShowGroupConsensus(false);
4465 if (view.hasShowGroupConservation())
4467 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4471 af.viewport.setShowGroupConservation(false);
4474 // recover featre settings
4475 if (jms.getFeatureSettings() != null)
4477 FeaturesDisplayed fdi;
4478 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4479 String[] renderOrder = new String[jms.getFeatureSettings()
4480 .getSettingCount()];
4481 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4482 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4484 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4486 Setting setting = jms.getFeatureSettings().getSetting(fs);
4487 if (setting.hasMincolour())
4489 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4490 new Color(setting.getMincolour()), new Color(
4491 setting.getColour()), setting.getMin(),
4492 setting.getMax()) : new FeatureColour(new Color(
4493 setting.getMincolour()), new Color(setting.getColour()),
4495 if (setting.hasThreshold())
4497 gc.setThreshold(setting.getThreshold());
4498 int threshstate = setting.getThreshstate();
4499 // -1 = None, 0 = Below, 1 = Above threshold
4500 if (threshstate == 0)
4502 gc.setBelowThreshold(true);
4504 else if (threshstate == 1)
4506 gc.setAboveThreshold(true);
4509 gc.setAutoScaled(true); // default
4510 if (setting.hasAutoScale())
4512 gc.setAutoScaled(setting.getAutoScale());
4514 if (setting.hasColourByLabel())
4516 gc.setColourByLabel(setting.getColourByLabel());
4518 // and put in the feature colour table.
4519 featureColours.put(setting.getType(), gc);
4523 featureColours.put(setting.getType(), new FeatureColour(
4524 new Color(setting.getColour())));
4526 renderOrder[fs] = setting.getType();
4527 if (setting.hasOrder())
4529 featureOrder.put(setting.getType(), setting.getOrder());
4533 featureOrder.put(setting.getType(), new Float(fs
4534 / jms.getFeatureSettings().getSettingCount()));
4536 if (setting.getDisplay())
4538 fdi.setVisible(setting.getType());
4541 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4542 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4544 Group grp = jms.getFeatureSettings().getGroup(gs);
4545 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4547 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4548 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4549 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4550 FeatureRendererSettings frs = new FeatureRendererSettings(
4551 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4552 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4553 .transferSettings(frs);
4557 if (view.getHiddenColumnsCount() > 0)
4559 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4561 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4562 .getHiddenColumns(c).getEnd() // +1
4566 if (view.getCalcIdParam() != null)
4568 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4570 if (calcIdParam != null)
4572 if (recoverCalcIdParam(calcIdParam, af.viewport))
4577 warn("Couldn't recover parameters for "
4578 + calcIdParam.getCalcId());
4583 af.setMenusFromViewport(af.viewport);
4584 af.setTitle(view.getTitle());
4585 // TODO: we don't need to do this if the viewport is aready visible.
4587 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4588 * has a 'cdna/protein complement' view, in which case save it in order to
4589 * populate a SplitFrame once all views have been read in.
4591 String complementaryViewId = view.getComplementId();
4592 if (complementaryViewId == null)
4594 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4596 // recompute any autoannotation
4597 af.alignPanel.updateAnnotation(false, true);
4598 reorderAutoannotation(af, al, autoAlan);
4599 af.alignPanel.alignmentChanged();
4603 splitFrameCandidates.put(view, af);
4608 private ColourSchemeI constructAnnotationColour(
4609 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4610 JalviewModelSequence jms, boolean checkGroupAnnColour)
4612 boolean propagateAnnColour = false;
4613 ColourSchemeI cs = null;
4614 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4615 if (checkGroupAnnColour && al.getGroups() != null
4616 && al.getGroups().size() > 0)
4618 // pre 2.8.1 behaviour
4619 // check to see if we should transfer annotation colours
4620 propagateAnnColour = true;
4621 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4623 if (sg.cs instanceof AnnotationColourGradient)
4625 propagateAnnColour = false;
4629 // int find annotation
4630 if (annAlignment.getAlignmentAnnotation() != null)
4632 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4634 if (annAlignment.getAlignmentAnnotation()[i].label
4635 .equals(viewAnnColour.getAnnotation()))
4637 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4639 annAlignment.getAlignmentAnnotation()[i]
4640 .setThreshold(new jalview.datamodel.GraphLine(
4641 viewAnnColour.getThreshold(), "Threshold",
4642 java.awt.Color.black)
4647 if (viewAnnColour.getColourScheme().equals("None"))
4649 cs = new AnnotationColourGradient(
4650 annAlignment.getAlignmentAnnotation()[i],
4651 new java.awt.Color(viewAnnColour.getMinColour()),
4652 new java.awt.Color(viewAnnColour.getMaxColour()),
4653 viewAnnColour.getAboveThreshold());
4655 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4657 cs = new AnnotationColourGradient(
4658 annAlignment.getAlignmentAnnotation()[i],
4659 getUserColourScheme(jms,
4660 viewAnnColour.getColourScheme()),
4661 viewAnnColour.getAboveThreshold());
4665 cs = new AnnotationColourGradient(
4666 annAlignment.getAlignmentAnnotation()[i],
4667 ColourSchemeProperty.getColour(al,
4668 viewAnnColour.getColourScheme()),
4669 viewAnnColour.getAboveThreshold());
4671 if (viewAnnColour.hasPerSequence())
4673 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4676 if (viewAnnColour.hasPredefinedColours())
4678 ((AnnotationColourGradient) cs)
4679 .setPredefinedColours(viewAnnColour
4680 .isPredefinedColours());
4682 if (propagateAnnColour && al.getGroups() != null)
4684 // Also use these settings for all the groups
4685 for (int g = 0; g < al.getGroups().size(); g++)
4687 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4695 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4696 * new AnnotationColourGradient(
4697 * annAlignment.getAlignmentAnnotation()[i], new
4698 * java.awt.Color(viewAnnColour. getMinColour()), new
4699 * java.awt.Color(viewAnnColour. getMaxColour()),
4700 * viewAnnColour.getAboveThreshold()); } else
4703 sg.cs = new AnnotationColourGradient(
4704 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4705 viewAnnColour.getAboveThreshold());
4706 if (cs instanceof AnnotationColourGradient)
4708 if (viewAnnColour.hasPerSequence())
4710 ((AnnotationColourGradient) cs)
4711 .setSeqAssociated(viewAnnColour.isPerSequence());
4713 if (viewAnnColour.hasPredefinedColours())
4715 ((AnnotationColourGradient) cs)
4716 .setPredefinedColours(viewAnnColour
4717 .isPredefinedColours());
4733 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4734 List<JvAnnotRow> autoAlan)
4736 // copy over visualization settings for autocalculated annotation in the
4738 if (al.getAlignmentAnnotation() != null)
4741 * Kludge for magic autoannotation names (see JAL-811)
4743 String[] magicNames = new String[] { "Consensus", "Quality",
4745 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4746 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4747 for (String nm : magicNames)
4749 visan.put(nm, nullAnnot);
4751 for (JvAnnotRow auan : autoAlan)
4753 visan.put(auan.template.label
4754 + (auan.template.getCalcId() == null ? "" : "\t"
4755 + auan.template.getCalcId()), auan);
4757 int hSize = al.getAlignmentAnnotation().length;
4758 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4759 // work through any autoCalculated annotation already on the view
4760 // removing it if it should be placed in a different location on the
4761 // annotation panel.
4762 List<String> remains = new ArrayList<String>(visan.keySet());
4763 for (int h = 0; h < hSize; h++)
4765 jalview.datamodel.AlignmentAnnotation jalan = al
4766 .getAlignmentAnnotation()[h];
4767 if (jalan.autoCalculated)
4770 JvAnnotRow valan = visan.get(k = jalan.label);
4771 if (jalan.getCalcId() != null)
4773 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4778 // delete the auto calculated row from the alignment
4779 al.deleteAnnotation(jalan, false);
4783 if (valan != nullAnnot)
4785 if (jalan != valan.template)
4787 // newly created autoannotation row instance
4788 // so keep a reference to the visible annotation row
4789 // and copy over all relevant attributes
4790 if (valan.template.graphHeight >= 0)
4793 jalan.graphHeight = valan.template.graphHeight;
4795 jalan.visible = valan.template.visible;
4797 reorder.add(new JvAnnotRow(valan.order, jalan));
4802 // Add any (possibly stale) autocalculated rows that were not appended to
4803 // the view during construction
4804 for (String other : remains)
4806 JvAnnotRow othera = visan.get(other);
4807 if (othera != nullAnnot && othera.template.getCalcId() != null
4808 && othera.template.getCalcId().length() > 0)
4810 reorder.add(othera);
4813 // now put the automatic annotation in its correct place
4814 int s = 0, srt[] = new int[reorder.size()];
4815 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4816 for (JvAnnotRow jvar : reorder)
4819 srt[s++] = jvar.order;
4822 jalview.util.QuickSort.sort(srt, rws);
4823 // and re-insert the annotation at its correct position
4824 for (JvAnnotRow jvar : rws)
4826 al.addAnnotation(jvar.template, jvar.order);
4828 af.alignPanel.adjustAnnotationHeight();
4832 Hashtable skipList = null;
4835 * TODO remove this method
4838 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4839 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4840 * throw new Error("Implementation Error. No skipList defined for this
4841 * Jalview2XML instance."); } return (AlignFrame)
4842 * skipList.get(view.getSequenceSetId()); }
4846 * Check if the Jalview view contained in object should be skipped or not.
4849 * @return true if view's sequenceSetId is a key in skipList
4851 private boolean skipViewport(JalviewModel object)
4853 if (skipList == null)
4858 if (skipList.containsKey(id = object.getJalviewModelSequence()
4859 .getViewport()[0].getSequenceSetId()))
4861 if (Cache.log != null && Cache.log.isDebugEnabled())
4863 Cache.log.debug("Skipping seuqence set id " + id);
4870 public void addToSkipList(AlignFrame af)
4872 if (skipList == null)
4874 skipList = new Hashtable();
4876 skipList.put(af.getViewport().getSequenceSetId(), af);
4879 public void clearSkipList()
4881 if (skipList != null)
4888 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4889 boolean ignoreUnrefed)
4891 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4893 Vector dseqs = null;
4896 // create a list of new dataset sequences
4897 dseqs = new Vector();
4899 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4901 Sequence vamsasSeq = vamsasSet.getSequence(i);
4902 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4904 // create a new dataset
4907 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4908 dseqs.copyInto(dsseqs);
4909 ds = new jalview.datamodel.Alignment(dsseqs);
4910 debug("Created new dataset " + vamsasSet.getDatasetId()
4911 + " for alignment " + System.identityHashCode(al));
4912 addDatasetRef(vamsasSet.getDatasetId(), ds);
4914 // set the dataset for the newly imported alignment.
4915 if (al.getDataset() == null && !ignoreUnrefed)
4924 * sequence definition to create/merge dataset sequence for
4928 * vector to add new dataset sequence to
4930 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4931 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4933 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4935 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4936 SequenceI dsq = null;
4937 if (sq != null && sq.getDatasetSequence() != null)
4939 dsq = sq.getDatasetSequence();
4941 if (sq == null && ignoreUnrefed)
4945 String sqid = vamsasSeq.getDsseqid();
4948 // need to create or add a new dataset sequence reference to this sequence
4951 dsq = seqRefIds.get(sqid);
4956 // make a new dataset sequence
4957 dsq = sq.createDatasetSequence();
4960 // make up a new dataset reference for this sequence
4961 sqid = seqHash(dsq);
4963 dsq.setVamsasId(uniqueSetSuffix + sqid);
4964 seqRefIds.put(sqid, dsq);
4969 dseqs.addElement(dsq);
4974 ds.addSequence(dsq);
4980 { // make this dataset sequence sq's dataset sequence
4981 sq.setDatasetSequence(dsq);
4982 // and update the current dataset alignment
4987 if (!dseqs.contains(dsq))
4994 if (ds.findIndex(dsq) < 0)
4996 ds.addSequence(dsq);
5003 // TODO: refactor this as a merge dataset sequence function
5004 // now check that sq (the dataset sequence) sequence really is the union of
5005 // all references to it
5006 // boolean pre = sq.getStart() < dsq.getStart();
5007 // boolean post = sq.getEnd() > dsq.getEnd();
5011 // StringBuffer sb = new StringBuffer();
5012 String newres = jalview.analysis.AlignSeq.extractGaps(
5013 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5014 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5015 && newres.length() > dsq.getLength())
5017 // Update with the longer sequence.
5021 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5022 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5023 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5024 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5026 dsq.setSequence(newres);
5028 // TODO: merges will never happen if we 'know' we have the real dataset
5029 // sequence - this should be detected when id==dssid
5031 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5032 // + (pre ? "prepended" : "") + " "
5033 // + (post ? "appended" : ""));
5039 * TODO use AlignmentI here and in related methods - needs
5040 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5042 Hashtable<String, AlignmentI> datasetIds = null;
5044 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5046 private AlignmentI getDatasetFor(String datasetId)
5048 if (datasetIds == null)
5050 datasetIds = new Hashtable<String, AlignmentI>();
5053 if (datasetIds.containsKey(datasetId))
5055 return datasetIds.get(datasetId);
5060 private void addDatasetRef(String datasetId, AlignmentI dataset)
5062 if (datasetIds == null)
5064 datasetIds = new Hashtable<String, AlignmentI>();
5066 datasetIds.put(datasetId, dataset);
5070 * make a new dataset ID for this jalview dataset alignment
5075 private String getDatasetIdRef(AlignmentI dataset)
5077 if (dataset.getDataset() != null)
5079 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5081 String datasetId = makeHashCode(dataset, null);
5082 if (datasetId == null)
5084 // make a new datasetId and record it
5085 if (dataset2Ids == null)
5087 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5091 datasetId = dataset2Ids.get(dataset);
5093 if (datasetId == null)
5095 datasetId = "ds" + dataset2Ids.size() + 1;
5096 dataset2Ids.put(dataset, datasetId);
5102 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5104 for (int d = 0; d < sequence.getDBRefCount(); d++)
5106 DBRef dr = sequence.getDBRef(d);
5107 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5108 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5109 .getVersion(), sequence.getDBRef(d).getAccessionId());
5110 if (dr.getMapping() != null)
5112 entry.setMap(addMapping(dr.getMapping()));
5114 datasetSequence.addDBRef(entry);
5118 private jalview.datamodel.Mapping addMapping(Mapping m)
5120 SequenceI dsto = null;
5121 // Mapping m = dr.getMapping();
5122 int fr[] = new int[m.getMapListFromCount() * 2];
5123 Enumeration f = m.enumerateMapListFrom();
5124 for (int _i = 0; f.hasMoreElements(); _i += 2)
5126 MapListFrom mf = (MapListFrom) f.nextElement();
5127 fr[_i] = mf.getStart();
5128 fr[_i + 1] = mf.getEnd();
5130 int fto[] = new int[m.getMapListToCount() * 2];
5131 f = m.enumerateMapListTo();
5132 for (int _i = 0; f.hasMoreElements(); _i += 2)
5134 MapListTo mf = (MapListTo) f.nextElement();
5135 fto[_i] = mf.getStart();
5136 fto[_i + 1] = mf.getEnd();
5138 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5139 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5140 if (m.getMappingChoice() != null)
5142 MappingChoice mc = m.getMappingChoice();
5143 if (mc.getDseqFor() != null)
5145 String dsfor = "" + mc.getDseqFor();
5146 if (seqRefIds.containsKey(dsfor))
5151 jmap.setTo(seqRefIds.get(dsfor));
5155 frefedSequence.add(newMappingRef(dsfor, jmap));
5161 * local sequence definition
5163 Sequence ms = mc.getSequence();
5164 SequenceI djs = null;
5165 String sqid = ms.getDsseqid();
5166 if (sqid != null && sqid.length() > 0)
5169 * recover dataset sequence
5171 djs = seqRefIds.get(sqid);
5176 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5177 sqid = ((Object) ms).toString(); // make up a new hascode for
5178 // undefined dataset sequence hash
5179 // (unlikely to happen)
5185 * make a new dataset sequence and add it to refIds hash
5187 djs = new jalview.datamodel.Sequence(ms.getName(),
5189 djs.setStart(jmap.getMap().getToLowest());
5190 djs.setEnd(jmap.getMap().getToHighest());
5191 djs.setVamsasId(uniqueSetSuffix + sqid);
5193 incompleteSeqs.put(sqid, djs);
5194 seqRefIds.put(sqid, djs);
5197 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5206 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5207 boolean keepSeqRefs)
5210 JalviewModel jm = saveState(ap, null, null, null);
5215 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5219 uniqueSetSuffix = "";
5220 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5225 if (this.frefedSequence == null)
5227 frefedSequence = new Vector();
5230 viewportsAdded.clear();
5232 AlignFrame af = loadFromObject(jm, null, false, null);
5233 af.alignPanels.clear();
5234 af.closeMenuItem_actionPerformed(true);
5237 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5238 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5239 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5240 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5241 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5244 return af.alignPanel;
5248 * flag indicating if hashtables should be cleared on finalization TODO this
5249 * flag may not be necessary
5251 private final boolean _cleartables = true;
5253 private Hashtable jvids2vobj;
5258 * @see java.lang.Object#finalize()
5261 protected void finalize() throws Throwable
5263 // really make sure we have no buried refs left.
5268 this.seqRefIds = null;
5269 this.seqsToIds = null;
5273 private void warn(String msg)
5278 private void warn(String msg, Exception e)
5280 if (Cache.log != null)
5284 Cache.log.warn(msg, e);
5288 Cache.log.warn(msg);
5293 System.err.println("Warning: " + msg);
5296 e.printStackTrace();
5301 private void debug(String string)
5303 debug(string, null);
5306 private void debug(String msg, Exception e)
5308 if (Cache.log != null)
5312 Cache.log.debug(msg, e);
5316 Cache.log.debug(msg);
5321 System.err.println("Warning: " + msg);
5324 e.printStackTrace();
5330 * set the object to ID mapping tables used to write/recover objects and XML
5331 * ID strings for the jalview project. If external tables are provided then
5332 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5333 * object goes out of scope. - also populates the datasetIds hashtable with
5334 * alignment objects containing dataset sequences
5337 * Map from ID strings to jalview datamodel
5339 * Map from jalview datamodel to ID strings
5343 public void setObjectMappingTables(Hashtable vobj2jv,
5344 IdentityHashMap jv2vobj)
5346 this.jv2vobj = jv2vobj;
5347 this.vobj2jv = vobj2jv;
5348 Iterator ds = jv2vobj.keySet().iterator();
5350 while (ds.hasNext())
5352 Object jvobj = ds.next();
5353 id = jv2vobj.get(jvobj).toString();
5354 if (jvobj instanceof jalview.datamodel.Alignment)
5356 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5358 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5361 else if (jvobj instanceof jalview.datamodel.Sequence)
5363 // register sequence object so the XML parser can recover it.
5364 if (seqRefIds == null)
5366 seqRefIds = new HashMap<String, SequenceI>();
5368 if (seqsToIds == null)
5370 seqsToIds = new IdentityHashMap<SequenceI, String>();
5372 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5373 seqsToIds.put((SequenceI) jvobj, id);
5375 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5378 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5379 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5380 if (jvann.annotationId == null)
5382 jvann.annotationId = anid;
5384 if (!jvann.annotationId.equals(anid))
5386 // TODO verify that this is the correct behaviour
5387 this.warn("Overriding Annotation ID for " + anid
5388 + " from different id : " + jvann.annotationId);
5389 jvann.annotationId = anid;
5392 else if (jvobj instanceof String)
5394 if (jvids2vobj == null)
5396 jvids2vobj = new Hashtable();
5397 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5402 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5408 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5409 * objects created from the project archive. If string is null (default for
5410 * construction) then suffix will be set automatically.
5414 public void setUniqueSetSuffix(String string)
5416 uniqueSetSuffix = string;
5421 * uses skipList2 as the skipList for skipping views on sequence sets
5422 * associated with keys in the skipList
5426 public void setSkipList(Hashtable skipList2)
5428 skipList = skipList2;
5432 * Reads the jar entry of given name and returns its contents, or null if the
5433 * entry is not found.
5436 * @param jarEntryName
5439 protected String readJarEntry(jarInputStreamProvider jprovider,
5440 String jarEntryName)
5442 String result = null;
5443 BufferedReader in = null;
5448 * Reopen the jar input stream and traverse its entries to find a matching
5451 JarInputStream jin = jprovider.getJarInputStream();
5452 JarEntry entry = null;
5455 entry = jin.getNextJarEntry();
5456 } while (entry != null && !entry.getName().equals(jarEntryName));
5460 StringBuilder out = new StringBuilder(256);
5461 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5464 while ((data = in.readLine()) != null)
5468 result = out.toString();
5472 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5474 } catch (Exception ex)
5476 ex.printStackTrace();
5484 } catch (IOException e)
5495 * Returns an incrementing counter (0, 1, 2...)
5499 private synchronized int nextCounter()