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.schemabinding.version2.AlcodMap;
40 import jalview.schemabinding.version2.AlcodonFrame;
41 import jalview.schemabinding.version2.Annotation;
42 import jalview.schemabinding.version2.AnnotationColours;
43 import jalview.schemabinding.version2.AnnotationElement;
44 import jalview.schemabinding.version2.CalcIdParam;
45 import jalview.schemabinding.version2.DBRef;
46 import jalview.schemabinding.version2.Features;
47 import jalview.schemabinding.version2.Group;
48 import jalview.schemabinding.version2.HiddenColumns;
49 import jalview.schemabinding.version2.JGroup;
50 import jalview.schemabinding.version2.JSeq;
51 import jalview.schemabinding.version2.JalviewModel;
52 import jalview.schemabinding.version2.JalviewModelSequence;
53 import jalview.schemabinding.version2.MapListFrom;
54 import jalview.schemabinding.version2.MapListTo;
55 import jalview.schemabinding.version2.Mapping;
56 import jalview.schemabinding.version2.MappingChoice;
57 import jalview.schemabinding.version2.OtherData;
58 import jalview.schemabinding.version2.PdbentryItem;
59 import jalview.schemabinding.version2.Pdbids;
60 import jalview.schemabinding.version2.Property;
61 import jalview.schemabinding.version2.RnaViewer;
62 import jalview.schemabinding.version2.SecondaryStructure;
63 import jalview.schemabinding.version2.Sequence;
64 import jalview.schemabinding.version2.SequenceSet;
65 import jalview.schemabinding.version2.SequenceSetProperties;
66 import jalview.schemabinding.version2.Setting;
67 import jalview.schemabinding.version2.StructureState;
68 import jalview.schemabinding.version2.ThresholdLine;
69 import jalview.schemabinding.version2.Tree;
70 import jalview.schemabinding.version2.UserColours;
71 import jalview.schemabinding.version2.Viewport;
72 import jalview.schemes.AnnotationColourGradient;
73 import jalview.schemes.ColourSchemeI;
74 import jalview.schemes.ColourSchemeProperty;
75 import jalview.schemes.FeatureColour;
76 import jalview.schemes.ResidueColourScheme;
77 import jalview.schemes.ResidueProperties;
78 import jalview.schemes.UserColourScheme;
79 import jalview.structure.StructureSelectionManager;
80 import jalview.structures.models.AAStructureBindingModel;
81 import jalview.util.MessageManager;
82 import jalview.util.Platform;
83 import jalview.util.StringUtils;
84 import jalview.util.jarInputStreamProvider;
85 import jalview.viewmodel.AlignmentViewport;
86 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
87 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
88 import jalview.ws.jws2.Jws2Discoverer;
89 import jalview.ws.jws2.dm.AAConSettings;
90 import jalview.ws.jws2.jabaws2.Jws2Instance;
91 import jalview.ws.params.ArgumentI;
92 import jalview.ws.params.AutoCalcSetting;
93 import jalview.ws.params.WsParamSetI;
95 import java.awt.Color;
96 import java.awt.Rectangle;
97 import java.io.BufferedReader;
98 import java.io.DataInputStream;
99 import java.io.DataOutputStream;
101 import java.io.FileInputStream;
102 import java.io.FileOutputStream;
103 import java.io.IOException;
104 import java.io.InputStreamReader;
105 import java.io.OutputStreamWriter;
106 import java.io.PrintWriter;
107 import java.lang.reflect.InvocationTargetException;
108 import java.net.MalformedURLException;
110 import java.util.ArrayList;
111 import java.util.Arrays;
112 import java.util.Enumeration;
113 import java.util.HashMap;
114 import java.util.HashSet;
115 import java.util.Hashtable;
116 import java.util.IdentityHashMap;
117 import java.util.Iterator;
118 import java.util.LinkedHashMap;
119 import java.util.List;
120 import java.util.Map;
121 import java.util.Map.Entry;
122 import java.util.Set;
123 import java.util.Vector;
124 import java.util.jar.JarEntry;
125 import java.util.jar.JarInputStream;
126 import java.util.jar.JarOutputStream;
128 import javax.swing.JInternalFrame;
129 import javax.swing.JOptionPane;
130 import javax.swing.SwingUtilities;
132 import org.exolab.castor.xml.Marshaller;
133 import org.exolab.castor.xml.Unmarshaller;
136 * Write out the current jalview desktop state as a Jalview XML stream.
138 * Note: the vamsas objects referred to here are primitive versions of the
139 * VAMSAS project schema elements - they are not the same and most likely never
143 * @version $Revision: 1.134 $
145 public class Jalview2XML
147 private static final String VIEWER_PREFIX = "viewer_";
149 private static final String RNA_PREFIX = "rna_";
151 private static final String UTF_8 = "UTF-8";
153 // use this with nextCounter() to make unique names for entities
154 private int counter = 0;
157 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
158 * of sequence objects are created.
160 IdentityHashMap<SequenceI, String> seqsToIds = null;
163 * jalview XML Sequence ID to jalview sequence object reference (both dataset
164 * and alignment sequences. Populated as XML reps of sequence objects are
167 Map<String, SequenceI> seqRefIds = null;
169 Map<String, SequenceI> incompleteSeqs = null;
171 List<SeqFref> frefedSequence = null;
173 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
176 * Map of reconstructed AlignFrame objects that appear to have come from
177 * SplitFrame objects (have a dna/protein complement view).
179 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
182 * Map from displayed rna structure models to their saved session state jar
185 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
188 * create/return unique hash string for sq
191 * @return new or existing unique string for sq
193 String seqHash(SequenceI sq)
195 if (seqsToIds == null)
199 if (seqsToIds.containsKey(sq))
201 return seqsToIds.get(sq);
205 // create sequential key
206 String key = "sq" + (seqsToIds.size() + 1);
207 key = makeHashCode(sq, key); // check we don't have an external reference
209 seqsToIds.put(sq, key);
218 if (seqRefIds != null)
222 if (seqsToIds != null)
226 if (incompleteSeqs != null)
228 incompleteSeqs.clear();
236 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
237 // seqRefIds = new Hashtable();
238 // seqsToIds = new IdentityHashMap();
244 if (seqsToIds == null)
246 seqsToIds = new IdentityHashMap<SequenceI, String>();
248 if (seqRefIds == null)
250 seqRefIds = new HashMap<String, SequenceI>();
252 if (incompleteSeqs == null)
254 incompleteSeqs = new HashMap<String, SequenceI>();
256 if (frefedSequence == null)
258 frefedSequence = new ArrayList<SeqFref>();
266 public Jalview2XML(boolean raiseGUI)
268 this.raiseGUI = raiseGUI;
272 * base class for resolving forward references to sequences by their ID
277 abstract class SeqFref
283 public SeqFref(String _sref, String type)
289 public String getSref()
294 public SequenceI getSrefSeq()
296 return seqRefIds.get(sref);
299 public boolean isResolvable()
301 return seqRefIds.get(sref) != null;
304 public SequenceI getSrefDatasetSeq()
306 SequenceI sq = seqRefIds.get(sref);
309 while (sq.getDatasetSequence() != null)
311 sq = sq.getDatasetSequence();
317 * @return true if the forward reference was fully resolved
319 abstract boolean resolve();
322 public String toString()
324 return type + " reference to " + sref;
329 * create forward reference for a mapping
335 public SeqFref newMappingRef(final String sref,
336 final jalview.datamodel.Mapping _jmap)
338 SeqFref fref = new SeqFref(sref, "Mapping")
340 public jalview.datamodel.Mapping jmap = _jmap;
345 SequenceI seq = getSrefDatasetSeq();
357 public SeqFref newAlcodMapRef(final String sref,
358 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
361 SeqFref fref = new SeqFref(sref, "Codon Frame")
363 AlignedCodonFrame cf = _cf;
365 public jalview.datamodel.Mapping mp = _jmap;
368 public boolean isResolvable()
370 return super.isResolvable() && mp.getTo() != null;
376 SequenceI seq = getSrefDatasetSeq();
381 cf.addMap(seq, mp.getTo(), mp.getMap());
388 public void resolveFrefedSequences()
390 Iterator<SeqFref> nextFref=frefedSequence.iterator();
391 int toresolve=frefedSequence.size();
392 int unresolved=0,failedtoresolve=0;
393 while (nextFref.hasNext()) {
394 SeqFref ref = nextFref.next();
395 if (ref.isResolvable())
404 } catch (Exception x) {
405 System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
415 System.err.println("Jalview Project Import: There were " + unresolved
416 + " forward references left unresolved on the stack.");
418 if (failedtoresolve>0)
420 System.err.println("SERIOUS! " + failedtoresolve
421 + " resolvable forward references failed to resolve.");
423 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
425 System.err.println("Jalview Project Import: There are "
426 + incompleteSeqs.size()
427 + " sequences which may have incomplete metadata.");
428 if (incompleteSeqs.size() < 10)
430 for (SequenceI s : incompleteSeqs.values())
432 System.err.println(s.toString());
438 .println("Too many to report. Skipping output of incomplete sequences.");
444 * This maintains a map of viewports, the key being the seqSetId. Important to
445 * set historyItem and redoList for multiple views
447 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
449 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
451 String uniqueSetSuffix = "";
454 * List of pdbfiles added to Jar
456 List<String> pdbfiles = null;
458 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
459 public void saveState(File statefile)
461 FileOutputStream fos = null;
464 fos = new FileOutputStream(statefile);
465 JarOutputStream jout = new JarOutputStream(fos);
468 } catch (Exception e)
470 // TODO: inform user of the problem - they need to know if their data was
472 if (errorMessage == null)
474 errorMessage = "Couldn't write Jalview Archive to output file '"
475 + statefile + "' - See console error log for details";
479 errorMessage += "(output file was '" + statefile + "')";
489 } catch (IOException e)
499 * Writes a jalview project archive to the given Jar output stream.
503 public void saveState(JarOutputStream jout)
505 AlignFrame[] frames = Desktop.getAlignFrames();
511 saveAllFrames(Arrays.asList(frames), jout);
515 * core method for storing state for a set of AlignFrames.
518 * - frames involving all data to be exported (including containing
521 * - project output stream
523 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
525 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
528 * ensure cached data is clear before starting
530 // todo tidy up seqRefIds, seqsToIds initialisation / reset
532 splitFrameCandidates.clear();
537 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
538 // //////////////////////////////////////////////////
540 List<String> shortNames = new ArrayList<String>();
541 List<String> viewIds = new ArrayList<String>();
544 for (int i = frames.size() - 1; i > -1; i--)
546 AlignFrame af = frames.get(i);
550 .containsKey(af.getViewport().getSequenceSetId()))
555 String shortName = makeFilename(af, shortNames);
557 int ap, apSize = af.alignPanels.size();
559 for (ap = 0; ap < apSize; ap++)
561 AlignmentPanel apanel = af.alignPanels.get(ap);
562 String fileName = apSize == 1 ? shortName : ap + shortName;
563 if (!fileName.endsWith(".xml"))
565 fileName = fileName + ".xml";
568 saveState(apanel, fileName, jout, viewIds);
570 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
572 if (!dsses.containsKey(dssid))
574 dsses.put(dssid, af);
579 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
585 } catch (Exception foo)
590 } catch (Exception ex)
592 // TODO: inform user of the problem - they need to know if their data was
594 if (errorMessage == null)
596 errorMessage = "Couldn't write Jalview Archive - see error output for details";
598 ex.printStackTrace();
603 * Generates a distinct file name, based on the title of the AlignFrame, by
604 * appending _n for increasing n until an unused name is generated. The new
605 * name (without its extension) is added to the list.
609 * @return the generated name, with .xml extension
611 protected String makeFilename(AlignFrame af, List<String> namesUsed)
613 String shortName = af.getTitle();
615 if (shortName.indexOf(File.separatorChar) > -1)
617 shortName = shortName.substring(shortName
618 .lastIndexOf(File.separatorChar) + 1);
623 while (namesUsed.contains(shortName))
625 if (shortName.endsWith("_" + (count - 1)))
627 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
630 shortName = shortName.concat("_" + count);
634 namesUsed.add(shortName);
636 if (!shortName.endsWith(".xml"))
638 shortName = shortName + ".xml";
643 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
644 public boolean saveAlignment(AlignFrame af, String jarFile,
649 FileOutputStream fos = new FileOutputStream(jarFile);
650 JarOutputStream jout = new JarOutputStream(fos);
651 List<AlignFrame> frames = new ArrayList<AlignFrame>();
653 // resolve splitframes
654 if (af.getViewport().getCodingComplement() != null)
656 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
662 saveAllFrames(frames, jout);
666 } catch (Exception foo)
672 } catch (Exception ex)
674 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
675 ex.printStackTrace();
680 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
681 String fileName, JarOutputStream jout)
684 for (String dssids : dsses.keySet())
686 AlignFrame _af = dsses.get(dssids);
687 String jfileName = fileName + " Dataset for " + _af.getTitle();
688 if (!jfileName.endsWith(".xml"))
690 jfileName = jfileName + ".xml";
692 saveState(_af.alignPanel, jfileName, true, jout, null);
697 * create a JalviewModel from an alignment view and marshall it to a
701 * panel to create jalview model for
703 * name of alignment panel written to output stream
710 public JalviewModel saveState(AlignmentPanel ap, String fileName,
711 JarOutputStream jout, List<String> viewIds)
713 return saveState(ap, fileName, false, jout, viewIds);
717 * create a JalviewModel from an alignment view and marshall it to a
721 * panel to create jalview model for
723 * name of alignment panel written to output stream
725 * when true, only write the dataset for the alignment, not the data
726 * associated with the view.
732 public JalviewModel saveState(AlignmentPanel ap, String fileName,
733 boolean storeDS, JarOutputStream jout, List<String> viewIds)
737 viewIds = new ArrayList<String>();
742 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
744 AlignViewport av = ap.av;
746 JalviewModel object = new JalviewModel();
747 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
749 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
750 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
751 "Development Build"));
754 * rjal is full height alignment, jal is actual alignment with full metadata
755 * but excludes hidden sequences.
757 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
759 if (av.hasHiddenRows())
761 rjal = jal.getHiddenSequences().getFullAlignment();
764 SequenceSet vamsasSet = new SequenceSet();
766 JalviewModelSequence jms = new JalviewModelSequence();
768 vamsasSet.setGapChar(jal.getGapCharacter() + "");
770 if (jal.getDataset() != null)
772 // dataset id is the dataset's hashcode
773 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
776 // switch jal and the dataset
777 jal = jal.getDataset();
781 if (jal.getProperties() != null)
783 Enumeration en = jal.getProperties().keys();
784 while (en.hasMoreElements())
786 String key = en.nextElement().toString();
787 SequenceSetProperties ssp = new SequenceSetProperties();
789 ssp.setValue(jal.getProperties().get(key).toString());
790 vamsasSet.addSequenceSetProperties(ssp);
795 Set<String> calcIdSet = new HashSet<String>();
798 for (final SequenceI jds : rjal.getSequences())
800 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
801 : jds.getDatasetSequence();
802 String id = seqHash(jds);
804 if (seqRefIds.get(id) != null)
806 // This happens for two reasons: 1. multiple views are being serialised.
807 // 2. the hashCode has collided with another sequence's code. This DOES
808 // HAPPEN! (PF00072.15.stk does this)
809 // JBPNote: Uncomment to debug writing out of files that do not read
810 // back in due to ArrayOutOfBoundExceptions.
811 // System.err.println("vamsasSeq backref: "+id+"");
812 // System.err.println(jds.getName()+"
813 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
814 // System.err.println("Hashcode: "+seqHash(jds));
815 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
816 // System.err.println(rsq.getName()+"
817 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
818 // System.err.println("Hashcode: "+seqHash(rsq));
822 vamsasSeq = createVamsasSequence(id, jds);
823 vamsasSet.addSequence(vamsasSeq);
824 seqRefIds.put(id, jds);
828 jseq.setStart(jds.getStart());
829 jseq.setEnd(jds.getEnd());
830 jseq.setColour(av.getSequenceColour(jds).getRGB());
832 jseq.setId(id); // jseq id should be a string not a number
835 // Store any sequences this sequence represents
836 if (av.hasHiddenRows())
838 // use rjal, contains the full height alignment
839 jseq.setHidden(av.getAlignment().getHiddenSequences()
842 if (av.isHiddenRepSequence(jds))
844 jalview.datamodel.SequenceI[] reps = av
845 .getRepresentedSequences(jds)
846 .getSequencesInOrder(rjal);
848 for (int h = 0; h < reps.length; h++)
852 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
857 // mark sequence as reference - if it is the reference for this view
860 jseq.setViewreference(jds == jal.getSeqrep());
864 // TODO: omit sequence features from each alignment view's XML dump if we
865 // are storing dataset
866 if (jds.getSequenceFeatures() != null)
868 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
870 while (index < sf.length)
872 Features features = new Features();
874 features.setBegin(sf[index].getBegin());
875 features.setEnd(sf[index].getEnd());
876 features.setDescription(sf[index].getDescription());
877 features.setType(sf[index].getType());
878 features.setFeatureGroup(sf[index].getFeatureGroup());
879 features.setScore(sf[index].getScore());
880 if (sf[index].links != null)
882 for (int l = 0; l < sf[index].links.size(); l++)
884 OtherData keyValue = new OtherData();
885 keyValue.setKey("LINK_" + l);
886 keyValue.setValue(sf[index].links.elementAt(l).toString());
887 features.addOtherData(keyValue);
890 if (sf[index].otherDetails != null)
893 Iterator<String> keys = sf[index].otherDetails.keySet()
895 while (keys.hasNext())
898 OtherData keyValue = new OtherData();
899 keyValue.setKey(key);
900 keyValue.setValue(sf[index].otherDetails.get(key).toString());
901 features.addOtherData(keyValue);
905 jseq.addFeatures(features);
910 if (jdatasq.getAllPDBEntries() != null)
912 Enumeration en = jdatasq.getAllPDBEntries().elements();
913 while (en.hasMoreElements())
915 Pdbids pdb = new Pdbids();
916 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
919 String pdbId = entry.getId();
921 pdb.setType(entry.getType());
924 * Store any structure views associated with this sequence. This
925 * section copes with duplicate entries in the project, so a dataset
926 * only view *should* be coped with sensibly.
928 // This must have been loaded, is it still visible?
929 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
930 String matchedFile = null;
931 for (int f = frames.length - 1; f > -1; f--)
933 if (frames[f] instanceof StructureViewerBase)
935 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
936 matchedFile = saveStructureState(ap, jds, pdb, entry,
937 viewIds, matchedFile, viewFrame);
939 * Only store each structure viewer's state once in the project
940 * jar. First time through only (storeDS==false)
942 String viewId = viewFrame.getViewId();
943 if (!storeDS && !viewIds.contains(viewId))
948 String viewerState = viewFrame.getStateInfo();
949 writeJarEntry(jout, getViewerJarEntryName(viewId),
950 viewerState.getBytes());
951 } catch (IOException e)
953 System.err.println("Error saving viewer state: "
960 if (matchedFile != null || entry.getFile() != null)
962 if (entry.getFile() != null)
965 matchedFile = entry.getFile();
967 pdb.setFile(matchedFile); // entry.getFile());
968 if (pdbfiles == null)
970 pdbfiles = new ArrayList<String>();
973 if (!pdbfiles.contains(pdbId))
976 copyFileToJar(jout, matchedFile, pdbId);
980 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
982 PdbentryItem item = new PdbentryItem();
983 Hashtable properties = entry.getProperty();
984 Enumeration en2 = properties.keys();
985 while (en2.hasMoreElements())
987 Property prop = new Property();
988 String key = en2.nextElement().toString();
990 prop.setValue(properties.get(key).toString());
991 item.addProperty(prop);
993 pdb.addPdbentryItem(item);
1000 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1005 if (!storeDS && av.hasHiddenRows())
1007 jal = av.getAlignment();
1011 if (storeDS && jal.getCodonFrames() != null)
1013 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1014 for (AlignedCodonFrame acf : jac)
1016 AlcodonFrame alc = new AlcodonFrame();
1017 if (acf.getProtMappings() != null
1018 && acf.getProtMappings().length > 0)
1020 boolean hasMap = false;
1021 SequenceI[] dnas = acf.getdnaSeqs();
1022 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1023 for (int m = 0; m < pmaps.length; m++)
1025 AlcodMap alcmap = new AlcodMap();
1026 alcmap.setDnasq(seqHash(dnas[m]));
1027 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1029 alc.addAlcodMap(alcmap);
1034 vamsasSet.addAlcodonFrame(alc);
1037 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1039 // AlcodonFrame alc = new AlcodonFrame();
1040 // vamsasSet.addAlcodonFrame(alc);
1041 // for (int p = 0; p < acf.aaWidth; p++)
1043 // Alcodon cmap = new Alcodon();
1044 // if (acf.codons[p] != null)
1046 // // Null codons indicate a gapped column in the translated peptide
1048 // cmap.setPos1(acf.codons[p][0]);
1049 // cmap.setPos2(acf.codons[p][1]);
1050 // cmap.setPos3(acf.codons[p][2]);
1052 // alc.addAlcodon(cmap);
1054 // if (acf.getProtMappings() != null
1055 // && acf.getProtMappings().length > 0)
1057 // SequenceI[] dnas = acf.getdnaSeqs();
1058 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1059 // for (int m = 0; m < pmaps.length; m++)
1061 // AlcodMap alcmap = new AlcodMap();
1062 // alcmap.setDnasq(seqHash(dnas[m]));
1063 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1065 // alc.addAlcodMap(alcmap);
1072 // /////////////////////////////////
1073 if (!storeDS && av.currentTree != null)
1075 // FIND ANY ASSOCIATED TREES
1076 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1077 if (Desktop.desktop != null)
1079 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1081 for (int t = 0; t < frames.length; t++)
1083 if (frames[t] instanceof TreePanel)
1085 TreePanel tp = (TreePanel) frames[t];
1087 if (tp.treeCanvas.av.getAlignment() == jal)
1089 Tree tree = new Tree();
1090 tree.setTitle(tp.getTitle());
1091 tree.setCurrentTree((av.currentTree == tp.getTree()));
1092 tree.setNewick(tp.getTree().toString());
1093 tree.setThreshold(tp.treeCanvas.threshold);
1095 tree.setFitToWindow(tp.fitToWindow.getState());
1096 tree.setFontName(tp.getTreeFont().getName());
1097 tree.setFontSize(tp.getTreeFont().getSize());
1098 tree.setFontStyle(tp.getTreeFont().getStyle());
1099 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1101 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1102 tree.setShowDistances(tp.distanceMenu.getState());
1104 tree.setHeight(tp.getHeight());
1105 tree.setWidth(tp.getWidth());
1106 tree.setXpos(tp.getX());
1107 tree.setYpos(tp.getY());
1108 tree.setId(makeHashCode(tp, null));
1118 * store forward refs from an annotationRow to any groups
1120 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1123 for (SequenceI sq : jal.getSequences())
1125 // Store annotation on dataset sequences only
1126 AlignmentAnnotation[] aa = sq.getAnnotation();
1127 if (aa != null && aa.length > 0)
1129 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1136 if (jal.getAlignmentAnnotation() != null)
1138 // Store the annotation shown on the alignment.
1139 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1140 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1145 if (jal.getGroups() != null)
1147 JGroup[] groups = new JGroup[jal.getGroups().size()];
1149 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1151 JGroup jGroup = new JGroup();
1152 groups[++i] = jGroup;
1154 jGroup.setStart(sg.getStartRes());
1155 jGroup.setEnd(sg.getEndRes());
1156 jGroup.setName(sg.getName());
1157 if (groupRefs.containsKey(sg))
1159 // group has references so set its ID field
1160 jGroup.setId(groupRefs.get(sg));
1164 if (sg.cs.conservationApplied())
1166 jGroup.setConsThreshold(sg.cs.getConservationInc());
1168 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1170 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1174 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1177 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1179 jGroup.setColour("AnnotationColourGradient");
1180 jGroup.setAnnotationColours(constructAnnotationColours(
1181 (jalview.schemes.AnnotationColourGradient) sg.cs,
1184 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1186 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1190 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1193 jGroup.setPidThreshold(sg.cs.getThreshold());
1196 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1197 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1198 jGroup.setDisplayText(sg.getDisplayText());
1199 jGroup.setColourText(sg.getColourText());
1200 jGroup.setTextCol1(sg.textColour.getRGB());
1201 jGroup.setTextCol2(sg.textColour2.getRGB());
1202 jGroup.setTextColThreshold(sg.thresholdTextColour);
1203 jGroup.setShowUnconserved(sg.getShowNonconserved());
1204 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1205 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1206 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1207 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1208 for (SequenceI seq : sg.getSequences())
1210 jGroup.addSeq(seqHash(seq));
1214 jms.setJGroup(groups);
1218 // /////////SAVE VIEWPORT
1219 Viewport view = new Viewport();
1220 view.setTitle(ap.alignFrame.getTitle());
1221 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1222 av.getSequenceSetId()));
1223 view.setId(av.getViewId());
1224 if (av.getCodingComplement() != null)
1226 view.setComplementId(av.getCodingComplement().getViewId());
1228 view.setViewName(av.viewName);
1229 view.setGatheredViews(av.isGatherViewsHere());
1231 Rectangle size = ap.av.getExplodedGeometry();
1232 Rectangle position = size;
1235 size = ap.alignFrame.getBounds();
1236 if (av.getCodingComplement() != null)
1238 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1246 view.setXpos(position.x);
1247 view.setYpos(position.y);
1249 view.setWidth(size.width);
1250 view.setHeight(size.height);
1252 view.setStartRes(av.startRes);
1253 view.setStartSeq(av.startSeq);
1255 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1257 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1260 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1262 AnnotationColours ac = constructAnnotationColours(
1263 (jalview.schemes.AnnotationColourGradient) av
1264 .getGlobalColourScheme(),
1267 view.setAnnotationColours(ac);
1268 view.setBgColour("AnnotationColourGradient");
1272 view.setBgColour(ColourSchemeProperty.getColourName(av
1273 .getGlobalColourScheme()));
1276 ColourSchemeI cs = av.getGlobalColourScheme();
1280 if (cs.conservationApplied())
1282 view.setConsThreshold(cs.getConservationInc());
1283 if (cs instanceof jalview.schemes.UserColourScheme)
1285 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1289 if (cs instanceof ResidueColourScheme)
1291 view.setPidThreshold(cs.getThreshold());
1295 view.setConservationSelected(av.getConservationSelected());
1296 view.setPidSelected(av.getAbovePIDThreshold());
1297 view.setFontName(av.font.getName());
1298 view.setFontSize(av.font.getSize());
1299 view.setFontStyle(av.font.getStyle());
1300 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1301 view.setRenderGaps(av.isRenderGaps());
1302 view.setShowAnnotation(av.isShowAnnotation());
1303 view.setShowBoxes(av.getShowBoxes());
1304 view.setShowColourText(av.getColourText());
1305 view.setShowFullId(av.getShowJVSuffix());
1306 view.setRightAlignIds(av.isRightAlignIds());
1307 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1308 view.setShowText(av.getShowText());
1309 view.setShowUnconserved(av.getShowUnconserved());
1310 view.setWrapAlignment(av.getWrapAlignment());
1311 view.setTextCol1(av.getTextColour().getRGB());
1312 view.setTextCol2(av.getTextColour2().getRGB());
1313 view.setTextColThreshold(av.getThresholdTextColour());
1314 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1315 view.setShowSequenceLogo(av.isShowSequenceLogo());
1316 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1317 view.setShowGroupConsensus(av.isShowGroupConsensus());
1318 view.setShowGroupConservation(av.isShowGroupConservation());
1319 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1320 view.setShowDbRefTooltip(av.isShowDBRefs());
1321 view.setFollowHighlight(av.isFollowHighlight());
1322 view.setFollowSelection(av.followSelection);
1323 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1324 if (av.getFeaturesDisplayed() != null)
1326 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1328 String[] renderOrder = ap.getSeqPanel().seqCanvas
1329 .getFeatureRenderer().getRenderOrder()
1330 .toArray(new String[0]);
1332 Vector<String> settingsAdded = new Vector<String>();
1333 if (renderOrder != null)
1335 for (String featureType : renderOrder)
1337 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1338 .getFeatureRenderer()
1339 .getFeatureStyle(featureType);
1340 Setting setting = new Setting();
1341 setting.setType(featureType);
1342 if (!fcol.isSimpleColour())
1344 setting.setColour(fcol.getMaxColour().getRGB());
1345 setting.setMincolour(fcol.getMinColour().getRGB());
1346 setting.setMin(fcol.getMin());
1347 setting.setMax(fcol.getMax());
1348 setting.setColourByLabel(fcol.isColourByLabel());
1349 setting.setAutoScale(fcol.isAutoScaled());
1350 setting.setThreshold(fcol.getThreshold());
1351 // -1 = No threshold, 0 = Below, 1 = Above
1352 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1353 : (fcol.isBelowThreshold() ? 0 : -1));
1357 setting.setColour(fcol.getColour().getRGB());
1360 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1362 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1363 .getOrder(featureType);
1366 setting.setOrder(rorder);
1368 fs.addSetting(setting);
1369 settingsAdded.addElement(featureType);
1373 // is groups actually supposed to be a map here ?
1374 Iterator<String> en = ap.getSeqPanel().seqCanvas
1375 .getFeatureRenderer()
1376 .getFeatureGroups().iterator();
1377 Vector<String> groupsAdded = new Vector<String>();
1378 while (en.hasNext())
1380 String grp = en.next();
1381 if (groupsAdded.contains(grp))
1385 Group g = new Group();
1387 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1388 .getFeatureRenderer().checkGroupVisibility(grp, false))
1391 groupsAdded.addElement(grp);
1393 jms.setFeatureSettings(fs);
1396 if (av.hasHiddenColumns())
1398 if (av.getColumnSelection() == null
1399 || av.getColumnSelection().getHiddenColumns() == null)
1401 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1405 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1408 int[] region = av.getColumnSelection().getHiddenColumns()
1410 HiddenColumns hc = new HiddenColumns();
1411 hc.setStart(region[0]);
1412 hc.setEnd(region[1]);
1413 view.addHiddenColumns(hc);
1417 if (calcIdSet.size() > 0)
1419 for (String calcId : calcIdSet)
1421 if (calcId.trim().length() > 0)
1423 CalcIdParam cidp = createCalcIdParam(calcId, av);
1424 // Some calcIds have no parameters.
1427 view.addCalcIdParam(cidp);
1433 jms.addViewport(view);
1435 object.setJalviewModelSequence(jms);
1436 object.getVamsasModel().addSequenceSet(vamsasSet);
1438 if (jout != null && fileName != null)
1440 // We may not want to write the object to disk,
1441 // eg we can copy the alignViewport to a new view object
1442 // using save and then load
1445 System.out.println("Writing jar entry " + fileName);
1446 JarEntry entry = new JarEntry(fileName);
1447 jout.putNextEntry(entry);
1448 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1450 Marshaller marshaller = new Marshaller(pout);
1451 marshaller.marshal(object);
1454 } catch (Exception ex)
1456 // TODO: raise error in GUI if marshalling failed.
1457 ex.printStackTrace();
1464 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1465 * for each viewer, with
1467 * <li>viewer geometry (position, size, split pane divider location)</li>
1468 * <li>index of the selected structure in the viewer (currently shows gapped
1470 * <li>the id of the annotation holding RNA secondary structure</li>
1471 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1473 * Varna viewer state is also written out (in native Varna XML) to separate
1474 * project jar entries. A separate entry is written for each RNA structure
1475 * displayed, with the naming convention
1477 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1485 * @param storeDataset
1487 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1488 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1489 boolean storeDataset)
1491 if (Desktop.desktop == null)
1495 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1496 for (int f = frames.length - 1; f > -1; f--)
1498 if (frames[f] instanceof AppVarna)
1500 AppVarna varna = (AppVarna) frames[f];
1502 * link the sequence to every viewer that is showing it and is linked to
1503 * its alignment panel
1505 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1507 String viewId = varna.getViewId();
1508 RnaViewer rna = new RnaViewer();
1509 rna.setViewId(viewId);
1510 rna.setTitle(varna.getTitle());
1511 rna.setXpos(varna.getX());
1512 rna.setYpos(varna.getY());
1513 rna.setWidth(varna.getWidth());
1514 rna.setHeight(varna.getHeight());
1515 rna.setDividerLocation(varna.getDividerLocation());
1516 rna.setSelectedRna(varna.getSelectedIndex());
1517 jseq.addRnaViewer(rna);
1520 * Store each Varna panel's state once in the project per sequence.
1521 * First time through only (storeDataset==false)
1523 // boolean storeSessions = false;
1524 // String sequenceViewId = viewId + seqsToIds.get(jds);
1525 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1527 // viewIds.add(sequenceViewId);
1528 // storeSessions = true;
1530 for (RnaModel model : varna.getModels())
1532 if (model.seq == jds)
1535 * VARNA saves each view (sequence or alignment secondary
1536 * structure, gapped or trimmed) as a separate XML file
1538 String jarEntryName = rnaSessions.get(model);
1539 if (jarEntryName == null)
1542 String varnaStateFile = varna.getStateInfo(model.rna);
1543 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1544 copyFileToJar(jout, varnaStateFile, jarEntryName);
1545 rnaSessions.put(model, jarEntryName);
1547 SecondaryStructure ss = new SecondaryStructure();
1548 String annotationId = varna.getAnnotation(jds).annotationId;
1549 ss.setAnnotationId(annotationId);
1550 ss.setViewerState(jarEntryName);
1551 ss.setGapped(model.gapped);
1552 ss.setTitle(model.title);
1553 rna.addSecondaryStructure(ss);
1562 * Copy the contents of a file to a new entry added to the output jar
1566 * @param jarEntryName
1568 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1569 String jarEntryName)
1571 DataInputStream dis = null;
1574 File file = new File(infilePath);
1575 if (file.exists() && jout != null)
1577 dis = new DataInputStream(new FileInputStream(file));
1578 byte[] data = new byte[(int) file.length()];
1579 dis.readFully(data);
1580 writeJarEntry(jout, jarEntryName, data);
1582 } catch (Exception ex)
1584 ex.printStackTrace();
1592 } catch (IOException e)
1601 * Write the data to a new entry of given name in the output jar file
1604 * @param jarEntryName
1606 * @throws IOException
1608 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1609 byte[] data) throws IOException
1613 System.out.println("Writing jar entry " + jarEntryName);
1614 jout.putNextEntry(new JarEntry(jarEntryName));
1615 DataOutputStream dout = new DataOutputStream(jout);
1616 dout.write(data, 0, data.length);
1623 * Save the state of a structure viewer
1628 * the archive XML element under which to save the state
1631 * @param matchedFile
1635 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1636 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1637 String matchedFile, StructureViewerBase viewFrame)
1639 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1642 * Look for any bindings for this viewer to the PDB file of interest
1643 * (including part matches excluding chain id)
1645 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1647 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1648 final String pdbId = pdbentry.getId();
1649 if (!pdbId.equals(entry.getId())
1650 && !(entry.getId().length() > 4 && entry.getId()
1651 .toLowerCase().startsWith(pdbId.toLowerCase())))
1654 * not interested in a binding to a different PDB entry here
1658 if (matchedFile == null)
1660 matchedFile = pdbentry.getFile();
1662 else if (!matchedFile.equals(pdbentry.getFile()))
1665 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1666 + pdbentry.getFile());
1670 // can get at it if the ID
1671 // match is ambiguous (e.g.
1674 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1676 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1677 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1679 StructureState state = new StructureState();
1680 state.setVisible(true);
1681 state.setXpos(viewFrame.getX());
1682 state.setYpos(viewFrame.getY());
1683 state.setWidth(viewFrame.getWidth());
1684 state.setHeight(viewFrame.getHeight());
1685 final String viewId = viewFrame.getViewId();
1686 state.setViewId(viewId);
1687 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1688 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1689 state.setColourByJmol(viewFrame.isColouredByViewer());
1690 state.setType(viewFrame.getViewerType().toString());
1691 pdb.addStructureState(state);
1698 private AnnotationColours constructAnnotationColours(
1699 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1700 JalviewModelSequence jms)
1702 AnnotationColours ac = new AnnotationColours();
1703 ac.setAboveThreshold(acg.getAboveThreshold());
1704 ac.setThreshold(acg.getAnnotationThreshold());
1705 ac.setAnnotation(acg.getAnnotation());
1706 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1708 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1713 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1717 ac.setMaxColour(acg.getMaxColour().getRGB());
1718 ac.setMinColour(acg.getMinColour().getRGB());
1719 ac.setPerSequence(acg.isSeqAssociated());
1720 ac.setPredefinedColours(acg.isPredefinedColours());
1724 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1725 IdentityHashMap<SequenceGroup, String> groupRefs,
1726 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1727 SequenceSet vamsasSet)
1730 for (int i = 0; i < aa.length; i++)
1732 Annotation an = new Annotation();
1734 AlignmentAnnotation annotation = aa[i];
1735 if (annotation.annotationId != null)
1737 annotationIds.put(annotation.annotationId, annotation);
1740 an.setId(annotation.annotationId);
1742 an.setVisible(annotation.visible);
1744 an.setDescription(annotation.description);
1746 if (annotation.sequenceRef != null)
1748 // 2.9 JAL-1781 xref on sequence id rather than name
1749 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1751 if (annotation.groupRef != null)
1753 String groupIdr = groupRefs.get(annotation.groupRef);
1754 if (groupIdr == null)
1756 // make a locally unique String
1758 annotation.groupRef,
1759 groupIdr = ("" + System.currentTimeMillis()
1760 + annotation.groupRef.getName() + groupRefs
1763 an.setGroupRef(groupIdr.toString());
1766 // store all visualization attributes for annotation
1767 an.setGraphHeight(annotation.graphHeight);
1768 an.setCentreColLabels(annotation.centreColLabels);
1769 an.setScaleColLabels(annotation.scaleColLabel);
1770 an.setShowAllColLabels(annotation.showAllColLabels);
1771 an.setBelowAlignment(annotation.belowAlignment);
1773 if (annotation.graph > 0)
1776 an.setGraphType(annotation.graph);
1777 an.setGraphGroup(annotation.graphGroup);
1778 if (annotation.getThreshold() != null)
1780 ThresholdLine line = new ThresholdLine();
1781 line.setLabel(annotation.getThreshold().label);
1782 line.setValue(annotation.getThreshold().value);
1783 line.setColour(annotation.getThreshold().colour.getRGB());
1784 an.setThresholdLine(line);
1792 an.setLabel(annotation.label);
1794 if (annotation == av.getAlignmentQualityAnnot()
1795 || annotation == av.getAlignmentConservationAnnotation()
1796 || annotation == av.getAlignmentConsensusAnnotation()
1797 || annotation.autoCalculated)
1799 // new way of indicating autocalculated annotation -
1800 an.setAutoCalculated(annotation.autoCalculated);
1802 if (annotation.hasScore())
1804 an.setScore(annotation.getScore());
1807 if (annotation.getCalcId() != null)
1809 calcIdSet.add(annotation.getCalcId());
1810 an.setCalcId(annotation.getCalcId());
1812 if (annotation.hasProperties())
1814 for (String pr : annotation.getProperties())
1816 Property prop = new Property();
1818 prop.setValue(annotation.getProperty(pr));
1819 an.addProperty(prop);
1823 AnnotationElement ae;
1824 if (annotation.annotations != null)
1826 an.setScoreOnly(false);
1827 for (int a = 0; a < annotation.annotations.length; a++)
1829 if ((annotation == null) || (annotation.annotations[a] == null))
1834 ae = new AnnotationElement();
1835 if (annotation.annotations[a].description != null)
1837 ae.setDescription(annotation.annotations[a].description);
1839 if (annotation.annotations[a].displayCharacter != null)
1841 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1844 if (!Float.isNaN(annotation.annotations[a].value))
1846 ae.setValue(annotation.annotations[a].value);
1850 if (annotation.annotations[a].secondaryStructure > ' ')
1852 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1856 if (annotation.annotations[a].colour != null
1857 && annotation.annotations[a].colour != java.awt.Color.black)
1859 ae.setColour(annotation.annotations[a].colour.getRGB());
1862 an.addAnnotationElement(ae);
1863 if (annotation.autoCalculated)
1865 // only write one non-null entry into the annotation row -
1866 // sufficient to get the visualization attributes necessary to
1874 an.setScoreOnly(true);
1876 if (!storeDS || (storeDS && !annotation.autoCalculated))
1878 // skip autocalculated annotation - these are only provided for
1880 vamsasSet.addAnnotation(an);
1886 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1888 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1889 if (settings != null)
1891 CalcIdParam vCalcIdParam = new CalcIdParam();
1892 vCalcIdParam.setCalcId(calcId);
1893 vCalcIdParam.addServiceURL(settings.getServiceURI());
1894 // generic URI allowing a third party to resolve another instance of the
1895 // service used for this calculation
1896 for (String urls : settings.getServiceURLs())
1898 vCalcIdParam.addServiceURL(urls);
1900 vCalcIdParam.setVersion("1.0");
1901 if (settings.getPreset() != null)
1903 WsParamSetI setting = settings.getPreset();
1904 vCalcIdParam.setName(setting.getName());
1905 vCalcIdParam.setDescription(setting.getDescription());
1909 vCalcIdParam.setName("");
1910 vCalcIdParam.setDescription("Last used parameters");
1912 // need to be able to recover 1) settings 2) user-defined presets or
1913 // recreate settings from preset 3) predefined settings provided by
1914 // service - or settings that can be transferred (or discarded)
1915 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1917 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1918 // todo - decide if updateImmediately is needed for any projects.
1920 return vCalcIdParam;
1925 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1928 if (calcIdParam.getVersion().equals("1.0"))
1930 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1931 .getPreferredServiceFor(calcIdParam.getServiceURL());
1932 if (service != null)
1934 WsParamSetI parmSet = null;
1937 parmSet = service.getParamStore().parseServiceParameterFile(
1938 calcIdParam.getName(), calcIdParam.getDescription(),
1939 calcIdParam.getServiceURL(),
1940 calcIdParam.getParameters().replace("|\\n|", "\n"));
1941 } catch (IOException x)
1943 warn("Couldn't parse parameter data for "
1944 + calcIdParam.getCalcId(), x);
1947 List<ArgumentI> argList = null;
1948 if (calcIdParam.getName().length() > 0)
1950 parmSet = service.getParamStore()
1951 .getPreset(calcIdParam.getName());
1952 if (parmSet != null)
1954 // TODO : check we have a good match with settings in AACon -
1955 // otherwise we'll need to create a new preset
1960 argList = parmSet.getArguments();
1963 AAConSettings settings = new AAConSettings(
1964 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1965 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1966 calcIdParam.isNeedsUpdate());
1971 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1975 throw new Error(MessageManager.formatMessage(
1976 "error.unsupported_version_calcIdparam",
1977 new Object[] { calcIdParam.toString() }));
1981 * External mapping between jalview objects and objects yielding a valid and
1982 * unique object ID string. This is null for normal Jalview project IO, but
1983 * non-null when a jalview project is being read or written as part of a
1986 IdentityHashMap jv2vobj = null;
1989 * Construct a unique ID for jvobj using either existing bindings or if none
1990 * exist, the result of the hashcode call for the object.
1993 * jalview data object
1994 * @return unique ID for referring to jvobj
1996 private String makeHashCode(Object jvobj, String altCode)
1998 if (jv2vobj != null)
2000 Object id = jv2vobj.get(jvobj);
2003 return id.toString();
2005 // check string ID mappings
2006 if (jvids2vobj != null && jvobj instanceof String)
2008 id = jvids2vobj.get(jvobj);
2012 return id.toString();
2014 // give up and warn that something has gone wrong
2015 warn("Cannot find ID for object in external mapping : " + jvobj);
2021 * return local jalview object mapped to ID, if it exists
2025 * @return null or object bound to idcode
2027 private Object retrieveExistingObj(String idcode)
2029 if (idcode != null && vobj2jv != null)
2031 return vobj2jv.get(idcode);
2037 * binding from ID strings from external mapping table to jalview data model
2040 private Hashtable vobj2jv;
2042 private Sequence createVamsasSequence(String id, SequenceI jds)
2044 return createVamsasSequence(true, id, jds, null);
2047 private Sequence createVamsasSequence(boolean recurse, String id,
2048 SequenceI jds, SequenceI parentseq)
2050 Sequence vamsasSeq = new Sequence();
2051 vamsasSeq.setId(id);
2052 vamsasSeq.setName(jds.getName());
2053 vamsasSeq.setSequence(jds.getSequenceAsString());
2054 vamsasSeq.setDescription(jds.getDescription());
2055 jalview.datamodel.DBRefEntry[] dbrefs = null;
2056 if (jds.getDatasetSequence() != null)
2058 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2062 // seqId==dsseqid so we can tell which sequences really are
2063 // dataset sequences only
2064 vamsasSeq.setDsseqid(id);
2065 dbrefs = jds.getDBRefs();
2066 if (parentseq == null)
2073 for (int d = 0; d < dbrefs.length; d++)
2075 DBRef dbref = new DBRef();
2076 dbref.setSource(dbrefs[d].getSource());
2077 dbref.setVersion(dbrefs[d].getVersion());
2078 dbref.setAccessionId(dbrefs[d].getAccessionId());
2079 if (dbrefs[d].hasMap())
2081 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2083 dbref.setMapping(mp);
2085 vamsasSeq.addDBRef(dbref);
2091 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2092 SequenceI parentseq, SequenceI jds, boolean recurse)
2095 if (jmp.getMap() != null)
2099 jalview.util.MapList mlst = jmp.getMap();
2100 List<int[]> r = mlst.getFromRanges();
2101 for (int[] range : r)
2103 MapListFrom mfrom = new MapListFrom();
2104 mfrom.setStart(range[0]);
2105 mfrom.setEnd(range[1]);
2106 mp.addMapListFrom(mfrom);
2108 r = mlst.getToRanges();
2109 for (int[] range : r)
2111 MapListTo mto = new MapListTo();
2112 mto.setStart(range[0]);
2113 mto.setEnd(range[1]);
2114 mp.addMapListTo(mto);
2116 mp.setMapFromUnit(mlst.getFromRatio());
2117 mp.setMapToUnit(mlst.getToRatio());
2118 if (jmp.getTo() != null)
2120 MappingChoice mpc = new MappingChoice();
2122 // check/create ID for the sequence referenced by getTo()
2125 SequenceI ps = null;
2126 if (parentseq != jmp.getTo()
2127 && parentseq.getDatasetSequence() != jmp.getTo())
2129 // chaining dbref rather than a handshaking one
2130 jmpid = seqHash(ps = jmp.getTo());
2134 jmpid = seqHash(ps = parentseq);
2136 mpc.setDseqFor(jmpid);
2137 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2139 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2140 seqRefIds.put(mpc.getDseqFor(), ps);
2144 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2147 mp.setMappingChoice(mpc);
2153 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2154 List<UserColourScheme> userColours, JalviewModelSequence jms)
2157 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2158 boolean newucs = false;
2159 if (!userColours.contains(ucs))
2161 userColours.add(ucs);
2164 id = "ucs" + userColours.indexOf(ucs);
2167 // actually create the scheme's entry in the XML model
2168 java.awt.Color[] colours = ucs.getColours();
2169 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2170 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2172 for (int i = 0; i < colours.length; i++)
2174 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2175 col.setName(ResidueProperties.aa[i]);
2176 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2177 jbucs.addColour(col);
2179 if (ucs.getLowerCaseColours() != null)
2181 colours = ucs.getLowerCaseColours();
2182 for (int i = 0; i < colours.length; i++)
2184 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2185 col.setName(ResidueProperties.aa[i].toLowerCase());
2186 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2187 jbucs.addColour(col);
2192 uc.setUserColourScheme(jbucs);
2193 jms.addUserColours(uc);
2199 jalview.schemes.UserColourScheme getUserColourScheme(
2200 JalviewModelSequence jms, String id)
2202 UserColours[] uc = jms.getUserColours();
2203 UserColours colours = null;
2205 for (int i = 0; i < uc.length; i++)
2207 if (uc[i].getId().equals(id))
2215 java.awt.Color[] newColours = new java.awt.Color[24];
2217 for (int i = 0; i < 24; i++)
2219 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2220 .getUserColourScheme().getColour(i).getRGB(), 16));
2223 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2226 if (colours.getUserColourScheme().getColourCount() > 24)
2228 newColours = new java.awt.Color[23];
2229 for (int i = 0; i < 23; i++)
2231 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2232 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2234 ucs.setLowerCaseColours(newColours);
2241 * contains last error message (if any) encountered by XML loader.
2243 String errorMessage = null;
2246 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2247 * exceptions are raised during project XML parsing
2249 public boolean attemptversion1parse = true;
2252 * Load a jalview project archive from a jar file
2255 * - HTTP URL or filename
2257 public AlignFrame loadJalviewAlign(final String file)
2260 jalview.gui.AlignFrame af = null;
2264 // create list to store references for any new Jmol viewers created
2265 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2266 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2267 // Workaround is to make sure caller implements the JarInputStreamProvider
2269 // so we can re-open the jar input stream for each entry.
2271 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2272 af = loadJalviewAlign(jprovider);
2274 } catch (MalformedURLException e)
2276 errorMessage = "Invalid URL format for '" + file + "'";
2282 SwingUtilities.invokeAndWait(new Runnable()
2287 setLoadingFinishedForNewStructureViewers();
2290 } catch (Exception x)
2292 System.err.println("Error loading alignment: " + x.getMessage());
2298 private jarInputStreamProvider createjarInputStreamProvider(
2299 final String file) throws MalformedURLException
2302 errorMessage = null;
2303 uniqueSetSuffix = null;
2305 viewportsAdded.clear();
2306 frefedSequence = null;
2308 if (file.startsWith("http://"))
2310 url = new URL(file);
2312 final URL _url = url;
2313 return new jarInputStreamProvider()
2317 public JarInputStream getJarInputStream() throws IOException
2321 return new JarInputStream(_url.openStream());
2325 return new JarInputStream(new FileInputStream(file));
2330 public String getFilename()
2338 * Recover jalview session from a jalview project archive. Caller may
2339 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2340 * themselves. Any null fields will be initialised with default values,
2341 * non-null fields are left alone.
2346 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2348 errorMessage = null;
2349 if (uniqueSetSuffix == null)
2351 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2353 if (seqRefIds == null)
2357 AlignFrame af = null, _af = null;
2358 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2359 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2360 final String file = jprovider.getFilename();
2363 JarInputStream jin = null;
2364 JarEntry jarentry = null;
2369 jin = jprovider.getJarInputStream();
2370 for (int i = 0; i < entryCount; i++)
2372 jarentry = jin.getNextJarEntry();
2375 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2377 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2378 JalviewModel object = new JalviewModel();
2380 Unmarshaller unmar = new Unmarshaller(object);
2381 unmar.setValidation(false);
2382 object = (JalviewModel) unmar.unmarshal(in);
2383 if (true) // !skipViewport(object))
2385 _af = loadFromObject(object, file, true, jprovider);
2387 && object.getJalviewModelSequence().getViewportCount() > 0)
2391 // store a reference to the first view
2394 if (_af.viewport.isGatherViewsHere())
2396 // if this is a gathered view, keep its reference since
2397 // after gathering views, only this frame will remain
2399 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2401 // Save dataset to register mappings once all resolved
2402 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2403 af.viewport.getAlignment().getDataset());
2408 else if (jarentry != null)
2410 // Some other file here.
2413 } while (jarentry != null);
2414 resolveFrefedSequences();
2415 } catch (IOException ex)
2417 ex.printStackTrace();
2418 errorMessage = "Couldn't locate Jalview XML file : " + file;
2419 System.err.println("Exception whilst loading jalview XML file : "
2421 } catch (Exception ex)
2423 System.err.println("Parsing as Jalview Version 2 file failed.");
2424 ex.printStackTrace(System.err);
2425 if (attemptversion1parse)
2427 // Is Version 1 Jar file?
2430 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2431 } catch (Exception ex2)
2433 System.err.println("Exception whilst loading as jalviewXMLV1:");
2434 ex2.printStackTrace();
2438 if (Desktop.instance != null)
2440 Desktop.instance.stopLoading();
2444 System.out.println("Successfully loaded archive file");
2447 ex.printStackTrace();
2449 System.err.println("Exception whilst loading jalview XML file : "
2451 } catch (OutOfMemoryError e)
2453 // Don't use the OOM Window here
2454 errorMessage = "Out of memory loading jalview XML file";
2455 System.err.println("Out of memory whilst loading jalview XML file");
2456 e.printStackTrace();
2460 * Regather multiple views (with the same sequence set id) to the frame (if
2461 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2462 * views instead of separate frames. Note this doesn't restore a state where
2463 * some expanded views in turn have tabbed views - the last "first tab" read
2464 * in will play the role of gatherer for all.
2466 for (AlignFrame fr : gatherToThisFrame.values())
2468 Desktop.instance.gatherViews(fr);
2471 restoreSplitFrames();
2472 for (AlignmentI ds : importedDatasets.keySet())
2474 if (ds.getCodonFrames() != null)
2476 StructureSelectionManager.getStructureSelectionManager(
2477 Desktop.instance).registerMappings(ds.getCodonFrames());
2480 if (errorMessage != null)
2485 if (Desktop.instance != null)
2487 Desktop.instance.stopLoading();
2494 * Try to reconstruct and display SplitFrame windows, where each contains
2495 * complementary dna and protein alignments. Done by pairing up AlignFrame
2496 * objects (created earlier) which have complementary viewport ids associated.
2498 protected void restoreSplitFrames()
2500 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2501 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2502 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2505 * Identify the DNA alignments
2507 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2510 AlignFrame af = candidate.getValue();
2511 if (af.getViewport().getAlignment().isNucleotide())
2513 dna.put(candidate.getKey().getId(), af);
2518 * Try to match up the protein complements
2520 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2523 AlignFrame af = candidate.getValue();
2524 if (!af.getViewport().getAlignment().isNucleotide())
2526 String complementId = candidate.getKey().getComplementId();
2527 // only non-null complements should be in the Map
2528 if (complementId != null && dna.containsKey(complementId))
2530 final AlignFrame dnaFrame = dna.get(complementId);
2531 SplitFrame sf = createSplitFrame(dnaFrame, af);
2532 addedToSplitFrames.add(dnaFrame);
2533 addedToSplitFrames.add(af);
2534 if (af.viewport.isGatherViewsHere())
2543 * Open any that we failed to pair up (which shouldn't happen!) as
2544 * standalone AlignFrame's.
2546 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2549 AlignFrame af = candidate.getValue();
2550 if (!addedToSplitFrames.contains(af))
2552 Viewport view = candidate.getKey();
2553 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2555 System.err.println("Failed to restore view " + view.getTitle()
2556 + " to split frame");
2561 * Gather back into tabbed views as flagged.
2563 for (SplitFrame sf : gatherTo)
2565 Desktop.instance.gatherViews(sf);
2568 splitFrameCandidates.clear();
2572 * Construct and display one SplitFrame holding DNA and protein alignments.
2575 * @param proteinFrame
2578 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2579 AlignFrame proteinFrame)
2581 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2582 String title = MessageManager.getString("label.linked_view_title");
2583 int width = (int) dnaFrame.getBounds().getWidth();
2584 int height = (int) (dnaFrame.getBounds().getHeight()
2585 + proteinFrame.getBounds().getHeight() + 50);
2588 * SplitFrame location is saved to both enclosed frames
2590 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2591 Desktop.addInternalFrame(splitFrame, title, width, height);
2594 * And compute cDNA consensus (couldn't do earlier with consensus as
2595 * mappings were not yet present)
2597 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2603 * check errorMessage for a valid error message and raise an error box in the
2604 * GUI or write the current errorMessage to stderr and then clear the error
2607 protected void reportErrors()
2609 reportErrors(false);
2612 protected void reportErrors(final boolean saving)
2614 if (errorMessage != null)
2616 final String finalErrorMessage = errorMessage;
2619 javax.swing.SwingUtilities.invokeLater(new Runnable()
2624 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2625 finalErrorMessage, "Error "
2626 + (saving ? "saving" : "loading")
2627 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2633 System.err.println("Problem loading Jalview file: " + errorMessage);
2636 errorMessage = null;
2639 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2642 * when set, local views will be updated from view stored in JalviewXML
2643 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2644 * sync if this is set to true.
2646 private final boolean updateLocalViews = false;
2649 * Returns the path to a temporary file holding the PDB file for the given PDB
2650 * id. The first time of asking, searches for a file of that name in the
2651 * Jalview project jar, and copies it to a new temporary file. Any repeat
2652 * requests just return the path to the file previously created.
2658 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2660 if (alreadyLoadedPDB.containsKey(pdbId))
2662 return alreadyLoadedPDB.get(pdbId).toString();
2665 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2666 if (tempFile != null)
2668 alreadyLoadedPDB.put(pdbId, tempFile);
2674 * Copies the jar entry of given name to a new temporary file and returns the
2675 * path to the file, or null if the entry is not found.
2678 * @param jarEntryName
2680 * a prefix for the temporary file name, must be at least three
2684 protected String copyJarEntry(jarInputStreamProvider jprovider,
2685 String jarEntryName, String prefix)
2687 BufferedReader in = null;
2688 PrintWriter out = null;
2692 JarInputStream jin = jprovider.getJarInputStream();
2694 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2695 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2696 * FileInputStream(jprovider)); }
2699 JarEntry entry = null;
2702 entry = jin.getNextJarEntry();
2703 } while (entry != null && !entry.getName().equals(jarEntryName));
2706 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2707 File outFile = File.createTempFile(prefix, ".tmp");
2708 outFile.deleteOnExit();
2709 out = new PrintWriter(new FileOutputStream(outFile));
2712 while ((data = in.readLine()) != null)
2717 String t = outFile.getAbsolutePath();
2722 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2724 } catch (Exception ex)
2726 ex.printStackTrace();
2734 } catch (IOException e)
2748 private class JvAnnotRow
2750 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2757 * persisted version of annotation row from which to take vis properties
2759 public jalview.datamodel.AlignmentAnnotation template;
2762 * original position of the annotation row in the alignment
2768 * Load alignment frame from jalview XML DOM object
2773 * filename source string
2774 * @param loadTreesAndStructures
2775 * when false only create Viewport
2777 * data source provider
2778 * @return alignment frame created from view stored in DOM
2780 AlignFrame loadFromObject(JalviewModel object, String file,
2781 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2783 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2784 Sequence[] vamsasSeq = vamsasSet.getSequence();
2786 JalviewModelSequence jms = object.getJalviewModelSequence();
2788 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2791 // ////////////////////////////////
2794 List<SequenceI> hiddenSeqs = null;
2797 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2799 boolean multipleView = false;
2800 SequenceI referenceseqForView = null;
2801 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2802 int vi = 0; // counter in vamsasSeq array
2803 for (int i = 0; i < jseqs.length; i++)
2805 String seqId = jseqs[i].getId();
2807 SequenceI tmpSeq = seqRefIds.get(seqId);
2810 if (!incompleteSeqs.containsKey(seqId))
2812 // may not need this check, but keep it for at least 2.9,1 release
2813 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2816 .println("Warning JAL-2154 regression: updating start/end for sequence "
2817 + tmpSeq.toString());
2820 incompleteSeqs.remove(seqId);
2822 tmpSeq.setStart(jseqs[i].getStart());
2823 tmpSeq.setEnd(jseqs[i].getEnd());
2824 tmpseqs.add(tmpSeq);
2825 multipleView = true;
2829 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2830 vamsasSeq[vi].getSequence());
2831 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2832 tmpSeq.setStart(jseqs[i].getStart());
2833 tmpSeq.setEnd(jseqs[i].getEnd());
2834 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2835 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2836 tmpseqs.add(tmpSeq);
2840 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2842 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2845 if (jseqs[i].getHidden())
2847 if (hiddenSeqs == null)
2849 hiddenSeqs = new ArrayList<SequenceI>();
2852 hiddenSeqs.add(tmpSeq);
2857 // Create the alignment object from the sequence set
2858 // ///////////////////////////////
2859 SequenceI[] orderedSeqs = tmpseqs
2860 .toArray(new SequenceI[tmpseqs.size()]);
2862 AlignmentI al = null;
2863 // so we must create or recover the dataset alignment before going further
2864 // ///////////////////////////////
2865 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2867 // older jalview projects do not have a dataset - so creat alignment and
2869 al = new Alignment(orderedSeqs);
2870 al.setDataset(null);
2874 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2877 // we are importing a dataset record, so
2878 // recover reference to an alignment already materialsed as dataset
2879 al = getDatasetFor(vamsasSet.getDatasetId());
2883 // materialse the alignment
2884 al = new Alignment(orderedSeqs);
2888 addDatasetRef(vamsasSet.getDatasetId(), al);
2891 // finally, verify all data in vamsasSet is actually present in al
2892 // passing on flag indicating if it is actually a stored dataset
2893 recoverDatasetFor(vamsasSet, al, isdsal);
2896 if (referenceseqForView != null)
2898 al.setSeqrep(referenceseqForView);
2900 // / Add the alignment properties
2901 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2903 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2904 al.setProperty(ssp.getKey(), ssp.getValue());
2907 // ///////////////////////////////
2909 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2912 // load sequence features, database references and any associated PDB
2913 // structures for the alignment
2914 for (int i = 0; i < vamsasSeq.length; i++)
2916 if (jseqs[i].getFeaturesCount() > 0)
2918 Features[] features = jseqs[i].getFeatures();
2919 for (int f = 0; f < features.length; f++)
2921 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2922 features[f].getType(), features[f].getDescription(),
2923 features[f].getStatus(), features[f].getBegin(),
2924 features[f].getEnd(), features[f].getFeatureGroup());
2926 sf.setScore(features[f].getScore());
2927 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2929 OtherData keyValue = features[f].getOtherData(od);
2930 if (keyValue.getKey().startsWith("LINK"))
2932 sf.addLink(keyValue.getValue());
2936 sf.setValue(keyValue.getKey(), keyValue.getValue());
2941 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2944 if (vamsasSeq[i].getDBRefCount() > 0)
2946 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2948 if (jseqs[i].getPdbidsCount() > 0)
2950 Pdbids[] ids = jseqs[i].getPdbids();
2951 for (int p = 0; p < ids.length; p++)
2953 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2954 entry.setId(ids[p].getId());
2955 if (ids[p].getType() != null)
2957 if (ids[p].getType().equalsIgnoreCase("PDB"))
2959 entry.setType(PDBEntry.Type.PDB);
2963 entry.setType(PDBEntry.Type.FILE);
2966 if (ids[p].getFile() != null)
2968 if (!pdbloaded.containsKey(ids[p].getFile()))
2970 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2974 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2977 StructureSelectionManager.getStructureSelectionManager(
2978 Desktop.instance).registerPDBEntry(entry);
2979 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2983 } // end !multipleview
2985 // ///////////////////////////////
2986 // LOAD SEQUENCE MAPPINGS
2988 if (vamsasSet.getAlcodonFrameCount() > 0)
2990 // TODO Potentially this should only be done once for all views of an
2992 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2993 for (int i = 0; i < alc.length; i++)
2995 AlignedCodonFrame cf = new AlignedCodonFrame();
2996 if (alc[i].getAlcodMapCount() > 0)
2998 AlcodMap[] maps = alc[i].getAlcodMap();
2999 for (int m = 0; m < maps.length; m++)
3001 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3003 jalview.datamodel.Mapping mapping = null;
3004 // attach to dna sequence reference.
3005 if (maps[m].getMapping() != null)
3007 mapping = addMapping(maps[m].getMapping());
3009 if (dnaseq != null && mapping.getTo() != null)
3011 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3016 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3020 al.addCodonFrame(cf);
3025 // ////////////////////////////////
3027 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3030 * store any annotations which forward reference a group's ID
3032 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3034 if (vamsasSet.getAnnotationCount() > 0)
3036 Annotation[] an = vamsasSet.getAnnotation();
3038 for (int i = 0; i < an.length; i++)
3040 Annotation annotation = an[i];
3043 * test if annotation is automatically calculated for this view only
3045 boolean autoForView = false;
3046 if (annotation.getLabel().equals("Quality")
3047 || annotation.getLabel().equals("Conservation")
3048 || annotation.getLabel().equals("Consensus"))
3050 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3052 if (!annotation.hasAutoCalculated())
3054 annotation.setAutoCalculated(true);
3058 || (annotation.hasAutoCalculated() && annotation
3059 .isAutoCalculated()))
3061 // remove ID - we don't recover annotation from other views for
3062 // view-specific annotation
3063 annotation.setId(null);
3066 // set visiblity for other annotation in this view
3067 String annotationId = annotation.getId();
3068 if (annotationId != null && annotationIds.containsKey(annotationId))
3070 AlignmentAnnotation jda = annotationIds.get(annotationId);
3071 // in principle Visible should always be true for annotation displayed
3072 // in multiple views
3073 if (annotation.hasVisible())
3075 jda.visible = annotation.getVisible();
3078 al.addAnnotation(jda);
3082 // Construct new annotation from model.
3083 AnnotationElement[] ae = annotation.getAnnotationElement();
3084 jalview.datamodel.Annotation[] anot = null;
3085 java.awt.Color firstColour = null;
3087 if (!annotation.getScoreOnly())
3089 anot = new jalview.datamodel.Annotation[al.getWidth()];
3090 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3092 anpos = ae[aa].getPosition();
3094 if (anpos >= anot.length)
3099 anot[anpos] = new jalview.datamodel.Annotation(
3101 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3102 (ae[aa].getSecondaryStructure() == null || ae[aa]
3103 .getSecondaryStructure().length() == 0) ? ' '
3104 : ae[aa].getSecondaryStructure().charAt(0),
3108 // JBPNote: Consider verifying dataflow for IO of secondary
3109 // structure annotation read from Stockholm files
3110 // this was added to try to ensure that
3111 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3113 // anot[ae[aa].getPosition()].displayCharacter = "";
3115 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3116 if (firstColour == null)
3118 firstColour = anot[anpos].colour;
3122 jalview.datamodel.AlignmentAnnotation jaa = null;
3124 if (annotation.getGraph())
3126 float llim = 0, hlim = 0;
3127 // if (autoForView || an[i].isAutoCalculated()) {
3130 jaa = new jalview.datamodel.AlignmentAnnotation(
3131 annotation.getLabel(), annotation.getDescription(), anot,
3132 llim, hlim, annotation.getGraphType());
3134 jaa.graphGroup = annotation.getGraphGroup();
3135 jaa._linecolour = firstColour;
3136 if (annotation.getThresholdLine() != null)
3138 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3139 .getThresholdLine().getValue(), annotation
3140 .getThresholdLine().getLabel(), new java.awt.Color(
3141 annotation.getThresholdLine().getColour())));
3144 if (autoForView || annotation.isAutoCalculated())
3146 // Hardwire the symbol display line to ensure that labels for
3147 // histograms are displayed
3153 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3154 an[i].getDescription(), anot);
3155 jaa._linecolour = firstColour;
3157 // register new annotation
3158 if (an[i].getId() != null)
3160 annotationIds.put(an[i].getId(), jaa);
3161 jaa.annotationId = an[i].getId();
3163 // recover sequence association
3164 String sequenceRef = an[i].getSequenceRef();
3165 if (sequenceRef != null)
3167 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3168 SequenceI sequence = seqRefIds.get(sequenceRef);
3169 if (sequence == null)
3171 // in pre-2.9 projects sequence ref is to sequence name
3172 sequence = al.findName(sequenceRef);
3174 if (sequence != null)
3176 jaa.createSequenceMapping(sequence, 1, true);
3177 sequence.addAlignmentAnnotation(jaa);
3180 // and make a note of any group association
3181 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3183 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3184 .get(an[i].getGroupRef());
3187 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3188 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3193 if (an[i].hasScore())
3195 jaa.setScore(an[i].getScore());
3197 if (an[i].hasVisible())
3199 jaa.visible = an[i].getVisible();
3202 if (an[i].hasCentreColLabels())
3204 jaa.centreColLabels = an[i].getCentreColLabels();
3207 if (an[i].hasScaleColLabels())
3209 jaa.scaleColLabel = an[i].getScaleColLabels();
3211 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3213 // newer files have an 'autoCalculated' flag and store calculation
3214 // state in viewport properties
3215 jaa.autoCalculated = true; // means annotation will be marked for
3216 // update at end of load.
3218 if (an[i].hasGraphHeight())
3220 jaa.graphHeight = an[i].getGraphHeight();
3222 if (an[i].hasBelowAlignment())
3224 jaa.belowAlignment = an[i].isBelowAlignment();
3226 jaa.setCalcId(an[i].getCalcId());
3227 if (an[i].getPropertyCount() > 0)
3229 for (jalview.schemabinding.version2.Property prop : an[i]
3232 jaa.setProperty(prop.getName(), prop.getValue());
3235 if (jaa.autoCalculated)
3237 autoAlan.add(new JvAnnotRow(i, jaa));
3240 // if (!autoForView)
3242 // add autocalculated group annotation and any user created annotation
3244 al.addAnnotation(jaa);
3248 // ///////////////////////
3250 // Create alignment markup and styles for this view
3251 if (jms.getJGroupCount() > 0)
3253 JGroup[] groups = jms.getJGroup();
3254 boolean addAnnotSchemeGroup = false;
3255 for (int i = 0; i < groups.length; i++)
3257 JGroup jGroup = groups[i];
3258 ColourSchemeI cs = null;
3259 if (jGroup.getColour() != null)
3261 if (jGroup.getColour().startsWith("ucs"))
3263 cs = getUserColourScheme(jms, jGroup.getColour());
3265 else if (jGroup.getColour().equals("AnnotationColourGradient")
3266 && jGroup.getAnnotationColours() != null)
3268 addAnnotSchemeGroup = true;
3273 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3278 cs.setThreshold(jGroup.getPidThreshold(), true);
3282 Vector<SequenceI> seqs = new Vector<SequenceI>();
3284 for (int s = 0; s < jGroup.getSeqCount(); s++)
3286 String seqId = jGroup.getSeq(s) + "";
3287 SequenceI ts = seqRefIds.get(seqId);
3291 seqs.addElement(ts);
3295 if (seqs.size() < 1)
3300 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3301 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3302 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3304 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3306 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3307 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3308 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3309 .isShowUnconserved() : false);
3310 sg.thresholdTextColour = jGroup.getTextColThreshold();
3311 if (jGroup.hasShowConsensusHistogram())
3313 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3316 if (jGroup.hasShowSequenceLogo())
3318 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3320 if (jGroup.hasNormaliseSequenceLogo())
3322 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3324 if (jGroup.hasIgnoreGapsinConsensus())
3326 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3328 if (jGroup.getConsThreshold() != 0)
3330 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3331 "All", ResidueProperties.propHash, 3,
3332 sg.getSequences(null), 0, sg.getWidth() - 1);
3334 c.verdict(false, 25);
3335 sg.cs.setConservation(c);
3338 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3340 // re-instate unique group/annotation row reference
3341 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3345 for (AlignmentAnnotation jaa : jaal)
3348 if (jaa.autoCalculated)
3350 // match up and try to set group autocalc alignment row for this
3352 if (jaa.label.startsWith("Consensus for "))
3354 sg.setConsensus(jaa);
3356 // match up and try to set group autocalc alignment row for this
3358 if (jaa.label.startsWith("Conservation for "))
3360 sg.setConservationRow(jaa);
3367 if (addAnnotSchemeGroup)
3369 // reconstruct the annotation colourscheme
3370 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3371 null, al, jms, false);
3377 // only dataset in this model, so just return.
3380 // ///////////////////////////////
3383 // If we just load in the same jar file again, the sequenceSetId
3384 // will be the same, and we end up with multiple references
3385 // to the same sequenceSet. We must modify this id on load
3386 // so that each load of the file gives a unique id
3387 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3388 String viewId = (view.getId() == null ? null : view.getId()
3390 AlignFrame af = null;
3391 AlignViewport av = null;
3392 // now check to see if we really need to create a new viewport.
3393 if (multipleView && viewportsAdded.size() == 0)
3395 // We recovered an alignment for which a viewport already exists.
3396 // TODO: fix up any settings necessary for overlaying stored state onto
3397 // state recovered from another document. (may not be necessary).
3398 // we may need a binding from a viewport in memory to one recovered from
3400 // and then recover its containing af to allow the settings to be applied.
3401 // TODO: fix for vamsas demo
3403 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3405 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3406 if (seqsetobj != null)
3408 if (seqsetobj instanceof String)
3410 uniqueSeqSetId = (String) seqsetobj;
3412 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3418 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3424 * indicate that annotation colours are applied across all groups (pre
3425 * Jalview 2.8.1 behaviour)
3427 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3428 "2.8.1", object.getVersion());
3430 AlignmentPanel ap = null;
3431 boolean isnewview = true;
3434 // Check to see if this alignment already has a view id == viewId
3435 jalview.gui.AlignmentPanel views[] = Desktop
3436 .getAlignmentPanels(uniqueSeqSetId);
3437 if (views != null && views.length > 0)
3439 for (int v = 0; v < views.length; v++)
3441 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3443 // recover the existing alignpanel, alignframe, viewport
3444 af = views[v].alignFrame;
3447 // TODO: could even skip resetting view settings if we don't want to
3448 // change the local settings from other jalview processes
3457 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3458 uniqueSeqSetId, viewId, autoAlan);
3464 * Load any trees, PDB structures and viewers
3466 * Not done if flag is false (when this method is used for New View)
3468 if (loadTreesAndStructures)
3470 loadTrees(jms, view, af, av, ap);
3471 loadPDBStructures(jprovider, jseqs, af, ap);
3472 loadRnaViewers(jprovider, jseqs, ap);
3474 // and finally return.
3479 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3480 * panel is restored from separate jar entries, two (gapped and trimmed) per
3481 * sequence and secondary structure.
3483 * Currently each viewer shows just one sequence and structure (gapped and
3484 * trimmed), however this method is designed to support multiple sequences or
3485 * structures in viewers if wanted in future.
3491 private void loadRnaViewers(jarInputStreamProvider jprovider,
3492 JSeq[] jseqs, AlignmentPanel ap)
3495 * scan the sequences for references to viewers; create each one the first
3496 * time it is referenced, add Rna models to existing viewers
3498 for (JSeq jseq : jseqs)
3500 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3502 RnaViewer viewer = jseq.getRnaViewer(i);
3503 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3504 uniqueSetSuffix, ap);
3506 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3508 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3509 SequenceI seq = seqRefIds.get(jseq.getId());
3510 AlignmentAnnotation ann = this.annotationIds.get(ss
3511 .getAnnotationId());
3514 * add the structure to the Varna display (with session state copied
3515 * from the jar to a temporary file)
3517 boolean gapped = ss.isGapped();
3518 String rnaTitle = ss.getTitle();
3519 String sessionState = ss.getViewerState();
3520 String tempStateFile = copyJarEntry(jprovider, sessionState,
3522 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3523 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3525 appVarna.setInitialSelection(viewer.getSelectedRna());
3531 * Locate and return an already instantiated matching AppVarna, or create one
3535 * @param viewIdSuffix
3539 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3540 String viewIdSuffix, AlignmentPanel ap)
3543 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3544 * if load is repeated
3546 String postLoadId = viewer.getViewId() + viewIdSuffix;
3547 for (JInternalFrame frame : getAllFrames())
3549 if (frame instanceof AppVarna)
3551 AppVarna varna = (AppVarna) frame;
3552 if (postLoadId.equals(varna.getViewId()))
3554 // this viewer is already instantiated
3555 // could in future here add ap as another 'parent' of the
3556 // AppVarna window; currently just 1-to-many
3563 * viewer not found - make it
3565 RnaViewerModel model = new RnaViewerModel(postLoadId,
3566 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3567 viewer.getWidth(), viewer.getHeight(),
3568 viewer.getDividerLocation());
3569 AppVarna varna = new AppVarna(model, ap);
3575 * Load any saved trees
3583 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3584 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3586 // TODO result of automated refactoring - are all these parameters needed?
3589 for (int t = 0; t < jms.getTreeCount(); t++)
3592 Tree tree = jms.getTree(t);
3594 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3597 tp = af.ShowNewickTree(
3598 new jalview.io.NewickFile(tree.getNewick()),
3599 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3600 tree.getXpos(), tree.getYpos());
3601 if (tree.getId() != null)
3603 // perhaps bind the tree id to something ?
3608 // update local tree attributes ?
3609 // TODO: should check if tp has been manipulated by user - if so its
3610 // settings shouldn't be modified
3611 tp.setTitle(tree.getTitle());
3612 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3613 .getWidth(), tree.getHeight()));
3614 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3617 tp.treeCanvas.av = av; // af.viewport;
3618 tp.treeCanvas.ap = ap; // af.alignPanel;
3623 warn("There was a problem recovering stored Newick tree: \n"
3624 + tree.getNewick());
3628 tp.fitToWindow.setState(tree.getFitToWindow());
3629 tp.fitToWindow_actionPerformed(null);
3631 if (tree.getFontName() != null)
3633 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3634 .getFontStyle(), tree.getFontSize()));
3638 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3639 .getFontStyle(), tree.getFontSize()));
3642 tp.showPlaceholders(tree.getMarkUnlinked());
3643 tp.showBootstrap(tree.getShowBootstrap());
3644 tp.showDistances(tree.getShowDistances());
3646 tp.treeCanvas.threshold = tree.getThreshold();
3648 if (tree.getCurrentTree())
3650 af.viewport.setCurrentTree(tp.getTree());
3654 } catch (Exception ex)
3656 ex.printStackTrace();
3661 * Load and link any saved structure viewers.
3668 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3669 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3672 * Run through all PDB ids on the alignment, and collect mappings between
3673 * distinct view ids and all sequences referring to that view.
3675 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3677 for (int i = 0; i < jseqs.length; i++)
3679 if (jseqs[i].getPdbidsCount() > 0)
3681 Pdbids[] ids = jseqs[i].getPdbids();
3682 for (int p = 0; p < ids.length; p++)
3684 final int structureStateCount = ids[p].getStructureStateCount();
3685 for (int s = 0; s < structureStateCount; s++)
3687 // check to see if we haven't already created this structure view
3688 final StructureState structureState = ids[p]
3689 .getStructureState(s);
3690 String sviewid = (structureState.getViewId() == null) ? null
3691 : structureState.getViewId() + uniqueSetSuffix;
3692 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3693 // Originally : ids[p].getFile()
3694 // : TODO: verify external PDB file recovery still works in normal
3695 // jalview project load
3696 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3697 jpdb.setId(ids[p].getId());
3699 int x = structureState.getXpos();
3700 int y = structureState.getYpos();
3701 int width = structureState.getWidth();
3702 int height = structureState.getHeight();
3704 // Probably don't need to do this anymore...
3705 // Desktop.desktop.getComponentAt(x, y);
3706 // TODO: NOW: check that this recovers the PDB file correctly.
3707 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3708 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3710 if (sviewid == null)
3712 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3715 if (!structureViewers.containsKey(sviewid))
3717 structureViewers.put(sviewid,
3718 new StructureViewerModel(x, y, width, height, false,
3719 false, true, structureState.getViewId(),
3720 structureState.getType()));
3721 // Legacy pre-2.7 conversion JAL-823 :
3722 // do not assume any view has to be linked for colour by
3726 // assemble String[] { pdb files }, String[] { id for each
3727 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3728 // seqs_file 2}, boolean[] {
3729 // linkAlignPanel,superposeWithAlignpanel}} from hash
3730 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3731 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3732 | (structureState.hasAlignwithAlignPanel() ? structureState
3733 .getAlignwithAlignPanel() : false));
3736 * Default colour by linked panel to false if not specified (e.g.
3737 * for pre-2.7 projects)
3739 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3740 colourWithAlignPanel |= (structureState
3741 .hasColourwithAlignPanel() ? structureState
3742 .getColourwithAlignPanel() : false);
3743 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3746 * Default colour by viewer to true if not specified (e.g. for
3749 boolean colourByViewer = jmoldat.isColourByViewer();
3750 colourByViewer &= structureState.hasColourByJmol() ? structureState
3751 .getColourByJmol() : true;
3752 jmoldat.setColourByViewer(colourByViewer);
3754 if (jmoldat.getStateData().length() < structureState
3755 .getContent().length())
3758 jmoldat.setStateData(structureState.getContent());
3761 if (ids[p].getFile() != null)
3763 File mapkey = new File(ids[p].getFile());
3764 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3765 if (seqstrmaps == null)
3767 jmoldat.getFileData().put(
3769 seqstrmaps = jmoldat.new StructureData(pdbFile,
3772 if (!seqstrmaps.getSeqList().contains(seq))
3774 seqstrmaps.getSeqList().add(seq);
3780 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");
3787 // Instantiate the associated structure views
3788 for (Entry<String, StructureViewerModel> entry : structureViewers
3793 createOrLinkStructureViewer(entry, af, ap, jprovider);
3794 } catch (Exception e)
3796 System.err.println("Error loading structure viewer: "
3798 // failed - try the next one
3810 protected void createOrLinkStructureViewer(
3811 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3812 AlignmentPanel ap, jarInputStreamProvider jprovider)
3814 final StructureViewerModel stateData = viewerData.getValue();
3817 * Search for any viewer windows already open from other alignment views
3818 * that exactly match the stored structure state
3820 StructureViewerBase comp = findMatchingViewer(viewerData);
3824 linkStructureViewer(ap, comp, stateData);
3829 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3830 * "viewer_"+stateData.viewId
3832 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3834 createChimeraViewer(viewerData, af, jprovider);
3839 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3841 createJmolViewer(viewerData, af, jprovider);
3846 * Create a new Chimera viewer.
3852 protected void createChimeraViewer(
3853 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3854 jarInputStreamProvider jprovider)
3856 StructureViewerModel data = viewerData.getValue();
3857 String chimeraSessionFile = data.getStateData();
3860 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3862 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3863 * 'uniquified' sviewid used to reconstruct the viewer here
3865 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3866 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3869 Set<Entry<File, StructureData>> fileData = data.getFileData()
3871 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3872 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3873 for (Entry<File, StructureData> pdb : fileData)
3875 String filePath = pdb.getValue().getFilePath();
3876 String pdbId = pdb.getValue().getPdbId();
3877 // pdbs.add(new PDBEntry(filePath, pdbId));
3878 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3879 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3880 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3884 boolean colourByChimera = data.isColourByViewer();
3885 boolean colourBySequence = data.isColourWithAlignPanel();
3887 // TODO use StructureViewer as a factory here, see JAL-1761
3888 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3889 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3891 String newViewId = viewerData.getKey();
3893 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3894 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3895 colourBySequence, newViewId);
3896 cvf.setSize(data.getWidth(), data.getHeight());
3897 cvf.setLocation(data.getX(), data.getY());
3901 * Create a new Jmol window. First parse the Jmol state to translate filenames
3902 * loaded into the view, and record the order in which files are shown in the
3903 * Jmol view, so we can add the sequence mappings in same order.
3909 protected void createJmolViewer(
3910 final Entry<String, StructureViewerModel> viewerData,
3911 AlignFrame af, jarInputStreamProvider jprovider)
3913 final StructureViewerModel svattrib = viewerData.getValue();
3914 String state = svattrib.getStateData();
3917 * Pre-2.9: state element value is the Jmol state string
3919 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3922 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3924 state = readJarEntry(jprovider,
3925 getViewerJarEntryName(svattrib.getViewId()));
3928 List<String> pdbfilenames = new ArrayList<String>();
3929 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3930 List<String> pdbids = new ArrayList<String>();
3931 StringBuilder newFileLoc = new StringBuilder(64);
3932 int cp = 0, ncp, ecp;
3933 Map<File, StructureData> oldFiles = svattrib.getFileData();
3934 while ((ncp = state.indexOf("load ", cp)) > -1)
3938 // look for next filename in load statement
3939 newFileLoc.append(state.substring(cp,
3940 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3941 String oldfilenam = state.substring(ncp,
3942 ecp = state.indexOf("\"", ncp));
3943 // recover the new mapping data for this old filename
3944 // have to normalize filename - since Jmol and jalview do
3946 // translation differently.
3947 StructureData filedat = oldFiles.get(new File(oldfilenam));
3948 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3949 pdbfilenames.add(filedat.getFilePath());
3950 pdbids.add(filedat.getPdbId());
3951 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3952 newFileLoc.append("\"");
3953 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3954 // look for next file statement.
3955 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3959 // just append rest of state
3960 newFileLoc.append(state.substring(cp));
3964 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3965 newFileLoc = new StringBuilder(state);
3966 newFileLoc.append("; load append ");
3967 for (File id : oldFiles.keySet())
3969 // add this and any other pdb files that should be present in
3971 StructureData filedat = oldFiles.get(id);
3972 newFileLoc.append(filedat.getFilePath());
3973 pdbfilenames.add(filedat.getFilePath());
3974 pdbids.add(filedat.getPdbId());
3975 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3976 newFileLoc.append(" \"");
3977 newFileLoc.append(filedat.getFilePath());
3978 newFileLoc.append("\"");
3981 newFileLoc.append(";");
3984 if (newFileLoc.length() == 0)
3988 int histbug = newFileLoc.indexOf("history = ");
3992 * change "history = [true|false];" to "history = [1|0];"
3995 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3996 String val = (diff == -1) ? null : newFileLoc
3997 .substring(histbug, diff);
3998 if (val != null && val.length() >= 4)
4000 if (val.contains("e")) // eh? what can it be?
4002 if (val.trim().equals("true"))
4010 newFileLoc.replace(histbug, diff, val);
4015 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4017 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4018 final SequenceI[][] sq = seqmaps
4019 .toArray(new SequenceI[seqmaps.size()][]);
4020 final String fileloc = newFileLoc.toString();
4021 final String sviewid = viewerData.getKey();
4022 final AlignFrame alf = af;
4023 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4024 svattrib.getWidth(), svattrib.getHeight());
4027 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4032 JalviewStructureDisplayI sview = null;
4035 sview = new StructureViewer(alf.alignPanel
4036 .getStructureSelectionManager()).createView(
4037 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4038 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4039 addNewStructureViewer(sview);
4040 } catch (OutOfMemoryError ex)
4042 new OOMWarning("restoring structure view for PDB id " + id,
4043 (OutOfMemoryError) ex.getCause());
4044 if (sview != null && sview.isVisible())
4046 sview.closeViewer(false);
4047 sview.setVisible(false);
4053 } catch (InvocationTargetException ex)
4055 warn("Unexpected error when opening Jmol view.", ex);
4057 } catch (InterruptedException e)
4059 // e.printStackTrace();
4065 * Generates a name for the entry in the project jar file to hold state
4066 * information for a structure viewer
4071 protected String getViewerJarEntryName(String viewId)
4073 return VIEWER_PREFIX + viewId;
4077 * Returns any open frame that matches given structure viewer data. The match
4078 * is based on the unique viewId, or (for older project versions) the frame's
4084 protected StructureViewerBase findMatchingViewer(
4085 Entry<String, StructureViewerModel> viewerData)
4087 final String sviewid = viewerData.getKey();
4088 final StructureViewerModel svattrib = viewerData.getValue();
4089 StructureViewerBase comp = null;
4090 JInternalFrame[] frames = getAllFrames();
4091 for (JInternalFrame frame : frames)
4093 if (frame instanceof StructureViewerBase)
4096 * Post jalview 2.4 schema includes structure view id
4099 && ((StructureViewerBase) frame).getViewId()
4102 comp = (StructureViewerBase) frame;
4103 break; // break added in 2.9
4106 * Otherwise test for matching position and size of viewer frame
4108 else if (frame.getX() == svattrib.getX()
4109 && frame.getY() == svattrib.getY()
4110 && frame.getHeight() == svattrib.getHeight()
4111 && frame.getWidth() == svattrib.getWidth())
4113 comp = (StructureViewerBase) frame;
4114 // no break in faint hope of an exact match on viewId
4122 * Link an AlignmentPanel to an existing structure viewer.
4127 * @param useinViewerSuperpos
4128 * @param usetoColourbyseq
4129 * @param viewerColouring
4131 protected void linkStructureViewer(AlignmentPanel ap,
4132 StructureViewerBase viewer, StructureViewerModel stateData)
4134 // NOTE: if the jalview project is part of a shared session then
4135 // view synchronization should/could be done here.
4137 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4138 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4139 final boolean viewerColouring = stateData.isColourByViewer();
4140 Map<File, StructureData> oldFiles = stateData.getFileData();
4143 * Add mapping for sequences in this view to an already open viewer
4145 final AAStructureBindingModel binding = viewer.getBinding();
4146 for (File id : oldFiles.keySet())
4148 // add this and any other pdb files that should be present in the
4150 StructureData filedat = oldFiles.get(id);
4151 String pdbFile = filedat.getFilePath();
4152 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4153 binding.getSsm().setMapping(seq, null, pdbFile,
4154 jalview.io.AppletFormatAdapter.FILE);
4155 binding.addSequenceForStructFile(pdbFile, seq);
4157 // and add the AlignmentPanel's reference to the view panel
4158 viewer.addAlignmentPanel(ap);
4159 if (useinViewerSuperpos)
4161 viewer.useAlignmentPanelForSuperposition(ap);
4165 viewer.excludeAlignmentPanelForSuperposition(ap);
4167 if (usetoColourbyseq)
4169 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4173 viewer.excludeAlignmentPanelForColourbyseq(ap);
4178 * Get all frames within the Desktop.
4182 protected JInternalFrame[] getAllFrames()
4184 JInternalFrame[] frames = null;
4185 // TODO is this necessary - is it safe - risk of hanging?
4190 frames = Desktop.desktop.getAllFrames();
4191 } catch (ArrayIndexOutOfBoundsException e)
4193 // occasional No such child exceptions are thrown here...
4197 } catch (InterruptedException f)
4201 } while (frames == null);
4206 * Answers true if 'version' is equal to or later than 'supported', where each
4207 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4208 * changes. Development and test values for 'version' are leniently treated
4212 * - minimum version we are comparing against
4214 * - version of data being processsed
4217 public static boolean isVersionStringLaterThan(String supported,
4220 if (supported == null || version == null
4221 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4222 || version.equalsIgnoreCase("Test")
4223 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4225 System.err.println("Assuming project file with "
4226 + (version == null ? "null" : version)
4227 + " is compatible with Jalview version " + supported);
4232 return StringUtils.compareVersions(version, supported, "b") >= 0;
4236 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4238 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4240 if (newStructureViewers != null)
4242 sview.getBinding().setFinishedLoadingFromArchive(false);
4243 newStructureViewers.add(sview);
4247 protected void setLoadingFinishedForNewStructureViewers()
4249 if (newStructureViewers != null)
4251 for (JalviewStructureDisplayI sview : newStructureViewers)
4253 sview.getBinding().setFinishedLoadingFromArchive(true);
4255 newStructureViewers.clear();
4256 newStructureViewers = null;
4260 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4261 List<SequenceI> hiddenSeqs, AlignmentI al,
4262 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4263 String viewId, List<JvAnnotRow> autoAlan)
4265 AlignFrame af = null;
4266 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4267 uniqueSeqSetId, viewId);
4269 af.setFileName(file, "Jalview");
4271 for (int i = 0; i < JSEQ.length; i++)
4273 af.viewport.setSequenceColour(af.viewport.getAlignment()
4274 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4279 af.getViewport().setColourByReferenceSeq(true);
4280 af.getViewport().setDisplayReferenceSeq(true);
4283 af.viewport.setGatherViewsHere(view.getGatheredViews());
4285 if (view.getSequenceSetId() != null)
4287 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4289 af.viewport.setSequenceSetId(uniqueSeqSetId);
4292 // propagate shared settings to this new view
4293 af.viewport.setHistoryList(av.getHistoryList());
4294 af.viewport.setRedoList(av.getRedoList());
4298 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4300 // TODO: check if this method can be called repeatedly without
4301 // side-effects if alignpanel already registered.
4302 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4304 // apply Hidden regions to view.
4305 if (hiddenSeqs != null)
4307 for (int s = 0; s < JSEQ.length; s++)
4309 SequenceGroup hidden = new SequenceGroup();
4310 boolean isRepresentative = false;
4311 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4313 isRepresentative = true;
4314 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4315 .getHiddenSequences(r));
4316 hidden.addSequence(sequenceToHide, false);
4317 // remove from hiddenSeqs list so we don't try to hide it twice
4318 hiddenSeqs.remove(sequenceToHide);
4320 if (isRepresentative)
4322 SequenceI representativeSequence = al.getSequenceAt(s);
4323 hidden.addSequence(representativeSequence, false);
4324 af.viewport.hideRepSequences(representativeSequence, hidden);
4328 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4330 af.viewport.hideSequence(hseqs);
4333 // recover view properties and display parameters
4334 if (view.getViewName() != null)
4336 af.viewport.viewName = view.getViewName();
4337 af.setInitialTabVisible();
4339 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4342 af.viewport.setShowAnnotation(view.getShowAnnotation());
4343 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4345 af.viewport.setColourText(view.getShowColourText());
4347 af.viewport.setConservationSelected(view.getConservationSelected());
4348 af.viewport.setShowJVSuffix(view.getShowFullId());
4349 af.viewport.setRightAlignIds(view.getRightAlignIds());
4350 af.viewport.setFont(
4351 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4352 .getFontSize()), true);
4353 ViewStyleI vs = af.viewport.getViewStyle();
4354 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4355 af.viewport.setViewStyle(vs);
4356 // TODO: allow custom charWidth/Heights to be restored by updating them
4357 // after setting font - which means set above to false
4358 af.viewport.setRenderGaps(view.getRenderGaps());
4359 af.viewport.setWrapAlignment(view.getWrapAlignment());
4360 af.viewport.setShowAnnotation(view.getShowAnnotation());
4362 af.viewport.setShowBoxes(view.getShowBoxes());
4364 af.viewport.setShowText(view.getShowText());
4366 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4367 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4368 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4369 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4370 .isShowUnconserved() : false);
4371 af.viewport.setStartRes(view.getStartRes());
4372 af.viewport.setStartSeq(view.getStartSeq());
4373 af.alignPanel.updateLayout();
4374 ColourSchemeI cs = null;
4375 // apply colourschemes
4376 if (view.getBgColour() != null)
4378 if (view.getBgColour().startsWith("ucs"))
4380 cs = getUserColourScheme(jms, view.getBgColour());
4382 else if (view.getBgColour().startsWith("Annotation"))
4384 AnnotationColours viewAnnColour = view.getAnnotationColours();
4385 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4392 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4397 cs.setThreshold(view.getPidThreshold(), true);
4398 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4402 af.viewport.setGlobalColourScheme(cs);
4403 af.viewport.setColourAppliesToAllGroups(false);
4405 if (view.getConservationSelected() && cs != null)
4407 cs.setConservationInc(view.getConsThreshold());
4410 af.changeColour(cs);
4412 af.viewport.setColourAppliesToAllGroups(true);
4414 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4416 if (view.hasCentreColumnLabels())
4418 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4420 if (view.hasIgnoreGapsinConsensus())
4422 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4425 if (view.hasFollowHighlight())
4427 af.viewport.setFollowHighlight(view.getFollowHighlight());
4429 if (view.hasFollowSelection())
4431 af.viewport.followSelection = view.getFollowSelection();
4433 if (view.hasShowConsensusHistogram())
4435 af.viewport.setShowConsensusHistogram(view
4436 .getShowConsensusHistogram());
4440 af.viewport.setShowConsensusHistogram(true);
4442 if (view.hasShowSequenceLogo())
4444 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4448 af.viewport.setShowSequenceLogo(false);
4450 if (view.hasNormaliseSequenceLogo())
4452 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4454 if (view.hasShowDbRefTooltip())
4456 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4458 if (view.hasShowNPfeatureTooltip())
4460 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4462 if (view.hasShowGroupConsensus())
4464 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4468 af.viewport.setShowGroupConsensus(false);
4470 if (view.hasShowGroupConservation())
4472 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4476 af.viewport.setShowGroupConservation(false);
4479 // recover featre settings
4480 if (jms.getFeatureSettings() != null)
4482 FeaturesDisplayed fdi;
4483 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4484 String[] renderOrder = new String[jms.getFeatureSettings()
4485 .getSettingCount()];
4486 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4487 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4489 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4491 Setting setting = jms.getFeatureSettings().getSetting(fs);
4492 if (setting.hasMincolour())
4494 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4495 new Color(setting.getMincolour()), new Color(
4496 setting.getColour()), setting.getMin(),
4497 setting.getMax()) : new FeatureColour(new Color(
4498 setting.getMincolour()), new Color(setting.getColour()),
4500 if (setting.hasThreshold())
4502 gc.setThreshold(setting.getThreshold());
4503 int threshstate = setting.getThreshstate();
4504 // -1 = None, 0 = Below, 1 = Above threshold
4505 if (threshstate == 0)
4507 gc.setBelowThreshold(true);
4509 else if (threshstate == 1)
4511 gc.setAboveThreshold(true);
4514 gc.setAutoScaled(true); // default
4515 if (setting.hasAutoScale())
4517 gc.setAutoScaled(setting.getAutoScale());
4519 if (setting.hasColourByLabel())
4521 gc.setColourByLabel(setting.getColourByLabel());
4523 // and put in the feature colour table.
4524 featureColours.put(setting.getType(), gc);
4528 featureColours.put(setting.getType(), new FeatureColour(
4529 new Color(setting.getColour())));
4531 renderOrder[fs] = setting.getType();
4532 if (setting.hasOrder())
4534 featureOrder.put(setting.getType(), setting.getOrder());
4538 featureOrder.put(setting.getType(), new Float(fs
4539 / jms.getFeatureSettings().getSettingCount()));
4541 if (setting.getDisplay())
4543 fdi.setVisible(setting.getType());
4546 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4547 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4549 Group grp = jms.getFeatureSettings().getGroup(gs);
4550 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4552 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4553 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4554 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4555 FeatureRendererSettings frs = new FeatureRendererSettings(
4556 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4557 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4558 .transferSettings(frs);
4562 if (view.getHiddenColumnsCount() > 0)
4564 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4566 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4567 .getHiddenColumns(c).getEnd() // +1
4571 if (view.getCalcIdParam() != null)
4573 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4575 if (calcIdParam != null)
4577 if (recoverCalcIdParam(calcIdParam, af.viewport))
4582 warn("Couldn't recover parameters for "
4583 + calcIdParam.getCalcId());
4588 af.setMenusFromViewport(af.viewport);
4589 af.setTitle(view.getTitle());
4590 // TODO: we don't need to do this if the viewport is aready visible.
4592 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4593 * has a 'cdna/protein complement' view, in which case save it in order to
4594 * populate a SplitFrame once all views have been read in.
4596 String complementaryViewId = view.getComplementId();
4597 if (complementaryViewId == null)
4599 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4601 // recompute any autoannotation
4602 af.alignPanel.updateAnnotation(false, true);
4603 reorderAutoannotation(af, al, autoAlan);
4604 af.alignPanel.alignmentChanged();
4608 splitFrameCandidates.put(view, af);
4613 private ColourSchemeI constructAnnotationColour(
4614 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4615 JalviewModelSequence jms, boolean checkGroupAnnColour)
4617 boolean propagateAnnColour = false;
4618 ColourSchemeI cs = null;
4619 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4620 if (checkGroupAnnColour && al.getGroups() != null
4621 && al.getGroups().size() > 0)
4623 // pre 2.8.1 behaviour
4624 // check to see if we should transfer annotation colours
4625 propagateAnnColour = true;
4626 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4628 if (sg.cs instanceof AnnotationColourGradient)
4630 propagateAnnColour = false;
4634 // int find annotation
4635 if (annAlignment.getAlignmentAnnotation() != null)
4637 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4639 if (annAlignment.getAlignmentAnnotation()[i].label
4640 .equals(viewAnnColour.getAnnotation()))
4642 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4644 annAlignment.getAlignmentAnnotation()[i]
4645 .setThreshold(new jalview.datamodel.GraphLine(
4646 viewAnnColour.getThreshold(), "Threshold",
4647 java.awt.Color.black)
4652 if (viewAnnColour.getColourScheme().equals("None"))
4654 cs = new AnnotationColourGradient(
4655 annAlignment.getAlignmentAnnotation()[i],
4656 new java.awt.Color(viewAnnColour.getMinColour()),
4657 new java.awt.Color(viewAnnColour.getMaxColour()),
4658 viewAnnColour.getAboveThreshold());
4660 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4662 cs = new AnnotationColourGradient(
4663 annAlignment.getAlignmentAnnotation()[i],
4664 getUserColourScheme(jms,
4665 viewAnnColour.getColourScheme()),
4666 viewAnnColour.getAboveThreshold());
4670 cs = new AnnotationColourGradient(
4671 annAlignment.getAlignmentAnnotation()[i],
4672 ColourSchemeProperty.getColour(al,
4673 viewAnnColour.getColourScheme()),
4674 viewAnnColour.getAboveThreshold());
4676 if (viewAnnColour.hasPerSequence())
4678 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4681 if (viewAnnColour.hasPredefinedColours())
4683 ((AnnotationColourGradient) cs)
4684 .setPredefinedColours(viewAnnColour
4685 .isPredefinedColours());
4687 if (propagateAnnColour && al.getGroups() != null)
4689 // Also use these settings for all the groups
4690 for (int g = 0; g < al.getGroups().size(); g++)
4692 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4700 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4701 * new AnnotationColourGradient(
4702 * annAlignment.getAlignmentAnnotation()[i], new
4703 * java.awt.Color(viewAnnColour. getMinColour()), new
4704 * java.awt.Color(viewAnnColour. getMaxColour()),
4705 * viewAnnColour.getAboveThreshold()); } else
4708 sg.cs = new AnnotationColourGradient(
4709 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4710 viewAnnColour.getAboveThreshold());
4711 if (cs instanceof AnnotationColourGradient)
4713 if (viewAnnColour.hasPerSequence())
4715 ((AnnotationColourGradient) cs)
4716 .setSeqAssociated(viewAnnColour.isPerSequence());
4718 if (viewAnnColour.hasPredefinedColours())
4720 ((AnnotationColourGradient) cs)
4721 .setPredefinedColours(viewAnnColour
4722 .isPredefinedColours());
4738 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4739 List<JvAnnotRow> autoAlan)
4741 // copy over visualization settings for autocalculated annotation in the
4743 if (al.getAlignmentAnnotation() != null)
4746 * Kludge for magic autoannotation names (see JAL-811)
4748 String[] magicNames = new String[] { "Consensus", "Quality",
4750 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4751 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4752 for (String nm : magicNames)
4754 visan.put(nm, nullAnnot);
4756 for (JvAnnotRow auan : autoAlan)
4758 visan.put(auan.template.label
4759 + (auan.template.getCalcId() == null ? "" : "\t"
4760 + auan.template.getCalcId()), auan);
4762 int hSize = al.getAlignmentAnnotation().length;
4763 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4764 // work through any autoCalculated annotation already on the view
4765 // removing it if it should be placed in a different location on the
4766 // annotation panel.
4767 List<String> remains = new ArrayList<String>(visan.keySet());
4768 for (int h = 0; h < hSize; h++)
4770 jalview.datamodel.AlignmentAnnotation jalan = al
4771 .getAlignmentAnnotation()[h];
4772 if (jalan.autoCalculated)
4775 JvAnnotRow valan = visan.get(k = jalan.label);
4776 if (jalan.getCalcId() != null)
4778 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4783 // delete the auto calculated row from the alignment
4784 al.deleteAnnotation(jalan, false);
4788 if (valan != nullAnnot)
4790 if (jalan != valan.template)
4792 // newly created autoannotation row instance
4793 // so keep a reference to the visible annotation row
4794 // and copy over all relevant attributes
4795 if (valan.template.graphHeight >= 0)
4798 jalan.graphHeight = valan.template.graphHeight;
4800 jalan.visible = valan.template.visible;
4802 reorder.add(new JvAnnotRow(valan.order, jalan));
4807 // Add any (possibly stale) autocalculated rows that were not appended to
4808 // the view during construction
4809 for (String other : remains)
4811 JvAnnotRow othera = visan.get(other);
4812 if (othera != nullAnnot && othera.template.getCalcId() != null
4813 && othera.template.getCalcId().length() > 0)
4815 reorder.add(othera);
4818 // now put the automatic annotation in its correct place
4819 int s = 0, srt[] = new int[reorder.size()];
4820 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4821 for (JvAnnotRow jvar : reorder)
4824 srt[s++] = jvar.order;
4827 jalview.util.QuickSort.sort(srt, rws);
4828 // and re-insert the annotation at its correct position
4829 for (JvAnnotRow jvar : rws)
4831 al.addAnnotation(jvar.template, jvar.order);
4833 af.alignPanel.adjustAnnotationHeight();
4837 Hashtable skipList = null;
4840 * TODO remove this method
4843 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4844 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4845 * throw new Error("Implementation Error. No skipList defined for this
4846 * Jalview2XML instance."); } return (AlignFrame)
4847 * skipList.get(view.getSequenceSetId()); }
4851 * Check if the Jalview view contained in object should be skipped or not.
4854 * @return true if view's sequenceSetId is a key in skipList
4856 private boolean skipViewport(JalviewModel object)
4858 if (skipList == null)
4863 if (skipList.containsKey(id = object.getJalviewModelSequence()
4864 .getViewport()[0].getSequenceSetId()))
4866 if (Cache.log != null && Cache.log.isDebugEnabled())
4868 Cache.log.debug("Skipping seuqence set id " + id);
4875 public void addToSkipList(AlignFrame af)
4877 if (skipList == null)
4879 skipList = new Hashtable();
4881 skipList.put(af.getViewport().getSequenceSetId(), af);
4884 public void clearSkipList()
4886 if (skipList != null)
4893 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4894 boolean ignoreUnrefed)
4896 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4898 Vector dseqs = null;
4901 // create a list of new dataset sequences
4902 dseqs = new Vector();
4904 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4906 Sequence vamsasSeq = vamsasSet.getSequence(i);
4907 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4909 // create a new dataset
4912 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4913 dseqs.copyInto(dsseqs);
4914 ds = new jalview.datamodel.Alignment(dsseqs);
4915 debug("Created new dataset " + vamsasSet.getDatasetId()
4916 + " for alignment " + System.identityHashCode(al));
4917 addDatasetRef(vamsasSet.getDatasetId(), ds);
4919 // set the dataset for the newly imported alignment.
4920 if (al.getDataset() == null && !ignoreUnrefed)
4929 * sequence definition to create/merge dataset sequence for
4933 * vector to add new dataset sequence to
4935 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4936 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4938 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4940 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4941 SequenceI dsq = null;
4942 if (sq != null && sq.getDatasetSequence() != null)
4944 dsq = sq.getDatasetSequence();
4946 if (sq == null && ignoreUnrefed)
4950 String sqid = vamsasSeq.getDsseqid();
4953 // need to create or add a new dataset sequence reference to this sequence
4956 dsq = seqRefIds.get(sqid);
4961 // make a new dataset sequence
4962 dsq = sq.createDatasetSequence();
4965 // make up a new dataset reference for this sequence
4966 sqid = seqHash(dsq);
4968 dsq.setVamsasId(uniqueSetSuffix + sqid);
4969 seqRefIds.put(sqid, dsq);
4974 dseqs.addElement(dsq);
4979 ds.addSequence(dsq);
4985 { // make this dataset sequence sq's dataset sequence
4986 sq.setDatasetSequence(dsq);
4987 // and update the current dataset alignment
4992 if (!dseqs.contains(dsq))
4999 if (ds.findIndex(dsq) < 0)
5001 ds.addSequence(dsq);
5008 // TODO: refactor this as a merge dataset sequence function
5009 // now check that sq (the dataset sequence) sequence really is the union of
5010 // all references to it
5011 // boolean pre = sq.getStart() < dsq.getStart();
5012 // boolean post = sq.getEnd() > dsq.getEnd();
5016 // StringBuffer sb = new StringBuffer();
5017 String newres = jalview.analysis.AlignSeq.extractGaps(
5018 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5019 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5020 && newres.length() > dsq.getLength())
5022 // Update with the longer sequence.
5026 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5027 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5028 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5029 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5031 dsq.setSequence(newres);
5033 // TODO: merges will never happen if we 'know' we have the real dataset
5034 // sequence - this should be detected when id==dssid
5036 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5037 // + (pre ? "prepended" : "") + " "
5038 // + (post ? "appended" : ""));
5044 * TODO use AlignmentI here and in related methods - needs
5045 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5047 Hashtable<String, AlignmentI> datasetIds = null;
5049 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5051 private AlignmentI getDatasetFor(String datasetId)
5053 if (datasetIds == null)
5055 datasetIds = new Hashtable<String, AlignmentI>();
5058 if (datasetIds.containsKey(datasetId))
5060 return datasetIds.get(datasetId);
5065 private void addDatasetRef(String datasetId, AlignmentI dataset)
5067 if (datasetIds == null)
5069 datasetIds = new Hashtable<String, AlignmentI>();
5071 datasetIds.put(datasetId, dataset);
5075 * make a new dataset ID for this jalview dataset alignment
5080 private String getDatasetIdRef(AlignmentI dataset)
5082 if (dataset.getDataset() != null)
5084 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5086 String datasetId = makeHashCode(dataset, null);
5087 if (datasetId == null)
5089 // make a new datasetId and record it
5090 if (dataset2Ids == null)
5092 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5096 datasetId = dataset2Ids.get(dataset);
5098 if (datasetId == null)
5100 datasetId = "ds" + dataset2Ids.size() + 1;
5101 dataset2Ids.put(dataset, datasetId);
5107 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5109 for (int d = 0; d < sequence.getDBRefCount(); d++)
5111 DBRef dr = sequence.getDBRef(d);
5112 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5113 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5114 .getVersion(), sequence.getDBRef(d).getAccessionId());
5115 if (dr.getMapping() != null)
5117 entry.setMap(addMapping(dr.getMapping()));
5119 datasetSequence.addDBRef(entry);
5123 private jalview.datamodel.Mapping addMapping(Mapping m)
5125 SequenceI dsto = null;
5126 // Mapping m = dr.getMapping();
5127 int fr[] = new int[m.getMapListFromCount() * 2];
5128 Enumeration f = m.enumerateMapListFrom();
5129 for (int _i = 0; f.hasMoreElements(); _i += 2)
5131 MapListFrom mf = (MapListFrom) f.nextElement();
5132 fr[_i] = mf.getStart();
5133 fr[_i + 1] = mf.getEnd();
5135 int fto[] = new int[m.getMapListToCount() * 2];
5136 f = m.enumerateMapListTo();
5137 for (int _i = 0; f.hasMoreElements(); _i += 2)
5139 MapListTo mf = (MapListTo) f.nextElement();
5140 fto[_i] = mf.getStart();
5141 fto[_i + 1] = mf.getEnd();
5143 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5144 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5145 if (m.getMappingChoice() != null)
5147 MappingChoice mc = m.getMappingChoice();
5148 if (mc.getDseqFor() != null)
5150 String dsfor = "" + mc.getDseqFor();
5151 if (seqRefIds.containsKey(dsfor))
5156 jmap.setTo(seqRefIds.get(dsfor));
5160 frefedSequence.add(newMappingRef(dsfor, jmap));
5166 * local sequence definition
5168 Sequence ms = mc.getSequence();
5169 SequenceI djs = null;
5170 String sqid = ms.getDsseqid();
5171 if (sqid != null && sqid.length() > 0)
5174 * recover dataset sequence
5176 djs = seqRefIds.get(sqid);
5181 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5182 sqid = ((Object) ms).toString(); // make up a new hascode for
5183 // undefined dataset sequence hash
5184 // (unlikely to happen)
5190 * make a new dataset sequence and add it to refIds hash
5192 djs = new jalview.datamodel.Sequence(ms.getName(),
5194 djs.setStart(jmap.getMap().getToLowest());
5195 djs.setEnd(jmap.getMap().getToHighest());
5196 djs.setVamsasId(uniqueSetSuffix + sqid);
5198 incompleteSeqs.put(sqid, djs);
5199 seqRefIds.put(sqid, djs);
5202 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5211 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5212 boolean keepSeqRefs)
5215 JalviewModel jm = saveState(ap, null, null, null);
5220 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5224 uniqueSetSuffix = "";
5225 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5230 if (this.frefedSequence == null)
5232 frefedSequence = new Vector();
5235 viewportsAdded.clear();
5237 AlignFrame af = loadFromObject(jm, null, false, null);
5238 af.alignPanels.clear();
5239 af.closeMenuItem_actionPerformed(true);
5242 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5243 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5244 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5245 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5246 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5249 return af.alignPanel;
5253 * flag indicating if hashtables should be cleared on finalization TODO this
5254 * flag may not be necessary
5256 private final boolean _cleartables = true;
5258 private Hashtable jvids2vobj;
5263 * @see java.lang.Object#finalize()
5266 protected void finalize() throws Throwable
5268 // really make sure we have no buried refs left.
5273 this.seqRefIds = null;
5274 this.seqsToIds = null;
5278 private void warn(String msg)
5283 private void warn(String msg, Exception e)
5285 if (Cache.log != null)
5289 Cache.log.warn(msg, e);
5293 Cache.log.warn(msg);
5298 System.err.println("Warning: " + msg);
5301 e.printStackTrace();
5306 private void debug(String string)
5308 debug(string, null);
5311 private void debug(String msg, Exception e)
5313 if (Cache.log != null)
5317 Cache.log.debug(msg, e);
5321 Cache.log.debug(msg);
5326 System.err.println("Warning: " + msg);
5329 e.printStackTrace();
5335 * set the object to ID mapping tables used to write/recover objects and XML
5336 * ID strings for the jalview project. If external tables are provided then
5337 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5338 * object goes out of scope. - also populates the datasetIds hashtable with
5339 * alignment objects containing dataset sequences
5342 * Map from ID strings to jalview datamodel
5344 * Map from jalview datamodel to ID strings
5348 public void setObjectMappingTables(Hashtable vobj2jv,
5349 IdentityHashMap jv2vobj)
5351 this.jv2vobj = jv2vobj;
5352 this.vobj2jv = vobj2jv;
5353 Iterator ds = jv2vobj.keySet().iterator();
5355 while (ds.hasNext())
5357 Object jvobj = ds.next();
5358 id = jv2vobj.get(jvobj).toString();
5359 if (jvobj instanceof jalview.datamodel.Alignment)
5361 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5363 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5366 else if (jvobj instanceof jalview.datamodel.Sequence)
5368 // register sequence object so the XML parser can recover it.
5369 if (seqRefIds == null)
5371 seqRefIds = new HashMap<String, SequenceI>();
5373 if (seqsToIds == null)
5375 seqsToIds = new IdentityHashMap<SequenceI, String>();
5377 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5378 seqsToIds.put((SequenceI) jvobj, id);
5380 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5383 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5384 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5385 if (jvann.annotationId == null)
5387 jvann.annotationId = anid;
5389 if (!jvann.annotationId.equals(anid))
5391 // TODO verify that this is the correct behaviour
5392 this.warn("Overriding Annotation ID for " + anid
5393 + " from different id : " + jvann.annotationId);
5394 jvann.annotationId = anid;
5397 else if (jvobj instanceof String)
5399 if (jvids2vobj == null)
5401 jvids2vobj = new Hashtable();
5402 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5407 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5413 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5414 * objects created from the project archive. If string is null (default for
5415 * construction) then suffix will be set automatically.
5419 public void setUniqueSetSuffix(String string)
5421 uniqueSetSuffix = string;
5426 * uses skipList2 as the skipList for skipping views on sequence sets
5427 * associated with keys in the skipList
5431 public void setSkipList(Hashtable skipList2)
5433 skipList = skipList2;
5437 * Reads the jar entry of given name and returns its contents, or null if the
5438 * entry is not found.
5441 * @param jarEntryName
5444 protected String readJarEntry(jarInputStreamProvider jprovider,
5445 String jarEntryName)
5447 String result = null;
5448 BufferedReader in = null;
5453 * Reopen the jar input stream and traverse its entries to find a matching
5456 JarInputStream jin = jprovider.getJarInputStream();
5457 JarEntry entry = null;
5460 entry = jin.getNextJarEntry();
5461 } while (entry != null && !entry.getName().equals(jarEntryName));
5465 StringBuilder out = new StringBuilder(256);
5466 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5469 while ((data = in.readLine()) != null)
5473 result = out.toString();
5477 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5479 } catch (Exception ex)
5481 ex.printStackTrace();
5489 } catch (IOException e)
5500 * Returns an incrementing counter (0, 1, 2...)
5504 private synchronized int nextCounter()