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;
370 SequenceI seq = getSrefDatasetSeq();
375 cf.addMap(seq, mp.getTo(), mp.getMap());
382 public void resolveFrefedSequences()
384 Iterator<SeqFref> nextFref=frefedSequence.iterator();
385 int toresolve=frefedSequence.size();
386 int unresolved=0,failedtoresolve=0;
387 while (nextFref.hasNext()) {
388 SeqFref ref = nextFref.next();
389 if (ref.isResolvable())
398 } catch (Exception x) {
399 System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
409 System.err.println("Jalview Project Import: There were " + unresolved
410 + " forward references left unresolved on the stack.");
412 if (failedtoresolve>0)
414 System.err.println("SERIOUS! " + failedtoresolve
415 + " resolvable forward references failed to resolve.");
417 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
419 System.err.println("Jalview Project Import: There are "
420 + incompleteSeqs.size()
421 + " sequences which may have incomplete metadata.");
422 if (incompleteSeqs.size() < 10)
424 for (SequenceI s : incompleteSeqs.values())
426 System.err.println(s.toString());
432 .println("Too many to report. Skipping output of incomplete sequences.");
438 * This maintains a map of viewports, the key being the seqSetId. Important to
439 * set historyItem and redoList for multiple views
441 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
443 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
445 String uniqueSetSuffix = "";
448 * List of pdbfiles added to Jar
450 List<String> pdbfiles = null;
452 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
453 public void saveState(File statefile)
455 FileOutputStream fos = null;
458 fos = new FileOutputStream(statefile);
459 JarOutputStream jout = new JarOutputStream(fos);
462 } catch (Exception e)
464 // TODO: inform user of the problem - they need to know if their data was
466 if (errorMessage == null)
468 errorMessage = "Couldn't write Jalview Archive to output file '"
469 + statefile + "' - See console error log for details";
473 errorMessage += "(output file was '" + statefile + "')";
483 } catch (IOException e)
493 * Writes a jalview project archive to the given Jar output stream.
497 public void saveState(JarOutputStream jout)
499 AlignFrame[] frames = Desktop.getAlignFrames();
505 saveAllFrames(Arrays.asList(frames), jout);
509 * core method for storing state for a set of AlignFrames.
512 * - frames involving all data to be exported (including containing
515 * - project output stream
517 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
519 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
522 * ensure cached data is clear before starting
524 // todo tidy up seqRefIds, seqsToIds initialisation / reset
526 splitFrameCandidates.clear();
531 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
532 // //////////////////////////////////////////////////
534 List<String> shortNames = new ArrayList<String>();
535 List<String> viewIds = new ArrayList<String>();
538 for (int i = frames.size() - 1; i > -1; i--)
540 AlignFrame af = frames.get(i);
544 .containsKey(af.getViewport().getSequenceSetId()))
549 String shortName = makeFilename(af, shortNames);
551 int ap, apSize = af.alignPanels.size();
553 for (ap = 0; ap < apSize; ap++)
555 AlignmentPanel apanel = af.alignPanels.get(ap);
556 String fileName = apSize == 1 ? shortName : ap + shortName;
557 if (!fileName.endsWith(".xml"))
559 fileName = fileName + ".xml";
562 saveState(apanel, fileName, jout, viewIds);
564 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
566 if (!dsses.containsKey(dssid))
568 dsses.put(dssid, af);
573 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
579 } catch (Exception foo)
584 } catch (Exception ex)
586 // TODO: inform user of the problem - they need to know if their data was
588 if (errorMessage == null)
590 errorMessage = "Couldn't write Jalview Archive - see error output for details";
592 ex.printStackTrace();
597 * Generates a distinct file name, based on the title of the AlignFrame, by
598 * appending _n for increasing n until an unused name is generated. The new
599 * name (without its extension) is added to the list.
603 * @return the generated name, with .xml extension
605 protected String makeFilename(AlignFrame af, List<String> namesUsed)
607 String shortName = af.getTitle();
609 if (shortName.indexOf(File.separatorChar) > -1)
611 shortName = shortName.substring(shortName
612 .lastIndexOf(File.separatorChar) + 1);
617 while (namesUsed.contains(shortName))
619 if (shortName.endsWith("_" + (count - 1)))
621 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
624 shortName = shortName.concat("_" + count);
628 namesUsed.add(shortName);
630 if (!shortName.endsWith(".xml"))
632 shortName = shortName + ".xml";
637 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
638 public boolean saveAlignment(AlignFrame af, String jarFile,
643 FileOutputStream fos = new FileOutputStream(jarFile);
644 JarOutputStream jout = new JarOutputStream(fos);
645 List<AlignFrame> frames = new ArrayList<AlignFrame>();
647 // resolve splitframes
648 if (af.getViewport().getCodingComplement() != null)
650 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
656 saveAllFrames(frames, jout);
660 } catch (Exception foo)
666 } catch (Exception ex)
668 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
669 ex.printStackTrace();
674 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
675 String fileName, JarOutputStream jout)
678 for (String dssids : dsses.keySet())
680 AlignFrame _af = dsses.get(dssids);
681 String jfileName = fileName + " Dataset for " + _af.getTitle();
682 if (!jfileName.endsWith(".xml"))
684 jfileName = jfileName + ".xml";
686 saveState(_af.alignPanel, jfileName, true, jout, null);
691 * create a JalviewModel from an alignment view and marshall it to a
695 * panel to create jalview model for
697 * name of alignment panel written to output stream
704 public JalviewModel saveState(AlignmentPanel ap, String fileName,
705 JarOutputStream jout, List<String> viewIds)
707 return saveState(ap, fileName, false, jout, viewIds);
711 * create a JalviewModel from an alignment view and marshall it to a
715 * panel to create jalview model for
717 * name of alignment panel written to output stream
719 * when true, only write the dataset for the alignment, not the data
720 * associated with the view.
726 public JalviewModel saveState(AlignmentPanel ap, String fileName,
727 boolean storeDS, JarOutputStream jout, List<String> viewIds)
731 viewIds = new ArrayList<String>();
736 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
738 AlignViewport av = ap.av;
740 JalviewModel object = new JalviewModel();
741 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
743 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
744 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
745 "Development Build"));
748 * rjal is full height alignment, jal is actual alignment with full metadata
749 * but excludes hidden sequences.
751 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
753 if (av.hasHiddenRows())
755 rjal = jal.getHiddenSequences().getFullAlignment();
758 SequenceSet vamsasSet = new SequenceSet();
760 JalviewModelSequence jms = new JalviewModelSequence();
762 vamsasSet.setGapChar(jal.getGapCharacter() + "");
764 if (jal.getDataset() != null)
766 // dataset id is the dataset's hashcode
767 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
770 // switch jal and the dataset
771 jal = jal.getDataset();
775 if (jal.getProperties() != null)
777 Enumeration en = jal.getProperties().keys();
778 while (en.hasMoreElements())
780 String key = en.nextElement().toString();
781 SequenceSetProperties ssp = new SequenceSetProperties();
783 ssp.setValue(jal.getProperties().get(key).toString());
784 vamsasSet.addSequenceSetProperties(ssp);
789 Set<String> calcIdSet = new HashSet<String>();
792 for (final SequenceI jds : rjal.getSequences())
794 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
795 : jds.getDatasetSequence();
796 String id = seqHash(jds);
798 if (seqRefIds.get(id) != null)
800 // This happens for two reasons: 1. multiple views are being serialised.
801 // 2. the hashCode has collided with another sequence's code. This DOES
802 // HAPPEN! (PF00072.15.stk does this)
803 // JBPNote: Uncomment to debug writing out of files that do not read
804 // back in due to ArrayOutOfBoundExceptions.
805 // System.err.println("vamsasSeq backref: "+id+"");
806 // System.err.println(jds.getName()+"
807 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
808 // System.err.println("Hashcode: "+seqHash(jds));
809 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
810 // System.err.println(rsq.getName()+"
811 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
812 // System.err.println("Hashcode: "+seqHash(rsq));
816 vamsasSeq = createVamsasSequence(id, jds);
817 vamsasSet.addSequence(vamsasSeq);
818 seqRefIds.put(id, jds);
822 jseq.setStart(jds.getStart());
823 jseq.setEnd(jds.getEnd());
824 jseq.setColour(av.getSequenceColour(jds).getRGB());
826 jseq.setId(id); // jseq id should be a string not a number
829 // Store any sequences this sequence represents
830 if (av.hasHiddenRows())
832 // use rjal, contains the full height alignment
833 jseq.setHidden(av.getAlignment().getHiddenSequences()
836 if (av.isHiddenRepSequence(jds))
838 jalview.datamodel.SequenceI[] reps = av
839 .getRepresentedSequences(jds)
840 .getSequencesInOrder(rjal);
842 for (int h = 0; h < reps.length; h++)
846 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
851 // mark sequence as reference - if it is the reference for this view
854 jseq.setViewreference(jds == jal.getSeqrep());
858 // TODO: omit sequence features from each alignment view's XML dump if we
859 // are storing dataset
860 if (jds.getSequenceFeatures() != null)
862 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
864 while (index < sf.length)
866 Features features = new Features();
868 features.setBegin(sf[index].getBegin());
869 features.setEnd(sf[index].getEnd());
870 features.setDescription(sf[index].getDescription());
871 features.setType(sf[index].getType());
872 features.setFeatureGroup(sf[index].getFeatureGroup());
873 features.setScore(sf[index].getScore());
874 if (sf[index].links != null)
876 for (int l = 0; l < sf[index].links.size(); l++)
878 OtherData keyValue = new OtherData();
879 keyValue.setKey("LINK_" + l);
880 keyValue.setValue(sf[index].links.elementAt(l).toString());
881 features.addOtherData(keyValue);
884 if (sf[index].otherDetails != null)
887 Iterator<String> keys = sf[index].otherDetails.keySet()
889 while (keys.hasNext())
892 OtherData keyValue = new OtherData();
893 keyValue.setKey(key);
894 keyValue.setValue(sf[index].otherDetails.get(key).toString());
895 features.addOtherData(keyValue);
899 jseq.addFeatures(features);
904 if (jdatasq.getAllPDBEntries() != null)
906 Enumeration en = jdatasq.getAllPDBEntries().elements();
907 while (en.hasMoreElements())
909 Pdbids pdb = new Pdbids();
910 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
913 String pdbId = entry.getId();
915 pdb.setType(entry.getType());
918 * Store any structure views associated with this sequence. This
919 * section copes with duplicate entries in the project, so a dataset
920 * only view *should* be coped with sensibly.
922 // This must have been loaded, is it still visible?
923 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
924 String matchedFile = null;
925 for (int f = frames.length - 1; f > -1; f--)
927 if (frames[f] instanceof StructureViewerBase)
929 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
930 matchedFile = saveStructureState(ap, jds, pdb, entry,
931 viewIds, matchedFile, viewFrame);
933 * Only store each structure viewer's state once in the project
934 * jar. First time through only (storeDS==false)
936 String viewId = viewFrame.getViewId();
937 if (!storeDS && !viewIds.contains(viewId))
942 String viewerState = viewFrame.getStateInfo();
943 writeJarEntry(jout, getViewerJarEntryName(viewId),
944 viewerState.getBytes());
945 } catch (IOException e)
947 System.err.println("Error saving viewer state: "
954 if (matchedFile != null || entry.getFile() != null)
956 if (entry.getFile() != null)
959 matchedFile = entry.getFile();
961 pdb.setFile(matchedFile); // entry.getFile());
962 if (pdbfiles == null)
964 pdbfiles = new ArrayList<String>();
967 if (!pdbfiles.contains(pdbId))
970 copyFileToJar(jout, matchedFile, pdbId);
974 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
976 PdbentryItem item = new PdbentryItem();
977 Hashtable properties = entry.getProperty();
978 Enumeration en2 = properties.keys();
979 while (en2.hasMoreElements())
981 Property prop = new Property();
982 String key = en2.nextElement().toString();
984 prop.setValue(properties.get(key).toString());
985 item.addProperty(prop);
987 pdb.addPdbentryItem(item);
994 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
999 if (!storeDS && av.hasHiddenRows())
1001 jal = av.getAlignment();
1005 if (storeDS && jal.getCodonFrames() != null)
1007 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1008 for (AlignedCodonFrame acf : jac)
1010 AlcodonFrame alc = new AlcodonFrame();
1011 if (acf.getProtMappings() != null
1012 && acf.getProtMappings().length > 0)
1014 boolean hasMap = false;
1015 SequenceI[] dnas = acf.getdnaSeqs();
1016 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1017 for (int m = 0; m < pmaps.length; m++)
1019 AlcodMap alcmap = new AlcodMap();
1020 alcmap.setDnasq(seqHash(dnas[m]));
1021 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1023 alc.addAlcodMap(alcmap);
1028 vamsasSet.addAlcodonFrame(alc);
1031 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1033 // AlcodonFrame alc = new AlcodonFrame();
1034 // vamsasSet.addAlcodonFrame(alc);
1035 // for (int p = 0; p < acf.aaWidth; p++)
1037 // Alcodon cmap = new Alcodon();
1038 // if (acf.codons[p] != null)
1040 // // Null codons indicate a gapped column in the translated peptide
1042 // cmap.setPos1(acf.codons[p][0]);
1043 // cmap.setPos2(acf.codons[p][1]);
1044 // cmap.setPos3(acf.codons[p][2]);
1046 // alc.addAlcodon(cmap);
1048 // if (acf.getProtMappings() != null
1049 // && acf.getProtMappings().length > 0)
1051 // SequenceI[] dnas = acf.getdnaSeqs();
1052 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1053 // for (int m = 0; m < pmaps.length; m++)
1055 // AlcodMap alcmap = new AlcodMap();
1056 // alcmap.setDnasq(seqHash(dnas[m]));
1057 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1059 // alc.addAlcodMap(alcmap);
1066 // /////////////////////////////////
1067 if (!storeDS && av.currentTree != null)
1069 // FIND ANY ASSOCIATED TREES
1070 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1071 if (Desktop.desktop != null)
1073 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1075 for (int t = 0; t < frames.length; t++)
1077 if (frames[t] instanceof TreePanel)
1079 TreePanel tp = (TreePanel) frames[t];
1081 if (tp.treeCanvas.av.getAlignment() == jal)
1083 Tree tree = new Tree();
1084 tree.setTitle(tp.getTitle());
1085 tree.setCurrentTree((av.currentTree == tp.getTree()));
1086 tree.setNewick(tp.getTree().toString());
1087 tree.setThreshold(tp.treeCanvas.threshold);
1089 tree.setFitToWindow(tp.fitToWindow.getState());
1090 tree.setFontName(tp.getTreeFont().getName());
1091 tree.setFontSize(tp.getTreeFont().getSize());
1092 tree.setFontStyle(tp.getTreeFont().getStyle());
1093 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1095 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1096 tree.setShowDistances(tp.distanceMenu.getState());
1098 tree.setHeight(tp.getHeight());
1099 tree.setWidth(tp.getWidth());
1100 tree.setXpos(tp.getX());
1101 tree.setYpos(tp.getY());
1102 tree.setId(makeHashCode(tp, null));
1112 * store forward refs from an annotationRow to any groups
1114 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1117 for (SequenceI sq : jal.getSequences())
1119 // Store annotation on dataset sequences only
1120 AlignmentAnnotation[] aa = sq.getAnnotation();
1121 if (aa != null && aa.length > 0)
1123 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1130 if (jal.getAlignmentAnnotation() != null)
1132 // Store the annotation shown on the alignment.
1133 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1134 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1139 if (jal.getGroups() != null)
1141 JGroup[] groups = new JGroup[jal.getGroups().size()];
1143 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1145 JGroup jGroup = new JGroup();
1146 groups[++i] = jGroup;
1148 jGroup.setStart(sg.getStartRes());
1149 jGroup.setEnd(sg.getEndRes());
1150 jGroup.setName(sg.getName());
1151 if (groupRefs.containsKey(sg))
1153 // group has references so set its ID field
1154 jGroup.setId(groupRefs.get(sg));
1158 if (sg.cs.conservationApplied())
1160 jGroup.setConsThreshold(sg.cs.getConservationInc());
1162 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1164 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1168 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1171 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1173 jGroup.setColour("AnnotationColourGradient");
1174 jGroup.setAnnotationColours(constructAnnotationColours(
1175 (jalview.schemes.AnnotationColourGradient) sg.cs,
1178 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1180 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1184 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1187 jGroup.setPidThreshold(sg.cs.getThreshold());
1190 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1191 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1192 jGroup.setDisplayText(sg.getDisplayText());
1193 jGroup.setColourText(sg.getColourText());
1194 jGroup.setTextCol1(sg.textColour.getRGB());
1195 jGroup.setTextCol2(sg.textColour2.getRGB());
1196 jGroup.setTextColThreshold(sg.thresholdTextColour);
1197 jGroup.setShowUnconserved(sg.getShowNonconserved());
1198 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1199 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1200 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1201 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1202 for (SequenceI seq : sg.getSequences())
1204 jGroup.addSeq(seqHash(seq));
1208 jms.setJGroup(groups);
1212 // /////////SAVE VIEWPORT
1213 Viewport view = new Viewport();
1214 view.setTitle(ap.alignFrame.getTitle());
1215 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1216 av.getSequenceSetId()));
1217 view.setId(av.getViewId());
1218 if (av.getCodingComplement() != null)
1220 view.setComplementId(av.getCodingComplement().getViewId());
1222 view.setViewName(av.viewName);
1223 view.setGatheredViews(av.isGatherViewsHere());
1225 Rectangle size = ap.av.getExplodedGeometry();
1226 Rectangle position = size;
1229 size = ap.alignFrame.getBounds();
1230 if (av.getCodingComplement() != null)
1232 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1240 view.setXpos(position.x);
1241 view.setYpos(position.y);
1243 view.setWidth(size.width);
1244 view.setHeight(size.height);
1246 view.setStartRes(av.startRes);
1247 view.setStartSeq(av.startSeq);
1249 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1251 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1254 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1256 AnnotationColours ac = constructAnnotationColours(
1257 (jalview.schemes.AnnotationColourGradient) av
1258 .getGlobalColourScheme(),
1261 view.setAnnotationColours(ac);
1262 view.setBgColour("AnnotationColourGradient");
1266 view.setBgColour(ColourSchemeProperty.getColourName(av
1267 .getGlobalColourScheme()));
1270 ColourSchemeI cs = av.getGlobalColourScheme();
1274 if (cs.conservationApplied())
1276 view.setConsThreshold(cs.getConservationInc());
1277 if (cs instanceof jalview.schemes.UserColourScheme)
1279 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1283 if (cs instanceof ResidueColourScheme)
1285 view.setPidThreshold(cs.getThreshold());
1289 view.setConservationSelected(av.getConservationSelected());
1290 view.setPidSelected(av.getAbovePIDThreshold());
1291 view.setFontName(av.font.getName());
1292 view.setFontSize(av.font.getSize());
1293 view.setFontStyle(av.font.getStyle());
1294 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1295 view.setRenderGaps(av.isRenderGaps());
1296 view.setShowAnnotation(av.isShowAnnotation());
1297 view.setShowBoxes(av.getShowBoxes());
1298 view.setShowColourText(av.getColourText());
1299 view.setShowFullId(av.getShowJVSuffix());
1300 view.setRightAlignIds(av.isRightAlignIds());
1301 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1302 view.setShowText(av.getShowText());
1303 view.setShowUnconserved(av.getShowUnconserved());
1304 view.setWrapAlignment(av.getWrapAlignment());
1305 view.setTextCol1(av.getTextColour().getRGB());
1306 view.setTextCol2(av.getTextColour2().getRGB());
1307 view.setTextColThreshold(av.getThresholdTextColour());
1308 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1309 view.setShowSequenceLogo(av.isShowSequenceLogo());
1310 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1311 view.setShowGroupConsensus(av.isShowGroupConsensus());
1312 view.setShowGroupConservation(av.isShowGroupConservation());
1313 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1314 view.setShowDbRefTooltip(av.isShowDBRefs());
1315 view.setFollowHighlight(av.isFollowHighlight());
1316 view.setFollowSelection(av.followSelection);
1317 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1318 if (av.getFeaturesDisplayed() != null)
1320 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1322 String[] renderOrder = ap.getSeqPanel().seqCanvas
1323 .getFeatureRenderer().getRenderOrder()
1324 .toArray(new String[0]);
1326 Vector<String> settingsAdded = new Vector<String>();
1327 if (renderOrder != null)
1329 for (String featureType : renderOrder)
1331 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1332 .getFeatureRenderer()
1333 .getFeatureStyle(featureType);
1334 Setting setting = new Setting();
1335 setting.setType(featureType);
1336 if (!fcol.isSimpleColour())
1338 setting.setColour(fcol.getMaxColour().getRGB());
1339 setting.setMincolour(fcol.getMinColour().getRGB());
1340 setting.setMin(fcol.getMin());
1341 setting.setMax(fcol.getMax());
1342 setting.setColourByLabel(fcol.isColourByLabel());
1343 setting.setAutoScale(fcol.isAutoScaled());
1344 setting.setThreshold(fcol.getThreshold());
1345 // -1 = No threshold, 0 = Below, 1 = Above
1346 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1347 : (fcol.isBelowThreshold() ? 0 : -1));
1351 setting.setColour(fcol.getColour().getRGB());
1354 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1356 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1357 .getOrder(featureType);
1360 setting.setOrder(rorder);
1362 fs.addSetting(setting);
1363 settingsAdded.addElement(featureType);
1367 // is groups actually supposed to be a map here ?
1368 Iterator<String> en = ap.getSeqPanel().seqCanvas
1369 .getFeatureRenderer()
1370 .getFeatureGroups().iterator();
1371 Vector<String> groupsAdded = new Vector<String>();
1372 while (en.hasNext())
1374 String grp = en.next();
1375 if (groupsAdded.contains(grp))
1379 Group g = new Group();
1381 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1382 .getFeatureRenderer().checkGroupVisibility(grp, false))
1385 groupsAdded.addElement(grp);
1387 jms.setFeatureSettings(fs);
1390 if (av.hasHiddenColumns())
1392 if (av.getColumnSelection() == null
1393 || av.getColumnSelection().getHiddenColumns() == null)
1395 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1399 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1402 int[] region = av.getColumnSelection().getHiddenColumns()
1404 HiddenColumns hc = new HiddenColumns();
1405 hc.setStart(region[0]);
1406 hc.setEnd(region[1]);
1407 view.addHiddenColumns(hc);
1411 if (calcIdSet.size() > 0)
1413 for (String calcId : calcIdSet)
1415 if (calcId.trim().length() > 0)
1417 CalcIdParam cidp = createCalcIdParam(calcId, av);
1418 // Some calcIds have no parameters.
1421 view.addCalcIdParam(cidp);
1427 jms.addViewport(view);
1429 object.setJalviewModelSequence(jms);
1430 object.getVamsasModel().addSequenceSet(vamsasSet);
1432 if (jout != null && fileName != null)
1434 // We may not want to write the object to disk,
1435 // eg we can copy the alignViewport to a new view object
1436 // using save and then load
1439 System.out.println("Writing jar entry " + fileName);
1440 JarEntry entry = new JarEntry(fileName);
1441 jout.putNextEntry(entry);
1442 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1444 Marshaller marshaller = new Marshaller(pout);
1445 marshaller.marshal(object);
1448 } catch (Exception ex)
1450 // TODO: raise error in GUI if marshalling failed.
1451 ex.printStackTrace();
1458 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1459 * for each viewer, with
1461 * <li>viewer geometry (position, size, split pane divider location)</li>
1462 * <li>index of the selected structure in the viewer (currently shows gapped
1464 * <li>the id of the annotation holding RNA secondary structure</li>
1465 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1467 * Varna viewer state is also written out (in native Varna XML) to separate
1468 * project jar entries. A separate entry is written for each RNA structure
1469 * displayed, with the naming convention
1471 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1479 * @param storeDataset
1481 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1482 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1483 boolean storeDataset)
1485 if (Desktop.desktop == null)
1489 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1490 for (int f = frames.length - 1; f > -1; f--)
1492 if (frames[f] instanceof AppVarna)
1494 AppVarna varna = (AppVarna) frames[f];
1496 * link the sequence to every viewer that is showing it and is linked to
1497 * its alignment panel
1499 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1501 String viewId = varna.getViewId();
1502 RnaViewer rna = new RnaViewer();
1503 rna.setViewId(viewId);
1504 rna.setTitle(varna.getTitle());
1505 rna.setXpos(varna.getX());
1506 rna.setYpos(varna.getY());
1507 rna.setWidth(varna.getWidth());
1508 rna.setHeight(varna.getHeight());
1509 rna.setDividerLocation(varna.getDividerLocation());
1510 rna.setSelectedRna(varna.getSelectedIndex());
1511 jseq.addRnaViewer(rna);
1514 * Store each Varna panel's state once in the project per sequence.
1515 * First time through only (storeDataset==false)
1517 // boolean storeSessions = false;
1518 // String sequenceViewId = viewId + seqsToIds.get(jds);
1519 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1521 // viewIds.add(sequenceViewId);
1522 // storeSessions = true;
1524 for (RnaModel model : varna.getModels())
1526 if (model.seq == jds)
1529 * VARNA saves each view (sequence or alignment secondary
1530 * structure, gapped or trimmed) as a separate XML file
1532 String jarEntryName = rnaSessions.get(model);
1533 if (jarEntryName == null)
1536 String varnaStateFile = varna.getStateInfo(model.rna);
1537 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1538 copyFileToJar(jout, varnaStateFile, jarEntryName);
1539 rnaSessions.put(model, jarEntryName);
1541 SecondaryStructure ss = new SecondaryStructure();
1542 String annotationId = varna.getAnnotation(jds).annotationId;
1543 ss.setAnnotationId(annotationId);
1544 ss.setViewerState(jarEntryName);
1545 ss.setGapped(model.gapped);
1546 ss.setTitle(model.title);
1547 rna.addSecondaryStructure(ss);
1556 * Copy the contents of a file to a new entry added to the output jar
1560 * @param jarEntryName
1562 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1563 String jarEntryName)
1565 DataInputStream dis = null;
1568 File file = new File(infilePath);
1569 if (file.exists() && jout != null)
1571 dis = new DataInputStream(new FileInputStream(file));
1572 byte[] data = new byte[(int) file.length()];
1573 dis.readFully(data);
1574 writeJarEntry(jout, jarEntryName, data);
1576 } catch (Exception ex)
1578 ex.printStackTrace();
1586 } catch (IOException e)
1595 * Write the data to a new entry of given name in the output jar file
1598 * @param jarEntryName
1600 * @throws IOException
1602 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1603 byte[] data) throws IOException
1607 System.out.println("Writing jar entry " + jarEntryName);
1608 jout.putNextEntry(new JarEntry(jarEntryName));
1609 DataOutputStream dout = new DataOutputStream(jout);
1610 dout.write(data, 0, data.length);
1617 * Save the state of a structure viewer
1622 * the archive XML element under which to save the state
1625 * @param matchedFile
1629 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1630 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1631 String matchedFile, StructureViewerBase viewFrame)
1633 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1636 * Look for any bindings for this viewer to the PDB file of interest
1637 * (including part matches excluding chain id)
1639 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1641 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1642 final String pdbId = pdbentry.getId();
1643 if (!pdbId.equals(entry.getId())
1644 && !(entry.getId().length() > 4 && entry.getId()
1645 .toLowerCase().startsWith(pdbId.toLowerCase())))
1648 * not interested in a binding to a different PDB entry here
1652 if (matchedFile == null)
1654 matchedFile = pdbentry.getFile();
1656 else if (!matchedFile.equals(pdbentry.getFile()))
1659 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1660 + pdbentry.getFile());
1664 // can get at it if the ID
1665 // match is ambiguous (e.g.
1668 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1670 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1671 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1673 StructureState state = new StructureState();
1674 state.setVisible(true);
1675 state.setXpos(viewFrame.getX());
1676 state.setYpos(viewFrame.getY());
1677 state.setWidth(viewFrame.getWidth());
1678 state.setHeight(viewFrame.getHeight());
1679 final String viewId = viewFrame.getViewId();
1680 state.setViewId(viewId);
1681 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1682 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1683 state.setColourByJmol(viewFrame.isColouredByViewer());
1684 state.setType(viewFrame.getViewerType().toString());
1685 pdb.addStructureState(state);
1692 private AnnotationColours constructAnnotationColours(
1693 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1694 JalviewModelSequence jms)
1696 AnnotationColours ac = new AnnotationColours();
1697 ac.setAboveThreshold(acg.getAboveThreshold());
1698 ac.setThreshold(acg.getAnnotationThreshold());
1699 ac.setAnnotation(acg.getAnnotation());
1700 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1702 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1707 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1711 ac.setMaxColour(acg.getMaxColour().getRGB());
1712 ac.setMinColour(acg.getMinColour().getRGB());
1713 ac.setPerSequence(acg.isSeqAssociated());
1714 ac.setPredefinedColours(acg.isPredefinedColours());
1718 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1719 IdentityHashMap<SequenceGroup, String> groupRefs,
1720 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1721 SequenceSet vamsasSet)
1724 for (int i = 0; i < aa.length; i++)
1726 Annotation an = new Annotation();
1728 AlignmentAnnotation annotation = aa[i];
1729 if (annotation.annotationId != null)
1731 annotationIds.put(annotation.annotationId, annotation);
1734 an.setId(annotation.annotationId);
1736 an.setVisible(annotation.visible);
1738 an.setDescription(annotation.description);
1740 if (annotation.sequenceRef != null)
1742 // 2.9 JAL-1781 xref on sequence id rather than name
1743 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1745 if (annotation.groupRef != null)
1747 String groupIdr = groupRefs.get(annotation.groupRef);
1748 if (groupIdr == null)
1750 // make a locally unique String
1752 annotation.groupRef,
1753 groupIdr = ("" + System.currentTimeMillis()
1754 + annotation.groupRef.getName() + groupRefs
1757 an.setGroupRef(groupIdr.toString());
1760 // store all visualization attributes for annotation
1761 an.setGraphHeight(annotation.graphHeight);
1762 an.setCentreColLabels(annotation.centreColLabels);
1763 an.setScaleColLabels(annotation.scaleColLabel);
1764 an.setShowAllColLabels(annotation.showAllColLabels);
1765 an.setBelowAlignment(annotation.belowAlignment);
1767 if (annotation.graph > 0)
1770 an.setGraphType(annotation.graph);
1771 an.setGraphGroup(annotation.graphGroup);
1772 if (annotation.getThreshold() != null)
1774 ThresholdLine line = new ThresholdLine();
1775 line.setLabel(annotation.getThreshold().label);
1776 line.setValue(annotation.getThreshold().value);
1777 line.setColour(annotation.getThreshold().colour.getRGB());
1778 an.setThresholdLine(line);
1786 an.setLabel(annotation.label);
1788 if (annotation == av.getAlignmentQualityAnnot()
1789 || annotation == av.getAlignmentConservationAnnotation()
1790 || annotation == av.getAlignmentConsensusAnnotation()
1791 || annotation.autoCalculated)
1793 // new way of indicating autocalculated annotation -
1794 an.setAutoCalculated(annotation.autoCalculated);
1796 if (annotation.hasScore())
1798 an.setScore(annotation.getScore());
1801 if (annotation.getCalcId() != null)
1803 calcIdSet.add(annotation.getCalcId());
1804 an.setCalcId(annotation.getCalcId());
1806 if (annotation.hasProperties())
1808 for (String pr : annotation.getProperties())
1810 Property prop = new Property();
1812 prop.setValue(annotation.getProperty(pr));
1813 an.addProperty(prop);
1817 AnnotationElement ae;
1818 if (annotation.annotations != null)
1820 an.setScoreOnly(false);
1821 for (int a = 0; a < annotation.annotations.length; a++)
1823 if ((annotation == null) || (annotation.annotations[a] == null))
1828 ae = new AnnotationElement();
1829 if (annotation.annotations[a].description != null)
1831 ae.setDescription(annotation.annotations[a].description);
1833 if (annotation.annotations[a].displayCharacter != null)
1835 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1838 if (!Float.isNaN(annotation.annotations[a].value))
1840 ae.setValue(annotation.annotations[a].value);
1844 if (annotation.annotations[a].secondaryStructure > ' ')
1846 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1850 if (annotation.annotations[a].colour != null
1851 && annotation.annotations[a].colour != java.awt.Color.black)
1853 ae.setColour(annotation.annotations[a].colour.getRGB());
1856 an.addAnnotationElement(ae);
1857 if (annotation.autoCalculated)
1859 // only write one non-null entry into the annotation row -
1860 // sufficient to get the visualization attributes necessary to
1868 an.setScoreOnly(true);
1870 if (!storeDS || (storeDS && !annotation.autoCalculated))
1872 // skip autocalculated annotation - these are only provided for
1874 vamsasSet.addAnnotation(an);
1880 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1882 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1883 if (settings != null)
1885 CalcIdParam vCalcIdParam = new CalcIdParam();
1886 vCalcIdParam.setCalcId(calcId);
1887 vCalcIdParam.addServiceURL(settings.getServiceURI());
1888 // generic URI allowing a third party to resolve another instance of the
1889 // service used for this calculation
1890 for (String urls : settings.getServiceURLs())
1892 vCalcIdParam.addServiceURL(urls);
1894 vCalcIdParam.setVersion("1.0");
1895 if (settings.getPreset() != null)
1897 WsParamSetI setting = settings.getPreset();
1898 vCalcIdParam.setName(setting.getName());
1899 vCalcIdParam.setDescription(setting.getDescription());
1903 vCalcIdParam.setName("");
1904 vCalcIdParam.setDescription("Last used parameters");
1906 // need to be able to recover 1) settings 2) user-defined presets or
1907 // recreate settings from preset 3) predefined settings provided by
1908 // service - or settings that can be transferred (or discarded)
1909 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1911 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1912 // todo - decide if updateImmediately is needed for any projects.
1914 return vCalcIdParam;
1919 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1922 if (calcIdParam.getVersion().equals("1.0"))
1924 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1925 .getPreferredServiceFor(calcIdParam.getServiceURL());
1926 if (service != null)
1928 WsParamSetI parmSet = null;
1931 parmSet = service.getParamStore().parseServiceParameterFile(
1932 calcIdParam.getName(), calcIdParam.getDescription(),
1933 calcIdParam.getServiceURL(),
1934 calcIdParam.getParameters().replace("|\\n|", "\n"));
1935 } catch (IOException x)
1937 warn("Couldn't parse parameter data for "
1938 + calcIdParam.getCalcId(), x);
1941 List<ArgumentI> argList = null;
1942 if (calcIdParam.getName().length() > 0)
1944 parmSet = service.getParamStore()
1945 .getPreset(calcIdParam.getName());
1946 if (parmSet != null)
1948 // TODO : check we have a good match with settings in AACon -
1949 // otherwise we'll need to create a new preset
1954 argList = parmSet.getArguments();
1957 AAConSettings settings = new AAConSettings(
1958 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1959 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1960 calcIdParam.isNeedsUpdate());
1965 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1969 throw new Error(MessageManager.formatMessage(
1970 "error.unsupported_version_calcIdparam",
1971 new Object[] { calcIdParam.toString() }));
1975 * External mapping between jalview objects and objects yielding a valid and
1976 * unique object ID string. This is null for normal Jalview project IO, but
1977 * non-null when a jalview project is being read or written as part of a
1980 IdentityHashMap jv2vobj = null;
1983 * Construct a unique ID for jvobj using either existing bindings or if none
1984 * exist, the result of the hashcode call for the object.
1987 * jalview data object
1988 * @return unique ID for referring to jvobj
1990 private String makeHashCode(Object jvobj, String altCode)
1992 if (jv2vobj != null)
1994 Object id = jv2vobj.get(jvobj);
1997 return id.toString();
1999 // check string ID mappings
2000 if (jvids2vobj != null && jvobj instanceof String)
2002 id = jvids2vobj.get(jvobj);
2006 return id.toString();
2008 // give up and warn that something has gone wrong
2009 warn("Cannot find ID for object in external mapping : " + jvobj);
2015 * return local jalview object mapped to ID, if it exists
2019 * @return null or object bound to idcode
2021 private Object retrieveExistingObj(String idcode)
2023 if (idcode != null && vobj2jv != null)
2025 return vobj2jv.get(idcode);
2031 * binding from ID strings from external mapping table to jalview data model
2034 private Hashtable vobj2jv;
2036 private Sequence createVamsasSequence(String id, SequenceI jds)
2038 return createVamsasSequence(true, id, jds, null);
2041 private Sequence createVamsasSequence(boolean recurse, String id,
2042 SequenceI jds, SequenceI parentseq)
2044 Sequence vamsasSeq = new Sequence();
2045 vamsasSeq.setId(id);
2046 vamsasSeq.setName(jds.getName());
2047 vamsasSeq.setSequence(jds.getSequenceAsString());
2048 vamsasSeq.setDescription(jds.getDescription());
2049 jalview.datamodel.DBRefEntry[] dbrefs = null;
2050 if (jds.getDatasetSequence() != null)
2052 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2056 // seqId==dsseqid so we can tell which sequences really are
2057 // dataset sequences only
2058 vamsasSeq.setDsseqid(id);
2059 dbrefs = jds.getDBRefs();
2060 if (parentseq == null)
2067 for (int d = 0; d < dbrefs.length; d++)
2069 DBRef dbref = new DBRef();
2070 dbref.setSource(dbrefs[d].getSource());
2071 dbref.setVersion(dbrefs[d].getVersion());
2072 dbref.setAccessionId(dbrefs[d].getAccessionId());
2073 if (dbrefs[d].hasMap())
2075 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2077 dbref.setMapping(mp);
2079 vamsasSeq.addDBRef(dbref);
2085 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2086 SequenceI parentseq, SequenceI jds, boolean recurse)
2089 if (jmp.getMap() != null)
2093 jalview.util.MapList mlst = jmp.getMap();
2094 List<int[]> r = mlst.getFromRanges();
2095 for (int[] range : r)
2097 MapListFrom mfrom = new MapListFrom();
2098 mfrom.setStart(range[0]);
2099 mfrom.setEnd(range[1]);
2100 mp.addMapListFrom(mfrom);
2102 r = mlst.getToRanges();
2103 for (int[] range : r)
2105 MapListTo mto = new MapListTo();
2106 mto.setStart(range[0]);
2107 mto.setEnd(range[1]);
2108 mp.addMapListTo(mto);
2110 mp.setMapFromUnit(mlst.getFromRatio());
2111 mp.setMapToUnit(mlst.getToRatio());
2112 if (jmp.getTo() != null)
2114 MappingChoice mpc = new MappingChoice();
2116 // check/create ID for the sequence referenced by getTo()
2119 SequenceI ps = null;
2120 if (parentseq != jmp.getTo()
2121 && parentseq.getDatasetSequence() != jmp.getTo())
2123 // chaining dbref rather than a handshaking one
2124 jmpid = seqHash(ps = jmp.getTo());
2128 jmpid = seqHash(ps = parentseq);
2130 mpc.setDseqFor(jmpid);
2131 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2133 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2134 seqRefIds.put(mpc.getDseqFor(), ps);
2138 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2141 mp.setMappingChoice(mpc);
2147 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2148 List<UserColourScheme> userColours, JalviewModelSequence jms)
2151 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2152 boolean newucs = false;
2153 if (!userColours.contains(ucs))
2155 userColours.add(ucs);
2158 id = "ucs" + userColours.indexOf(ucs);
2161 // actually create the scheme's entry in the XML model
2162 java.awt.Color[] colours = ucs.getColours();
2163 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2164 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2166 for (int i = 0; i < colours.length; i++)
2168 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2169 col.setName(ResidueProperties.aa[i]);
2170 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2171 jbucs.addColour(col);
2173 if (ucs.getLowerCaseColours() != null)
2175 colours = ucs.getLowerCaseColours();
2176 for (int i = 0; i < colours.length; i++)
2178 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2179 col.setName(ResidueProperties.aa[i].toLowerCase());
2180 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2181 jbucs.addColour(col);
2186 uc.setUserColourScheme(jbucs);
2187 jms.addUserColours(uc);
2193 jalview.schemes.UserColourScheme getUserColourScheme(
2194 JalviewModelSequence jms, String id)
2196 UserColours[] uc = jms.getUserColours();
2197 UserColours colours = null;
2199 for (int i = 0; i < uc.length; i++)
2201 if (uc[i].getId().equals(id))
2209 java.awt.Color[] newColours = new java.awt.Color[24];
2211 for (int i = 0; i < 24; i++)
2213 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2214 .getUserColourScheme().getColour(i).getRGB(), 16));
2217 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2220 if (colours.getUserColourScheme().getColourCount() > 24)
2222 newColours = new java.awt.Color[23];
2223 for (int i = 0; i < 23; i++)
2225 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2226 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2228 ucs.setLowerCaseColours(newColours);
2235 * contains last error message (if any) encountered by XML loader.
2237 String errorMessage = null;
2240 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2241 * exceptions are raised during project XML parsing
2243 public boolean attemptversion1parse = true;
2246 * Load a jalview project archive from a jar file
2249 * - HTTP URL or filename
2251 public AlignFrame loadJalviewAlign(final String file)
2254 jalview.gui.AlignFrame af = null;
2258 // create list to store references for any new Jmol viewers created
2259 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2260 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2261 // Workaround is to make sure caller implements the JarInputStreamProvider
2263 // so we can re-open the jar input stream for each entry.
2265 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2266 af = loadJalviewAlign(jprovider);
2268 } catch (MalformedURLException e)
2270 errorMessage = "Invalid URL format for '" + file + "'";
2276 SwingUtilities.invokeAndWait(new Runnable()
2281 setLoadingFinishedForNewStructureViewers();
2284 } catch (Exception x)
2286 System.err.println("Error loading alignment: " + x.getMessage());
2292 private jarInputStreamProvider createjarInputStreamProvider(
2293 final String file) throws MalformedURLException
2296 errorMessage = null;
2297 uniqueSetSuffix = null;
2299 viewportsAdded.clear();
2300 frefedSequence = null;
2302 if (file.startsWith("http://"))
2304 url = new URL(file);
2306 final URL _url = url;
2307 return new jarInputStreamProvider()
2311 public JarInputStream getJarInputStream() throws IOException
2315 return new JarInputStream(_url.openStream());
2319 return new JarInputStream(new FileInputStream(file));
2324 public String getFilename()
2332 * Recover jalview session from a jalview project archive. Caller may
2333 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2334 * themselves. Any null fields will be initialised with default values,
2335 * non-null fields are left alone.
2340 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2342 errorMessage = null;
2343 if (uniqueSetSuffix == null)
2345 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2347 if (seqRefIds == null)
2351 AlignFrame af = null, _af = null;
2352 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2353 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2354 final String file = jprovider.getFilename();
2357 JarInputStream jin = null;
2358 JarEntry jarentry = null;
2363 jin = jprovider.getJarInputStream();
2364 for (int i = 0; i < entryCount; i++)
2366 jarentry = jin.getNextJarEntry();
2369 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2371 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2372 JalviewModel object = new JalviewModel();
2374 Unmarshaller unmar = new Unmarshaller(object);
2375 unmar.setValidation(false);
2376 object = (JalviewModel) unmar.unmarshal(in);
2377 if (true) // !skipViewport(object))
2379 _af = loadFromObject(object, file, true, jprovider);
2381 && object.getJalviewModelSequence().getViewportCount() > 0)
2385 // store a reference to the first view
2388 if (_af.viewport.isGatherViewsHere())
2390 // if this is a gathered view, keep its reference since
2391 // after gathering views, only this frame will remain
2393 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2395 // Save dataset to register mappings once all resolved
2396 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2397 af.viewport.getAlignment().getDataset());
2402 else if (jarentry != null)
2404 // Some other file here.
2407 } while (jarentry != null);
2408 resolveFrefedSequences();
2409 } catch (IOException ex)
2411 ex.printStackTrace();
2412 errorMessage = "Couldn't locate Jalview XML file : " + file;
2413 System.err.println("Exception whilst loading jalview XML file : "
2415 } catch (Exception ex)
2417 System.err.println("Parsing as Jalview Version 2 file failed.");
2418 ex.printStackTrace(System.err);
2419 if (attemptversion1parse)
2421 // Is Version 1 Jar file?
2424 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2425 } catch (Exception ex2)
2427 System.err.println("Exception whilst loading as jalviewXMLV1:");
2428 ex2.printStackTrace();
2432 if (Desktop.instance != null)
2434 Desktop.instance.stopLoading();
2438 System.out.println("Successfully loaded archive file");
2441 ex.printStackTrace();
2443 System.err.println("Exception whilst loading jalview XML file : "
2445 } catch (OutOfMemoryError e)
2447 // Don't use the OOM Window here
2448 errorMessage = "Out of memory loading jalview XML file";
2449 System.err.println("Out of memory whilst loading jalview XML file");
2450 e.printStackTrace();
2454 * Regather multiple views (with the same sequence set id) to the frame (if
2455 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2456 * views instead of separate frames. Note this doesn't restore a state where
2457 * some expanded views in turn have tabbed views - the last "first tab" read
2458 * in will play the role of gatherer for all.
2460 for (AlignFrame fr : gatherToThisFrame.values())
2462 Desktop.instance.gatherViews(fr);
2465 restoreSplitFrames();
2466 for (AlignmentI ds : importedDatasets.keySet())
2468 if (ds.getCodonFrames() != null)
2470 StructureSelectionManager.getStructureSelectionManager(
2471 Desktop.instance).registerMappings(ds.getCodonFrames());
2474 if (errorMessage != null)
2479 if (Desktop.instance != null)
2481 Desktop.instance.stopLoading();
2488 * Try to reconstruct and display SplitFrame windows, where each contains
2489 * complementary dna and protein alignments. Done by pairing up AlignFrame
2490 * objects (created earlier) which have complementary viewport ids associated.
2492 protected void restoreSplitFrames()
2494 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2495 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2496 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2499 * Identify the DNA alignments
2501 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2504 AlignFrame af = candidate.getValue();
2505 if (af.getViewport().getAlignment().isNucleotide())
2507 dna.put(candidate.getKey().getId(), af);
2512 * Try to match up the protein complements
2514 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2517 AlignFrame af = candidate.getValue();
2518 if (!af.getViewport().getAlignment().isNucleotide())
2520 String complementId = candidate.getKey().getComplementId();
2521 // only non-null complements should be in the Map
2522 if (complementId != null && dna.containsKey(complementId))
2524 final AlignFrame dnaFrame = dna.get(complementId);
2525 SplitFrame sf = createSplitFrame(dnaFrame, af);
2526 addedToSplitFrames.add(dnaFrame);
2527 addedToSplitFrames.add(af);
2528 if (af.viewport.isGatherViewsHere())
2537 * Open any that we failed to pair up (which shouldn't happen!) as
2538 * standalone AlignFrame's.
2540 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2543 AlignFrame af = candidate.getValue();
2544 if (!addedToSplitFrames.contains(af))
2546 Viewport view = candidate.getKey();
2547 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2549 System.err.println("Failed to restore view " + view.getTitle()
2550 + " to split frame");
2555 * Gather back into tabbed views as flagged.
2557 for (SplitFrame sf : gatherTo)
2559 Desktop.instance.gatherViews(sf);
2562 splitFrameCandidates.clear();
2566 * Construct and display one SplitFrame holding DNA and protein alignments.
2569 * @param proteinFrame
2572 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2573 AlignFrame proteinFrame)
2575 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2576 String title = MessageManager.getString("label.linked_view_title");
2577 int width = (int) dnaFrame.getBounds().getWidth();
2578 int height = (int) (dnaFrame.getBounds().getHeight()
2579 + proteinFrame.getBounds().getHeight() + 50);
2582 * SplitFrame location is saved to both enclosed frames
2584 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2585 Desktop.addInternalFrame(splitFrame, title, width, height);
2588 * And compute cDNA consensus (couldn't do earlier with consensus as
2589 * mappings were not yet present)
2591 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2597 * check errorMessage for a valid error message and raise an error box in the
2598 * GUI or write the current errorMessage to stderr and then clear the error
2601 protected void reportErrors()
2603 reportErrors(false);
2606 protected void reportErrors(final boolean saving)
2608 if (errorMessage != null)
2610 final String finalErrorMessage = errorMessage;
2613 javax.swing.SwingUtilities.invokeLater(new Runnable()
2618 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2619 finalErrorMessage, "Error "
2620 + (saving ? "saving" : "loading")
2621 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2627 System.err.println("Problem loading Jalview file: " + errorMessage);
2630 errorMessage = null;
2633 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2636 * when set, local views will be updated from view stored in JalviewXML
2637 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2638 * sync if this is set to true.
2640 private final boolean updateLocalViews = false;
2643 * Returns the path to a temporary file holding the PDB file for the given PDB
2644 * id. The first time of asking, searches for a file of that name in the
2645 * Jalview project jar, and copies it to a new temporary file. Any repeat
2646 * requests just return the path to the file previously created.
2652 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2654 if (alreadyLoadedPDB.containsKey(pdbId))
2656 return alreadyLoadedPDB.get(pdbId).toString();
2659 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2660 if (tempFile != null)
2662 alreadyLoadedPDB.put(pdbId, tempFile);
2668 * Copies the jar entry of given name to a new temporary file and returns the
2669 * path to the file, or null if the entry is not found.
2672 * @param jarEntryName
2674 * a prefix for the temporary file name, must be at least three
2678 protected String copyJarEntry(jarInputStreamProvider jprovider,
2679 String jarEntryName, String prefix)
2681 BufferedReader in = null;
2682 PrintWriter out = null;
2686 JarInputStream jin = jprovider.getJarInputStream();
2688 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2689 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2690 * FileInputStream(jprovider)); }
2693 JarEntry entry = null;
2696 entry = jin.getNextJarEntry();
2697 } while (entry != null && !entry.getName().equals(jarEntryName));
2700 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2701 File outFile = File.createTempFile(prefix, ".tmp");
2702 outFile.deleteOnExit();
2703 out = new PrintWriter(new FileOutputStream(outFile));
2706 while ((data = in.readLine()) != null)
2711 String t = outFile.getAbsolutePath();
2716 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2718 } catch (Exception ex)
2720 ex.printStackTrace();
2728 } catch (IOException e)
2742 private class JvAnnotRow
2744 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2751 * persisted version of annotation row from which to take vis properties
2753 public jalview.datamodel.AlignmentAnnotation template;
2756 * original position of the annotation row in the alignment
2762 * Load alignment frame from jalview XML DOM object
2767 * filename source string
2768 * @param loadTreesAndStructures
2769 * when false only create Viewport
2771 * data source provider
2772 * @return alignment frame created from view stored in DOM
2774 AlignFrame loadFromObject(JalviewModel object, String file,
2775 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2777 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2778 Sequence[] vamsasSeq = vamsasSet.getSequence();
2780 JalviewModelSequence jms = object.getJalviewModelSequence();
2782 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2785 // ////////////////////////////////
2788 List<SequenceI> hiddenSeqs = null;
2791 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2793 boolean multipleView = false;
2794 SequenceI referenceseqForView = null;
2795 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2796 int vi = 0; // counter in vamsasSeq array
2797 for (int i = 0; i < jseqs.length; i++)
2799 String seqId = jseqs[i].getId();
2801 SequenceI tmpSeq = seqRefIds.get(seqId);
2804 if (!incompleteSeqs.containsKey(seqId))
2806 // may not need this check, but keep it for at least 2.9,1 release
2807 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2810 .println("Warning JAL-2154 regression: updating start/end for sequence "
2811 + tmpSeq.toString());
2814 incompleteSeqs.remove(seqId);
2816 tmpSeq.setStart(jseqs[i].getStart());
2817 tmpSeq.setEnd(jseqs[i].getEnd());
2818 tmpseqs.add(tmpSeq);
2819 multipleView = true;
2823 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2824 vamsasSeq[vi].getSequence());
2825 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2826 tmpSeq.setStart(jseqs[i].getStart());
2827 tmpSeq.setEnd(jseqs[i].getEnd());
2828 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2829 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2830 tmpseqs.add(tmpSeq);
2834 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2836 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2839 if (jseqs[i].getHidden())
2841 if (hiddenSeqs == null)
2843 hiddenSeqs = new ArrayList<SequenceI>();
2846 hiddenSeqs.add(tmpSeq);
2851 // Create the alignment object from the sequence set
2852 // ///////////////////////////////
2853 SequenceI[] orderedSeqs = tmpseqs
2854 .toArray(new SequenceI[tmpseqs.size()]);
2856 AlignmentI al = null;
2857 // so we must create or recover the dataset alignment before going further
2858 // ///////////////////////////////
2859 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2861 // older jalview projects do not have a dataset - so creat alignment and
2863 al = new Alignment(orderedSeqs);
2864 al.setDataset(null);
2868 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2871 // we are importing a dataset record, so
2872 // recover reference to an alignment already materialsed as dataset
2873 al = getDatasetFor(vamsasSet.getDatasetId());
2877 // materialse the alignment
2878 al = new Alignment(orderedSeqs);
2882 addDatasetRef(vamsasSet.getDatasetId(), al);
2885 // finally, verify all data in vamsasSet is actually present in al
2886 // passing on flag indicating if it is actually a stored dataset
2887 recoverDatasetFor(vamsasSet, al, isdsal);
2890 if (referenceseqForView != null)
2892 al.setSeqrep(referenceseqForView);
2894 // / Add the alignment properties
2895 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2897 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2898 al.setProperty(ssp.getKey(), ssp.getValue());
2901 // ///////////////////////////////
2903 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2906 // load sequence features, database references and any associated PDB
2907 // structures for the alignment
2908 for (int i = 0; i < vamsasSeq.length; i++)
2910 if (jseqs[i].getFeaturesCount() > 0)
2912 Features[] features = jseqs[i].getFeatures();
2913 for (int f = 0; f < features.length; f++)
2915 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2916 features[f].getType(), features[f].getDescription(),
2917 features[f].getStatus(), features[f].getBegin(),
2918 features[f].getEnd(), features[f].getFeatureGroup());
2920 sf.setScore(features[f].getScore());
2921 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2923 OtherData keyValue = features[f].getOtherData(od);
2924 if (keyValue.getKey().startsWith("LINK"))
2926 sf.addLink(keyValue.getValue());
2930 sf.setValue(keyValue.getKey(), keyValue.getValue());
2935 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2938 if (vamsasSeq[i].getDBRefCount() > 0)
2940 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2942 if (jseqs[i].getPdbidsCount() > 0)
2944 Pdbids[] ids = jseqs[i].getPdbids();
2945 for (int p = 0; p < ids.length; p++)
2947 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2948 entry.setId(ids[p].getId());
2949 if (ids[p].getType() != null)
2951 if (ids[p].getType().equalsIgnoreCase("PDB"))
2953 entry.setType(PDBEntry.Type.PDB);
2957 entry.setType(PDBEntry.Type.FILE);
2960 if (ids[p].getFile() != null)
2962 if (!pdbloaded.containsKey(ids[p].getFile()))
2964 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2968 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2971 StructureSelectionManager.getStructureSelectionManager(
2972 Desktop.instance).registerPDBEntry(entry);
2973 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2977 } // end !multipleview
2979 // ///////////////////////////////
2980 // LOAD SEQUENCE MAPPINGS
2982 if (vamsasSet.getAlcodonFrameCount() > 0)
2984 // TODO Potentially this should only be done once for all views of an
2986 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2987 for (int i = 0; i < alc.length; i++)
2989 AlignedCodonFrame cf = new AlignedCodonFrame();
2990 if (alc[i].getAlcodMapCount() > 0)
2992 AlcodMap[] maps = alc[i].getAlcodMap();
2993 for (int m = 0; m < maps.length; m++)
2995 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2997 jalview.datamodel.Mapping mapping = null;
2998 // attach to dna sequence reference.
2999 if (maps[m].getMapping() != null)
3001 mapping = addMapping(maps[m].getMapping());
3003 if (dnaseq != null && mapping.getTo() != null)
3005 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3010 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3014 al.addCodonFrame(cf);
3019 // ////////////////////////////////
3021 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3024 * store any annotations which forward reference a group's ID
3026 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3028 if (vamsasSet.getAnnotationCount() > 0)
3030 Annotation[] an = vamsasSet.getAnnotation();
3032 for (int i = 0; i < an.length; i++)
3034 Annotation annotation = an[i];
3037 * test if annotation is automatically calculated for this view only
3039 boolean autoForView = false;
3040 if (annotation.getLabel().equals("Quality")
3041 || annotation.getLabel().equals("Conservation")
3042 || annotation.getLabel().equals("Consensus"))
3044 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3046 if (!annotation.hasAutoCalculated())
3048 annotation.setAutoCalculated(true);
3052 || (annotation.hasAutoCalculated() && annotation
3053 .isAutoCalculated()))
3055 // remove ID - we don't recover annotation from other views for
3056 // view-specific annotation
3057 annotation.setId(null);
3060 // set visiblity for other annotation in this view
3061 String annotationId = annotation.getId();
3062 if (annotationId != null && annotationIds.containsKey(annotationId))
3064 AlignmentAnnotation jda = annotationIds.get(annotationId);
3065 // in principle Visible should always be true for annotation displayed
3066 // in multiple views
3067 if (annotation.hasVisible())
3069 jda.visible = annotation.getVisible();
3072 al.addAnnotation(jda);
3076 // Construct new annotation from model.
3077 AnnotationElement[] ae = annotation.getAnnotationElement();
3078 jalview.datamodel.Annotation[] anot = null;
3079 java.awt.Color firstColour = null;
3081 if (!annotation.getScoreOnly())
3083 anot = new jalview.datamodel.Annotation[al.getWidth()];
3084 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3086 anpos = ae[aa].getPosition();
3088 if (anpos >= anot.length)
3093 anot[anpos] = new jalview.datamodel.Annotation(
3095 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3096 (ae[aa].getSecondaryStructure() == null || ae[aa]
3097 .getSecondaryStructure().length() == 0) ? ' '
3098 : ae[aa].getSecondaryStructure().charAt(0),
3102 // JBPNote: Consider verifying dataflow for IO of secondary
3103 // structure annotation read from Stockholm files
3104 // this was added to try to ensure that
3105 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3107 // anot[ae[aa].getPosition()].displayCharacter = "";
3109 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3110 if (firstColour == null)
3112 firstColour = anot[anpos].colour;
3116 jalview.datamodel.AlignmentAnnotation jaa = null;
3118 if (annotation.getGraph())
3120 float llim = 0, hlim = 0;
3121 // if (autoForView || an[i].isAutoCalculated()) {
3124 jaa = new jalview.datamodel.AlignmentAnnotation(
3125 annotation.getLabel(), annotation.getDescription(), anot,
3126 llim, hlim, annotation.getGraphType());
3128 jaa.graphGroup = annotation.getGraphGroup();
3129 jaa._linecolour = firstColour;
3130 if (annotation.getThresholdLine() != null)
3132 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3133 .getThresholdLine().getValue(), annotation
3134 .getThresholdLine().getLabel(), new java.awt.Color(
3135 annotation.getThresholdLine().getColour())));
3138 if (autoForView || annotation.isAutoCalculated())
3140 // Hardwire the symbol display line to ensure that labels for
3141 // histograms are displayed
3147 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3148 an[i].getDescription(), anot);
3149 jaa._linecolour = firstColour;
3151 // register new annotation
3152 if (an[i].getId() != null)
3154 annotationIds.put(an[i].getId(), jaa);
3155 jaa.annotationId = an[i].getId();
3157 // recover sequence association
3158 String sequenceRef = an[i].getSequenceRef();
3159 if (sequenceRef != null)
3161 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3162 SequenceI sequence = seqRefIds.get(sequenceRef);
3163 if (sequence == null)
3165 // in pre-2.9 projects sequence ref is to sequence name
3166 sequence = al.findName(sequenceRef);
3168 if (sequence != null)
3170 jaa.createSequenceMapping(sequence, 1, true);
3171 sequence.addAlignmentAnnotation(jaa);
3174 // and make a note of any group association
3175 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3177 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3178 .get(an[i].getGroupRef());
3181 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3182 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3187 if (an[i].hasScore())
3189 jaa.setScore(an[i].getScore());
3191 if (an[i].hasVisible())
3193 jaa.visible = an[i].getVisible();
3196 if (an[i].hasCentreColLabels())
3198 jaa.centreColLabels = an[i].getCentreColLabels();
3201 if (an[i].hasScaleColLabels())
3203 jaa.scaleColLabel = an[i].getScaleColLabels();
3205 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3207 // newer files have an 'autoCalculated' flag and store calculation
3208 // state in viewport properties
3209 jaa.autoCalculated = true; // means annotation will be marked for
3210 // update at end of load.
3212 if (an[i].hasGraphHeight())
3214 jaa.graphHeight = an[i].getGraphHeight();
3216 if (an[i].hasBelowAlignment())
3218 jaa.belowAlignment = an[i].isBelowAlignment();
3220 jaa.setCalcId(an[i].getCalcId());
3221 if (an[i].getPropertyCount() > 0)
3223 for (jalview.schemabinding.version2.Property prop : an[i]
3226 jaa.setProperty(prop.getName(), prop.getValue());
3229 if (jaa.autoCalculated)
3231 autoAlan.add(new JvAnnotRow(i, jaa));
3234 // if (!autoForView)
3236 // add autocalculated group annotation and any user created annotation
3238 al.addAnnotation(jaa);
3242 // ///////////////////////
3244 // Create alignment markup and styles for this view
3245 if (jms.getJGroupCount() > 0)
3247 JGroup[] groups = jms.getJGroup();
3248 boolean addAnnotSchemeGroup = false;
3249 for (int i = 0; i < groups.length; i++)
3251 JGroup jGroup = groups[i];
3252 ColourSchemeI cs = null;
3253 if (jGroup.getColour() != null)
3255 if (jGroup.getColour().startsWith("ucs"))
3257 cs = getUserColourScheme(jms, jGroup.getColour());
3259 else if (jGroup.getColour().equals("AnnotationColourGradient")
3260 && jGroup.getAnnotationColours() != null)
3262 addAnnotSchemeGroup = true;
3267 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3272 cs.setThreshold(jGroup.getPidThreshold(), true);
3276 Vector<SequenceI> seqs = new Vector<SequenceI>();
3278 for (int s = 0; s < jGroup.getSeqCount(); s++)
3280 String seqId = jGroup.getSeq(s) + "";
3281 SequenceI ts = seqRefIds.get(seqId);
3285 seqs.addElement(ts);
3289 if (seqs.size() < 1)
3294 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3295 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3296 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3298 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3300 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3301 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3302 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3303 .isShowUnconserved() : false);
3304 sg.thresholdTextColour = jGroup.getTextColThreshold();
3305 if (jGroup.hasShowConsensusHistogram())
3307 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3310 if (jGroup.hasShowSequenceLogo())
3312 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3314 if (jGroup.hasNormaliseSequenceLogo())
3316 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3318 if (jGroup.hasIgnoreGapsinConsensus())
3320 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3322 if (jGroup.getConsThreshold() != 0)
3324 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3325 "All", ResidueProperties.propHash, 3,
3326 sg.getSequences(null), 0, sg.getWidth() - 1);
3328 c.verdict(false, 25);
3329 sg.cs.setConservation(c);
3332 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3334 // re-instate unique group/annotation row reference
3335 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3339 for (AlignmentAnnotation jaa : jaal)
3342 if (jaa.autoCalculated)
3344 // match up and try to set group autocalc alignment row for this
3346 if (jaa.label.startsWith("Consensus for "))
3348 sg.setConsensus(jaa);
3350 // match up and try to set group autocalc alignment row for this
3352 if (jaa.label.startsWith("Conservation for "))
3354 sg.setConservationRow(jaa);
3361 if (addAnnotSchemeGroup)
3363 // reconstruct the annotation colourscheme
3364 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3365 null, al, jms, false);
3371 // only dataset in this model, so just return.
3374 // ///////////////////////////////
3377 // If we just load in the same jar file again, the sequenceSetId
3378 // will be the same, and we end up with multiple references
3379 // to the same sequenceSet. We must modify this id on load
3380 // so that each load of the file gives a unique id
3381 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3382 String viewId = (view.getId() == null ? null : view.getId()
3384 AlignFrame af = null;
3385 AlignViewport av = null;
3386 // now check to see if we really need to create a new viewport.
3387 if (multipleView && viewportsAdded.size() == 0)
3389 // We recovered an alignment for which a viewport already exists.
3390 // TODO: fix up any settings necessary for overlaying stored state onto
3391 // state recovered from another document. (may not be necessary).
3392 // we may need a binding from a viewport in memory to one recovered from
3394 // and then recover its containing af to allow the settings to be applied.
3395 // TODO: fix for vamsas demo
3397 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3399 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3400 if (seqsetobj != null)
3402 if (seqsetobj instanceof String)
3404 uniqueSeqSetId = (String) seqsetobj;
3406 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3412 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3418 * indicate that annotation colours are applied across all groups (pre
3419 * Jalview 2.8.1 behaviour)
3421 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3422 "2.8.1", object.getVersion());
3424 AlignmentPanel ap = null;
3425 boolean isnewview = true;
3428 // Check to see if this alignment already has a view id == viewId
3429 jalview.gui.AlignmentPanel views[] = Desktop
3430 .getAlignmentPanels(uniqueSeqSetId);
3431 if (views != null && views.length > 0)
3433 for (int v = 0; v < views.length; v++)
3435 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3437 // recover the existing alignpanel, alignframe, viewport
3438 af = views[v].alignFrame;
3441 // TODO: could even skip resetting view settings if we don't want to
3442 // change the local settings from other jalview processes
3451 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3452 uniqueSeqSetId, viewId, autoAlan);
3458 * Load any trees, PDB structures and viewers
3460 * Not done if flag is false (when this method is used for New View)
3462 if (loadTreesAndStructures)
3464 loadTrees(jms, view, af, av, ap);
3465 loadPDBStructures(jprovider, jseqs, af, ap);
3466 loadRnaViewers(jprovider, jseqs, ap);
3468 // and finally return.
3473 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3474 * panel is restored from separate jar entries, two (gapped and trimmed) per
3475 * sequence and secondary structure.
3477 * Currently each viewer shows just one sequence and structure (gapped and
3478 * trimmed), however this method is designed to support multiple sequences or
3479 * structures in viewers if wanted in future.
3485 private void loadRnaViewers(jarInputStreamProvider jprovider,
3486 JSeq[] jseqs, AlignmentPanel ap)
3489 * scan the sequences for references to viewers; create each one the first
3490 * time it is referenced, add Rna models to existing viewers
3492 for (JSeq jseq : jseqs)
3494 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3496 RnaViewer viewer = jseq.getRnaViewer(i);
3497 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3498 uniqueSetSuffix, ap);
3500 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3502 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3503 SequenceI seq = seqRefIds.get(jseq.getId());
3504 AlignmentAnnotation ann = this.annotationIds.get(ss
3505 .getAnnotationId());
3508 * add the structure to the Varna display (with session state copied
3509 * from the jar to a temporary file)
3511 boolean gapped = ss.isGapped();
3512 String rnaTitle = ss.getTitle();
3513 String sessionState = ss.getViewerState();
3514 String tempStateFile = copyJarEntry(jprovider, sessionState,
3516 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3517 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3519 appVarna.setInitialSelection(viewer.getSelectedRna());
3525 * Locate and return an already instantiated matching AppVarna, or create one
3529 * @param viewIdSuffix
3533 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3534 String viewIdSuffix, AlignmentPanel ap)
3537 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3538 * if load is repeated
3540 String postLoadId = viewer.getViewId() + viewIdSuffix;
3541 for (JInternalFrame frame : getAllFrames())
3543 if (frame instanceof AppVarna)
3545 AppVarna varna = (AppVarna) frame;
3546 if (postLoadId.equals(varna.getViewId()))
3548 // this viewer is already instantiated
3549 // could in future here add ap as another 'parent' of the
3550 // AppVarna window; currently just 1-to-many
3557 * viewer not found - make it
3559 RnaViewerModel model = new RnaViewerModel(postLoadId,
3560 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3561 viewer.getWidth(), viewer.getHeight(),
3562 viewer.getDividerLocation());
3563 AppVarna varna = new AppVarna(model, ap);
3569 * Load any saved trees
3577 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3578 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3580 // TODO result of automated refactoring - are all these parameters needed?
3583 for (int t = 0; t < jms.getTreeCount(); t++)
3586 Tree tree = jms.getTree(t);
3588 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3591 tp = af.ShowNewickTree(
3592 new jalview.io.NewickFile(tree.getNewick()),
3593 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3594 tree.getXpos(), tree.getYpos());
3595 if (tree.getId() != null)
3597 // perhaps bind the tree id to something ?
3602 // update local tree attributes ?
3603 // TODO: should check if tp has been manipulated by user - if so its
3604 // settings shouldn't be modified
3605 tp.setTitle(tree.getTitle());
3606 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3607 .getWidth(), tree.getHeight()));
3608 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3611 tp.treeCanvas.av = av; // af.viewport;
3612 tp.treeCanvas.ap = ap; // af.alignPanel;
3617 warn("There was a problem recovering stored Newick tree: \n"
3618 + tree.getNewick());
3622 tp.fitToWindow.setState(tree.getFitToWindow());
3623 tp.fitToWindow_actionPerformed(null);
3625 if (tree.getFontName() != null)
3627 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3628 .getFontStyle(), tree.getFontSize()));
3632 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3633 .getFontStyle(), tree.getFontSize()));
3636 tp.showPlaceholders(tree.getMarkUnlinked());
3637 tp.showBootstrap(tree.getShowBootstrap());
3638 tp.showDistances(tree.getShowDistances());
3640 tp.treeCanvas.threshold = tree.getThreshold();
3642 if (tree.getCurrentTree())
3644 af.viewport.setCurrentTree(tp.getTree());
3648 } catch (Exception ex)
3650 ex.printStackTrace();
3655 * Load and link any saved structure viewers.
3662 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3663 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3666 * Run through all PDB ids on the alignment, and collect mappings between
3667 * distinct view ids and all sequences referring to that view.
3669 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3671 for (int i = 0; i < jseqs.length; i++)
3673 if (jseqs[i].getPdbidsCount() > 0)
3675 Pdbids[] ids = jseqs[i].getPdbids();
3676 for (int p = 0; p < ids.length; p++)
3678 final int structureStateCount = ids[p].getStructureStateCount();
3679 for (int s = 0; s < structureStateCount; s++)
3681 // check to see if we haven't already created this structure view
3682 final StructureState structureState = ids[p]
3683 .getStructureState(s);
3684 String sviewid = (structureState.getViewId() == null) ? null
3685 : structureState.getViewId() + uniqueSetSuffix;
3686 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3687 // Originally : ids[p].getFile()
3688 // : TODO: verify external PDB file recovery still works in normal
3689 // jalview project load
3690 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3691 jpdb.setId(ids[p].getId());
3693 int x = structureState.getXpos();
3694 int y = structureState.getYpos();
3695 int width = structureState.getWidth();
3696 int height = structureState.getHeight();
3698 // Probably don't need to do this anymore...
3699 // Desktop.desktop.getComponentAt(x, y);
3700 // TODO: NOW: check that this recovers the PDB file correctly.
3701 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3702 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3704 if (sviewid == null)
3706 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3709 if (!structureViewers.containsKey(sviewid))
3711 structureViewers.put(sviewid,
3712 new StructureViewerModel(x, y, width, height, false,
3713 false, true, structureState.getViewId(),
3714 structureState.getType()));
3715 // Legacy pre-2.7 conversion JAL-823 :
3716 // do not assume any view has to be linked for colour by
3720 // assemble String[] { pdb files }, String[] { id for each
3721 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3722 // seqs_file 2}, boolean[] {
3723 // linkAlignPanel,superposeWithAlignpanel}} from hash
3724 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3725 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3726 | (structureState.hasAlignwithAlignPanel() ? structureState
3727 .getAlignwithAlignPanel() : false));
3730 * Default colour by linked panel to false if not specified (e.g.
3731 * for pre-2.7 projects)
3733 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3734 colourWithAlignPanel |= (structureState
3735 .hasColourwithAlignPanel() ? structureState
3736 .getColourwithAlignPanel() : false);
3737 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3740 * Default colour by viewer to true if not specified (e.g. for
3743 boolean colourByViewer = jmoldat.isColourByViewer();
3744 colourByViewer &= structureState.hasColourByJmol() ? structureState
3745 .getColourByJmol() : true;
3746 jmoldat.setColourByViewer(colourByViewer);
3748 if (jmoldat.getStateData().length() < structureState
3749 .getContent().length())
3752 jmoldat.setStateData(structureState.getContent());
3755 if (ids[p].getFile() != null)
3757 File mapkey = new File(ids[p].getFile());
3758 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3759 if (seqstrmaps == null)
3761 jmoldat.getFileData().put(
3763 seqstrmaps = jmoldat.new StructureData(pdbFile,
3766 if (!seqstrmaps.getSeqList().contains(seq))
3768 seqstrmaps.getSeqList().add(seq);
3774 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");
3781 // Instantiate the associated structure views
3782 for (Entry<String, StructureViewerModel> entry : structureViewers
3787 createOrLinkStructureViewer(entry, af, ap, jprovider);
3788 } catch (Exception e)
3790 System.err.println("Error loading structure viewer: "
3792 // failed - try the next one
3804 protected void createOrLinkStructureViewer(
3805 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3806 AlignmentPanel ap, jarInputStreamProvider jprovider)
3808 final StructureViewerModel stateData = viewerData.getValue();
3811 * Search for any viewer windows already open from other alignment views
3812 * that exactly match the stored structure state
3814 StructureViewerBase comp = findMatchingViewer(viewerData);
3818 linkStructureViewer(ap, comp, stateData);
3823 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3824 * "viewer_"+stateData.viewId
3826 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3828 createChimeraViewer(viewerData, af, jprovider);
3833 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3835 createJmolViewer(viewerData, af, jprovider);
3840 * Create a new Chimera viewer.
3846 protected void createChimeraViewer(
3847 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3848 jarInputStreamProvider jprovider)
3850 StructureViewerModel data = viewerData.getValue();
3851 String chimeraSessionFile = data.getStateData();
3854 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3856 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3857 * 'uniquified' sviewid used to reconstruct the viewer here
3859 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3860 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3863 Set<Entry<File, StructureData>> fileData = data.getFileData()
3865 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3866 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3867 for (Entry<File, StructureData> pdb : fileData)
3869 String filePath = pdb.getValue().getFilePath();
3870 String pdbId = pdb.getValue().getPdbId();
3871 // pdbs.add(new PDBEntry(filePath, pdbId));
3872 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3873 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3874 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3878 boolean colourByChimera = data.isColourByViewer();
3879 boolean colourBySequence = data.isColourWithAlignPanel();
3881 // TODO use StructureViewer as a factory here, see JAL-1761
3882 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3883 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3885 String newViewId = viewerData.getKey();
3887 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3888 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3889 colourBySequence, newViewId);
3890 cvf.setSize(data.getWidth(), data.getHeight());
3891 cvf.setLocation(data.getX(), data.getY());
3895 * Create a new Jmol window. First parse the Jmol state to translate filenames
3896 * loaded into the view, and record the order in which files are shown in the
3897 * Jmol view, so we can add the sequence mappings in same order.
3903 protected void createJmolViewer(
3904 final Entry<String, StructureViewerModel> viewerData,
3905 AlignFrame af, jarInputStreamProvider jprovider)
3907 final StructureViewerModel svattrib = viewerData.getValue();
3908 String state = svattrib.getStateData();
3911 * Pre-2.9: state element value is the Jmol state string
3913 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3916 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3918 state = readJarEntry(jprovider,
3919 getViewerJarEntryName(svattrib.getViewId()));
3922 List<String> pdbfilenames = new ArrayList<String>();
3923 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3924 List<String> pdbids = new ArrayList<String>();
3925 StringBuilder newFileLoc = new StringBuilder(64);
3926 int cp = 0, ncp, ecp;
3927 Map<File, StructureData> oldFiles = svattrib.getFileData();
3928 while ((ncp = state.indexOf("load ", cp)) > -1)
3932 // look for next filename in load statement
3933 newFileLoc.append(state.substring(cp,
3934 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3935 String oldfilenam = state.substring(ncp,
3936 ecp = state.indexOf("\"", ncp));
3937 // recover the new mapping data for this old filename
3938 // have to normalize filename - since Jmol and jalview do
3940 // translation differently.
3941 StructureData filedat = oldFiles.get(new File(oldfilenam));
3942 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3943 pdbfilenames.add(filedat.getFilePath());
3944 pdbids.add(filedat.getPdbId());
3945 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3946 newFileLoc.append("\"");
3947 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3948 // look for next file statement.
3949 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3953 // just append rest of state
3954 newFileLoc.append(state.substring(cp));
3958 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3959 newFileLoc = new StringBuilder(state);
3960 newFileLoc.append("; load append ");
3961 for (File id : oldFiles.keySet())
3963 // add this and any other pdb files that should be present in
3965 StructureData filedat = oldFiles.get(id);
3966 newFileLoc.append(filedat.getFilePath());
3967 pdbfilenames.add(filedat.getFilePath());
3968 pdbids.add(filedat.getPdbId());
3969 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3970 newFileLoc.append(" \"");
3971 newFileLoc.append(filedat.getFilePath());
3972 newFileLoc.append("\"");
3975 newFileLoc.append(";");
3978 if (newFileLoc.length() == 0)
3982 int histbug = newFileLoc.indexOf("history = ");
3986 * change "history = [true|false];" to "history = [1|0];"
3989 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3990 String val = (diff == -1) ? null : newFileLoc
3991 .substring(histbug, diff);
3992 if (val != null && val.length() >= 4)
3994 if (val.contains("e")) // eh? what can it be?
3996 if (val.trim().equals("true"))
4004 newFileLoc.replace(histbug, diff, val);
4009 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4011 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4012 final SequenceI[][] sq = seqmaps
4013 .toArray(new SequenceI[seqmaps.size()][]);
4014 final String fileloc = newFileLoc.toString();
4015 final String sviewid = viewerData.getKey();
4016 final AlignFrame alf = af;
4017 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4018 svattrib.getWidth(), svattrib.getHeight());
4021 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4026 JalviewStructureDisplayI sview = null;
4029 sview = new StructureViewer(alf.alignPanel
4030 .getStructureSelectionManager()).createView(
4031 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4032 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4033 addNewStructureViewer(sview);
4034 } catch (OutOfMemoryError ex)
4036 new OOMWarning("restoring structure view for PDB id " + id,
4037 (OutOfMemoryError) ex.getCause());
4038 if (sview != null && sview.isVisible())
4040 sview.closeViewer(false);
4041 sview.setVisible(false);
4047 } catch (InvocationTargetException ex)
4049 warn("Unexpected error when opening Jmol view.", ex);
4051 } catch (InterruptedException e)
4053 // e.printStackTrace();
4059 * Generates a name for the entry in the project jar file to hold state
4060 * information for a structure viewer
4065 protected String getViewerJarEntryName(String viewId)
4067 return VIEWER_PREFIX + viewId;
4071 * Returns any open frame that matches given structure viewer data. The match
4072 * is based on the unique viewId, or (for older project versions) the frame's
4078 protected StructureViewerBase findMatchingViewer(
4079 Entry<String, StructureViewerModel> viewerData)
4081 final String sviewid = viewerData.getKey();
4082 final StructureViewerModel svattrib = viewerData.getValue();
4083 StructureViewerBase comp = null;
4084 JInternalFrame[] frames = getAllFrames();
4085 for (JInternalFrame frame : frames)
4087 if (frame instanceof StructureViewerBase)
4090 * Post jalview 2.4 schema includes structure view id
4093 && ((StructureViewerBase) frame).getViewId()
4096 comp = (StructureViewerBase) frame;
4097 break; // break added in 2.9
4100 * Otherwise test for matching position and size of viewer frame
4102 else if (frame.getX() == svattrib.getX()
4103 && frame.getY() == svattrib.getY()
4104 && frame.getHeight() == svattrib.getHeight()
4105 && frame.getWidth() == svattrib.getWidth())
4107 comp = (StructureViewerBase) frame;
4108 // no break in faint hope of an exact match on viewId
4116 * Link an AlignmentPanel to an existing structure viewer.
4121 * @param useinViewerSuperpos
4122 * @param usetoColourbyseq
4123 * @param viewerColouring
4125 protected void linkStructureViewer(AlignmentPanel ap,
4126 StructureViewerBase viewer, StructureViewerModel stateData)
4128 // NOTE: if the jalview project is part of a shared session then
4129 // view synchronization should/could be done here.
4131 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4132 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4133 final boolean viewerColouring = stateData.isColourByViewer();
4134 Map<File, StructureData> oldFiles = stateData.getFileData();
4137 * Add mapping for sequences in this view to an already open viewer
4139 final AAStructureBindingModel binding = viewer.getBinding();
4140 for (File id : oldFiles.keySet())
4142 // add this and any other pdb files that should be present in the
4144 StructureData filedat = oldFiles.get(id);
4145 String pdbFile = filedat.getFilePath();
4146 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4147 binding.getSsm().setMapping(seq, null, pdbFile,
4148 jalview.io.AppletFormatAdapter.FILE);
4149 binding.addSequenceForStructFile(pdbFile, seq);
4151 // and add the AlignmentPanel's reference to the view panel
4152 viewer.addAlignmentPanel(ap);
4153 if (useinViewerSuperpos)
4155 viewer.useAlignmentPanelForSuperposition(ap);
4159 viewer.excludeAlignmentPanelForSuperposition(ap);
4161 if (usetoColourbyseq)
4163 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4167 viewer.excludeAlignmentPanelForColourbyseq(ap);
4172 * Get all frames within the Desktop.
4176 protected JInternalFrame[] getAllFrames()
4178 JInternalFrame[] frames = null;
4179 // TODO is this necessary - is it safe - risk of hanging?
4184 frames = Desktop.desktop.getAllFrames();
4185 } catch (ArrayIndexOutOfBoundsException e)
4187 // occasional No such child exceptions are thrown here...
4191 } catch (InterruptedException f)
4195 } while (frames == null);
4200 * Answers true if 'version' is equal to or later than 'supported', where each
4201 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4202 * changes. Development and test values for 'version' are leniently treated
4206 * - minimum version we are comparing against
4208 * - version of data being processsed
4211 public static boolean isVersionStringLaterThan(String supported,
4214 if (supported == null || version == null
4215 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4216 || version.equalsIgnoreCase("Test")
4217 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4219 System.err.println("Assuming project file with "
4220 + (version == null ? "null" : version)
4221 + " is compatible with Jalview version " + supported);
4226 return StringUtils.compareVersions(version, supported, "b") >= 0;
4230 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4232 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4234 if (newStructureViewers != null)
4236 sview.getBinding().setFinishedLoadingFromArchive(false);
4237 newStructureViewers.add(sview);
4241 protected void setLoadingFinishedForNewStructureViewers()
4243 if (newStructureViewers != null)
4245 for (JalviewStructureDisplayI sview : newStructureViewers)
4247 sview.getBinding().setFinishedLoadingFromArchive(true);
4249 newStructureViewers.clear();
4250 newStructureViewers = null;
4254 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4255 List<SequenceI> hiddenSeqs, AlignmentI al,
4256 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4257 String viewId, List<JvAnnotRow> autoAlan)
4259 AlignFrame af = null;
4260 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4261 uniqueSeqSetId, viewId);
4263 af.setFileName(file, "Jalview");
4265 for (int i = 0; i < JSEQ.length; i++)
4267 af.viewport.setSequenceColour(af.viewport.getAlignment()
4268 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4273 af.getViewport().setColourByReferenceSeq(true);
4274 af.getViewport().setDisplayReferenceSeq(true);
4277 af.viewport.setGatherViewsHere(view.getGatheredViews());
4279 if (view.getSequenceSetId() != null)
4281 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4283 af.viewport.setSequenceSetId(uniqueSeqSetId);
4286 // propagate shared settings to this new view
4287 af.viewport.setHistoryList(av.getHistoryList());
4288 af.viewport.setRedoList(av.getRedoList());
4292 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4294 // TODO: check if this method can be called repeatedly without
4295 // side-effects if alignpanel already registered.
4296 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4298 // apply Hidden regions to view.
4299 if (hiddenSeqs != null)
4301 for (int s = 0; s < JSEQ.length; s++)
4303 SequenceGroup hidden = new SequenceGroup();
4304 boolean isRepresentative = false;
4305 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4307 isRepresentative = true;
4308 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4309 .getHiddenSequences(r));
4310 hidden.addSequence(sequenceToHide, false);
4311 // remove from hiddenSeqs list so we don't try to hide it twice
4312 hiddenSeqs.remove(sequenceToHide);
4314 if (isRepresentative)
4316 SequenceI representativeSequence = al.getSequenceAt(s);
4317 hidden.addSequence(representativeSequence, false);
4318 af.viewport.hideRepSequences(representativeSequence, hidden);
4322 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4324 af.viewport.hideSequence(hseqs);
4327 // recover view properties and display parameters
4328 if (view.getViewName() != null)
4330 af.viewport.viewName = view.getViewName();
4331 af.setInitialTabVisible();
4333 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4336 af.viewport.setShowAnnotation(view.getShowAnnotation());
4337 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4339 af.viewport.setColourText(view.getShowColourText());
4341 af.viewport.setConservationSelected(view.getConservationSelected());
4342 af.viewport.setShowJVSuffix(view.getShowFullId());
4343 af.viewport.setRightAlignIds(view.getRightAlignIds());
4344 af.viewport.setFont(
4345 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4346 .getFontSize()), true);
4347 ViewStyleI vs = af.viewport.getViewStyle();
4348 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4349 af.viewport.setViewStyle(vs);
4350 // TODO: allow custom charWidth/Heights to be restored by updating them
4351 // after setting font - which means set above to false
4352 af.viewport.setRenderGaps(view.getRenderGaps());
4353 af.viewport.setWrapAlignment(view.getWrapAlignment());
4354 af.viewport.setShowAnnotation(view.getShowAnnotation());
4356 af.viewport.setShowBoxes(view.getShowBoxes());
4358 af.viewport.setShowText(view.getShowText());
4360 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4361 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4362 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4363 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4364 .isShowUnconserved() : false);
4365 af.viewport.setStartRes(view.getStartRes());
4366 af.viewport.setStartSeq(view.getStartSeq());
4367 af.alignPanel.updateLayout();
4368 ColourSchemeI cs = null;
4369 // apply colourschemes
4370 if (view.getBgColour() != null)
4372 if (view.getBgColour().startsWith("ucs"))
4374 cs = getUserColourScheme(jms, view.getBgColour());
4376 else if (view.getBgColour().startsWith("Annotation"))
4378 AnnotationColours viewAnnColour = view.getAnnotationColours();
4379 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4386 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4391 cs.setThreshold(view.getPidThreshold(), true);
4392 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4396 af.viewport.setGlobalColourScheme(cs);
4397 af.viewport.setColourAppliesToAllGroups(false);
4399 if (view.getConservationSelected() && cs != null)
4401 cs.setConservationInc(view.getConsThreshold());
4404 af.changeColour(cs);
4406 af.viewport.setColourAppliesToAllGroups(true);
4408 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4410 if (view.hasCentreColumnLabels())
4412 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4414 if (view.hasIgnoreGapsinConsensus())
4416 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4419 if (view.hasFollowHighlight())
4421 af.viewport.setFollowHighlight(view.getFollowHighlight());
4423 if (view.hasFollowSelection())
4425 af.viewport.followSelection = view.getFollowSelection();
4427 if (view.hasShowConsensusHistogram())
4429 af.viewport.setShowConsensusHistogram(view
4430 .getShowConsensusHistogram());
4434 af.viewport.setShowConsensusHistogram(true);
4436 if (view.hasShowSequenceLogo())
4438 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4442 af.viewport.setShowSequenceLogo(false);
4444 if (view.hasNormaliseSequenceLogo())
4446 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4448 if (view.hasShowDbRefTooltip())
4450 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4452 if (view.hasShowNPfeatureTooltip())
4454 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4456 if (view.hasShowGroupConsensus())
4458 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4462 af.viewport.setShowGroupConsensus(false);
4464 if (view.hasShowGroupConservation())
4466 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4470 af.viewport.setShowGroupConservation(false);
4473 // recover featre settings
4474 if (jms.getFeatureSettings() != null)
4476 FeaturesDisplayed fdi;
4477 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4478 String[] renderOrder = new String[jms.getFeatureSettings()
4479 .getSettingCount()];
4480 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4481 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4483 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4485 Setting setting = jms.getFeatureSettings().getSetting(fs);
4486 if (setting.hasMincolour())
4488 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4489 new Color(setting.getMincolour()), new Color(
4490 setting.getColour()), setting.getMin(),
4491 setting.getMax()) : new FeatureColour(new Color(
4492 setting.getMincolour()), new Color(setting.getColour()),
4494 if (setting.hasThreshold())
4496 gc.setThreshold(setting.getThreshold());
4497 int threshstate = setting.getThreshstate();
4498 // -1 = None, 0 = Below, 1 = Above threshold
4499 if (threshstate == 0)
4501 gc.setBelowThreshold(true);
4503 else if (threshstate == 1)
4505 gc.setAboveThreshold(true);
4508 gc.setAutoScaled(true); // default
4509 if (setting.hasAutoScale())
4511 gc.setAutoScaled(setting.getAutoScale());
4513 if (setting.hasColourByLabel())
4515 gc.setColourByLabel(setting.getColourByLabel());
4517 // and put in the feature colour table.
4518 featureColours.put(setting.getType(), gc);
4522 featureColours.put(setting.getType(), new FeatureColour(
4523 new Color(setting.getColour())));
4525 renderOrder[fs] = setting.getType();
4526 if (setting.hasOrder())
4528 featureOrder.put(setting.getType(), setting.getOrder());
4532 featureOrder.put(setting.getType(), new Float(fs
4533 / jms.getFeatureSettings().getSettingCount()));
4535 if (setting.getDisplay())
4537 fdi.setVisible(setting.getType());
4540 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4541 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4543 Group grp = jms.getFeatureSettings().getGroup(gs);
4544 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4546 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4547 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4548 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4549 FeatureRendererSettings frs = new FeatureRendererSettings(
4550 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4551 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4552 .transferSettings(frs);
4556 if (view.getHiddenColumnsCount() > 0)
4558 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4560 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4561 .getHiddenColumns(c).getEnd() // +1
4565 if (view.getCalcIdParam() != null)
4567 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4569 if (calcIdParam != null)
4571 if (recoverCalcIdParam(calcIdParam, af.viewport))
4576 warn("Couldn't recover parameters for "
4577 + calcIdParam.getCalcId());
4582 af.setMenusFromViewport(af.viewport);
4583 af.setTitle(view.getTitle());
4584 // TODO: we don't need to do this if the viewport is aready visible.
4586 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4587 * has a 'cdna/protein complement' view, in which case save it in order to
4588 * populate a SplitFrame once all views have been read in.
4590 String complementaryViewId = view.getComplementId();
4591 if (complementaryViewId == null)
4593 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4595 // recompute any autoannotation
4596 af.alignPanel.updateAnnotation(false, true);
4597 reorderAutoannotation(af, al, autoAlan);
4598 af.alignPanel.alignmentChanged();
4602 splitFrameCandidates.put(view, af);
4607 private ColourSchemeI constructAnnotationColour(
4608 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4609 JalviewModelSequence jms, boolean checkGroupAnnColour)
4611 boolean propagateAnnColour = false;
4612 ColourSchemeI cs = null;
4613 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4614 if (checkGroupAnnColour && al.getGroups() != null
4615 && al.getGroups().size() > 0)
4617 // pre 2.8.1 behaviour
4618 // check to see if we should transfer annotation colours
4619 propagateAnnColour = true;
4620 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4622 if (sg.cs instanceof AnnotationColourGradient)
4624 propagateAnnColour = false;
4628 // int find annotation
4629 if (annAlignment.getAlignmentAnnotation() != null)
4631 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4633 if (annAlignment.getAlignmentAnnotation()[i].label
4634 .equals(viewAnnColour.getAnnotation()))
4636 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4638 annAlignment.getAlignmentAnnotation()[i]
4639 .setThreshold(new jalview.datamodel.GraphLine(
4640 viewAnnColour.getThreshold(), "Threshold",
4641 java.awt.Color.black)
4646 if (viewAnnColour.getColourScheme().equals("None"))
4648 cs = new AnnotationColourGradient(
4649 annAlignment.getAlignmentAnnotation()[i],
4650 new java.awt.Color(viewAnnColour.getMinColour()),
4651 new java.awt.Color(viewAnnColour.getMaxColour()),
4652 viewAnnColour.getAboveThreshold());
4654 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4656 cs = new AnnotationColourGradient(
4657 annAlignment.getAlignmentAnnotation()[i],
4658 getUserColourScheme(jms,
4659 viewAnnColour.getColourScheme()),
4660 viewAnnColour.getAboveThreshold());
4664 cs = new AnnotationColourGradient(
4665 annAlignment.getAlignmentAnnotation()[i],
4666 ColourSchemeProperty.getColour(al,
4667 viewAnnColour.getColourScheme()),
4668 viewAnnColour.getAboveThreshold());
4670 if (viewAnnColour.hasPerSequence())
4672 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4675 if (viewAnnColour.hasPredefinedColours())
4677 ((AnnotationColourGradient) cs)
4678 .setPredefinedColours(viewAnnColour
4679 .isPredefinedColours());
4681 if (propagateAnnColour && al.getGroups() != null)
4683 // Also use these settings for all the groups
4684 for (int g = 0; g < al.getGroups().size(); g++)
4686 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4694 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4695 * new AnnotationColourGradient(
4696 * annAlignment.getAlignmentAnnotation()[i], new
4697 * java.awt.Color(viewAnnColour. getMinColour()), new
4698 * java.awt.Color(viewAnnColour. getMaxColour()),
4699 * viewAnnColour.getAboveThreshold()); } else
4702 sg.cs = new AnnotationColourGradient(
4703 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4704 viewAnnColour.getAboveThreshold());
4705 if (cs instanceof AnnotationColourGradient)
4707 if (viewAnnColour.hasPerSequence())
4709 ((AnnotationColourGradient) cs)
4710 .setSeqAssociated(viewAnnColour.isPerSequence());
4712 if (viewAnnColour.hasPredefinedColours())
4714 ((AnnotationColourGradient) cs)
4715 .setPredefinedColours(viewAnnColour
4716 .isPredefinedColours());
4732 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4733 List<JvAnnotRow> autoAlan)
4735 // copy over visualization settings for autocalculated annotation in the
4737 if (al.getAlignmentAnnotation() != null)
4740 * Kludge for magic autoannotation names (see JAL-811)
4742 String[] magicNames = new String[] { "Consensus", "Quality",
4744 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4745 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4746 for (String nm : magicNames)
4748 visan.put(nm, nullAnnot);
4750 for (JvAnnotRow auan : autoAlan)
4752 visan.put(auan.template.label
4753 + (auan.template.getCalcId() == null ? "" : "\t"
4754 + auan.template.getCalcId()), auan);
4756 int hSize = al.getAlignmentAnnotation().length;
4757 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4758 // work through any autoCalculated annotation already on the view
4759 // removing it if it should be placed in a different location on the
4760 // annotation panel.
4761 List<String> remains = new ArrayList<String>(visan.keySet());
4762 for (int h = 0; h < hSize; h++)
4764 jalview.datamodel.AlignmentAnnotation jalan = al
4765 .getAlignmentAnnotation()[h];
4766 if (jalan.autoCalculated)
4769 JvAnnotRow valan = visan.get(k = jalan.label);
4770 if (jalan.getCalcId() != null)
4772 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4777 // delete the auto calculated row from the alignment
4778 al.deleteAnnotation(jalan, false);
4782 if (valan != nullAnnot)
4784 if (jalan != valan.template)
4786 // newly created autoannotation row instance
4787 // so keep a reference to the visible annotation row
4788 // and copy over all relevant attributes
4789 if (valan.template.graphHeight >= 0)
4792 jalan.graphHeight = valan.template.graphHeight;
4794 jalan.visible = valan.template.visible;
4796 reorder.add(new JvAnnotRow(valan.order, jalan));
4801 // Add any (possibly stale) autocalculated rows that were not appended to
4802 // the view during construction
4803 for (String other : remains)
4805 JvAnnotRow othera = visan.get(other);
4806 if (othera != nullAnnot && othera.template.getCalcId() != null
4807 && othera.template.getCalcId().length() > 0)
4809 reorder.add(othera);
4812 // now put the automatic annotation in its correct place
4813 int s = 0, srt[] = new int[reorder.size()];
4814 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4815 for (JvAnnotRow jvar : reorder)
4818 srt[s++] = jvar.order;
4821 jalview.util.QuickSort.sort(srt, rws);
4822 // and re-insert the annotation at its correct position
4823 for (JvAnnotRow jvar : rws)
4825 al.addAnnotation(jvar.template, jvar.order);
4827 af.alignPanel.adjustAnnotationHeight();
4831 Hashtable skipList = null;
4834 * TODO remove this method
4837 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4838 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4839 * throw new Error("Implementation Error. No skipList defined for this
4840 * Jalview2XML instance."); } return (AlignFrame)
4841 * skipList.get(view.getSequenceSetId()); }
4845 * Check if the Jalview view contained in object should be skipped or not.
4848 * @return true if view's sequenceSetId is a key in skipList
4850 private boolean skipViewport(JalviewModel object)
4852 if (skipList == null)
4857 if (skipList.containsKey(id = object.getJalviewModelSequence()
4858 .getViewport()[0].getSequenceSetId()))
4860 if (Cache.log != null && Cache.log.isDebugEnabled())
4862 Cache.log.debug("Skipping seuqence set id " + id);
4869 public void addToSkipList(AlignFrame af)
4871 if (skipList == null)
4873 skipList = new Hashtable();
4875 skipList.put(af.getViewport().getSequenceSetId(), af);
4878 public void clearSkipList()
4880 if (skipList != null)
4887 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4888 boolean ignoreUnrefed)
4890 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4892 Vector dseqs = null;
4895 // create a list of new dataset sequences
4896 dseqs = new Vector();
4898 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4900 Sequence vamsasSeq = vamsasSet.getSequence(i);
4901 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4903 // create a new dataset
4906 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4907 dseqs.copyInto(dsseqs);
4908 ds = new jalview.datamodel.Alignment(dsseqs);
4909 debug("Created new dataset " + vamsasSet.getDatasetId()
4910 + " for alignment " + System.identityHashCode(al));
4911 addDatasetRef(vamsasSet.getDatasetId(), ds);
4913 // set the dataset for the newly imported alignment.
4914 if (al.getDataset() == null && !ignoreUnrefed)
4923 * sequence definition to create/merge dataset sequence for
4927 * vector to add new dataset sequence to
4929 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4930 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4932 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4934 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4935 SequenceI dsq = null;
4936 if (sq != null && sq.getDatasetSequence() != null)
4938 dsq = sq.getDatasetSequence();
4940 if (sq == null && ignoreUnrefed)
4944 String sqid = vamsasSeq.getDsseqid();
4947 // need to create or add a new dataset sequence reference to this sequence
4950 dsq = seqRefIds.get(sqid);
4955 // make a new dataset sequence
4956 dsq = sq.createDatasetSequence();
4959 // make up a new dataset reference for this sequence
4960 sqid = seqHash(dsq);
4962 dsq.setVamsasId(uniqueSetSuffix + sqid);
4963 seqRefIds.put(sqid, dsq);
4968 dseqs.addElement(dsq);
4973 ds.addSequence(dsq);
4979 { // make this dataset sequence sq's dataset sequence
4980 sq.setDatasetSequence(dsq);
4981 // and update the current dataset alignment
4986 if (!dseqs.contains(dsq))
4993 if (ds.findIndex(dsq) < 0)
4995 ds.addSequence(dsq);
5002 // TODO: refactor this as a merge dataset sequence function
5003 // now check that sq (the dataset sequence) sequence really is the union of
5004 // all references to it
5005 // boolean pre = sq.getStart() < dsq.getStart();
5006 // boolean post = sq.getEnd() > dsq.getEnd();
5010 // StringBuffer sb = new StringBuffer();
5011 String newres = jalview.analysis.AlignSeq.extractGaps(
5012 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5013 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5014 && newres.length() > dsq.getLength())
5016 // Update with the longer sequence.
5020 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5021 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5022 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5023 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5025 dsq.setSequence(newres);
5027 // TODO: merges will never happen if we 'know' we have the real dataset
5028 // sequence - this should be detected when id==dssid
5030 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5031 // + (pre ? "prepended" : "") + " "
5032 // + (post ? "appended" : ""));
5038 * TODO use AlignmentI here and in related methods - needs
5039 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5041 Hashtable<String, AlignmentI> datasetIds = null;
5043 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5045 private AlignmentI getDatasetFor(String datasetId)
5047 if (datasetIds == null)
5049 datasetIds = new Hashtable<String, AlignmentI>();
5052 if (datasetIds.containsKey(datasetId))
5054 return datasetIds.get(datasetId);
5059 private void addDatasetRef(String datasetId, AlignmentI dataset)
5061 if (datasetIds == null)
5063 datasetIds = new Hashtable<String, AlignmentI>();
5065 datasetIds.put(datasetId, dataset);
5069 * make a new dataset ID for this jalview dataset alignment
5074 private String getDatasetIdRef(AlignmentI dataset)
5076 if (dataset.getDataset() != null)
5078 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5080 String datasetId = makeHashCode(dataset, null);
5081 if (datasetId == null)
5083 // make a new datasetId and record it
5084 if (dataset2Ids == null)
5086 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5090 datasetId = dataset2Ids.get(dataset);
5092 if (datasetId == null)
5094 datasetId = "ds" + dataset2Ids.size() + 1;
5095 dataset2Ids.put(dataset, datasetId);
5101 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5103 for (int d = 0; d < sequence.getDBRefCount(); d++)
5105 DBRef dr = sequence.getDBRef(d);
5106 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5107 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5108 .getVersion(), sequence.getDBRef(d).getAccessionId());
5109 if (dr.getMapping() != null)
5111 entry.setMap(addMapping(dr.getMapping()));
5113 datasetSequence.addDBRef(entry);
5117 private jalview.datamodel.Mapping addMapping(Mapping m)
5119 SequenceI dsto = null;
5120 // Mapping m = dr.getMapping();
5121 int fr[] = new int[m.getMapListFromCount() * 2];
5122 Enumeration f = m.enumerateMapListFrom();
5123 for (int _i = 0; f.hasMoreElements(); _i += 2)
5125 MapListFrom mf = (MapListFrom) f.nextElement();
5126 fr[_i] = mf.getStart();
5127 fr[_i + 1] = mf.getEnd();
5129 int fto[] = new int[m.getMapListToCount() * 2];
5130 f = m.enumerateMapListTo();
5131 for (int _i = 0; f.hasMoreElements(); _i += 2)
5133 MapListTo mf = (MapListTo) f.nextElement();
5134 fto[_i] = mf.getStart();
5135 fto[_i + 1] = mf.getEnd();
5137 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5138 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5139 if (m.getMappingChoice() != null)
5141 MappingChoice mc = m.getMappingChoice();
5142 if (mc.getDseqFor() != null)
5144 String dsfor = "" + mc.getDseqFor();
5145 if (seqRefIds.containsKey(dsfor))
5150 jmap.setTo(seqRefIds.get(dsfor));
5154 frefedSequence.add(newMappingRef(dsfor, jmap));
5160 * local sequence definition
5162 Sequence ms = mc.getSequence();
5163 SequenceI djs = null;
5164 String sqid = ms.getDsseqid();
5165 if (sqid != null && sqid.length() > 0)
5168 * recover dataset sequence
5170 djs = seqRefIds.get(sqid);
5175 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5176 sqid = ((Object) ms).toString(); // make up a new hascode for
5177 // undefined dataset sequence hash
5178 // (unlikely to happen)
5184 * make a new dataset sequence and add it to refIds hash
5186 djs = new jalview.datamodel.Sequence(ms.getName(),
5188 djs.setStart(jmap.getMap().getToLowest());
5189 djs.setEnd(jmap.getMap().getToHighest());
5190 djs.setVamsasId(uniqueSetSuffix + sqid);
5192 incompleteSeqs.put(sqid, djs);
5193 seqRefIds.put(sqid, djs);
5196 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5205 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5206 boolean keepSeqRefs)
5209 JalviewModel jm = saveState(ap, null, null, null);
5214 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5218 uniqueSetSuffix = "";
5219 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5224 if (this.frefedSequence == null)
5226 frefedSequence = new Vector();
5229 viewportsAdded.clear();
5231 AlignFrame af = loadFromObject(jm, null, false, null);
5232 af.alignPanels.clear();
5233 af.closeMenuItem_actionPerformed(true);
5236 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5237 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5238 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5239 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5240 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5243 return af.alignPanel;
5247 * flag indicating if hashtables should be cleared on finalization TODO this
5248 * flag may not be necessary
5250 private final boolean _cleartables = true;
5252 private Hashtable jvids2vobj;
5257 * @see java.lang.Object#finalize()
5260 protected void finalize() throws Throwable
5262 // really make sure we have no buried refs left.
5267 this.seqRefIds = null;
5268 this.seqsToIds = null;
5272 private void warn(String msg)
5277 private void warn(String msg, Exception e)
5279 if (Cache.log != null)
5283 Cache.log.warn(msg, e);
5287 Cache.log.warn(msg);
5292 System.err.println("Warning: " + msg);
5295 e.printStackTrace();
5300 private void debug(String string)
5302 debug(string, null);
5305 private void debug(String msg, Exception e)
5307 if (Cache.log != null)
5311 Cache.log.debug(msg, e);
5315 Cache.log.debug(msg);
5320 System.err.println("Warning: " + msg);
5323 e.printStackTrace();
5329 * set the object to ID mapping tables used to write/recover objects and XML
5330 * ID strings for the jalview project. If external tables are provided then
5331 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5332 * object goes out of scope. - also populates the datasetIds hashtable with
5333 * alignment objects containing dataset sequences
5336 * Map from ID strings to jalview datamodel
5338 * Map from jalview datamodel to ID strings
5342 public void setObjectMappingTables(Hashtable vobj2jv,
5343 IdentityHashMap jv2vobj)
5345 this.jv2vobj = jv2vobj;
5346 this.vobj2jv = vobj2jv;
5347 Iterator ds = jv2vobj.keySet().iterator();
5349 while (ds.hasNext())
5351 Object jvobj = ds.next();
5352 id = jv2vobj.get(jvobj).toString();
5353 if (jvobj instanceof jalview.datamodel.Alignment)
5355 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5357 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5360 else if (jvobj instanceof jalview.datamodel.Sequence)
5362 // register sequence object so the XML parser can recover it.
5363 if (seqRefIds == null)
5365 seqRefIds = new HashMap<String, SequenceI>();
5367 if (seqsToIds == null)
5369 seqsToIds = new IdentityHashMap<SequenceI, String>();
5371 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5372 seqsToIds.put((SequenceI) jvobj, id);
5374 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5377 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5378 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5379 if (jvann.annotationId == null)
5381 jvann.annotationId = anid;
5383 if (!jvann.annotationId.equals(anid))
5385 // TODO verify that this is the correct behaviour
5386 this.warn("Overriding Annotation ID for " + anid
5387 + " from different id : " + jvann.annotationId);
5388 jvann.annotationId = anid;
5391 else if (jvobj instanceof String)
5393 if (jvids2vobj == null)
5395 jvids2vobj = new Hashtable();
5396 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5401 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5407 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5408 * objects created from the project archive. If string is null (default for
5409 * construction) then suffix will be set automatically.
5413 public void setUniqueSetSuffix(String string)
5415 uniqueSetSuffix = string;
5420 * uses skipList2 as the skipList for skipping views on sequence sets
5421 * associated with keys in the skipList
5425 public void setSkipList(Hashtable skipList2)
5427 skipList = skipList2;
5431 * Reads the jar entry of given name and returns its contents, or null if the
5432 * entry is not found.
5435 * @param jarEntryName
5438 protected String readJarEntry(jarInputStreamProvider jprovider,
5439 String jarEntryName)
5441 String result = null;
5442 BufferedReader in = null;
5447 * Reopen the jar input stream and traverse its entries to find a matching
5450 JarInputStream jin = jprovider.getJarInputStream();
5451 JarEntry entry = null;
5454 entry = jin.getNextJarEntry();
5455 } while (entry != null && !entry.getName().equals(jarEntryName));
5459 StringBuilder out = new StringBuilder(256);
5460 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5463 while ((data = in.readLine()) != null)
5467 result = out.toString();
5471 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5473 } catch (Exception ex)
5475 ex.printStackTrace();
5483 } catch (IOException e)
5494 * Returns an incrementing counter (0, 1, 2...)
5498 private synchronized int nextCounter()