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();
1004 if (jal.getCodonFrames() != null)
1006 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1007 for (AlignedCodonFrame acf : jac)
1009 AlcodonFrame alc = new AlcodonFrame();
1010 if (acf.getProtMappings() != null
1011 && acf.getProtMappings().length > 0)
1013 boolean hasMap = false;
1014 SequenceI[] dnas = acf.getdnaSeqs();
1015 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1016 for (int m = 0; m < pmaps.length; m++)
1018 AlcodMap alcmap = new AlcodMap();
1019 alcmap.setDnasq(seqHash(dnas[m]));
1020 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1022 alc.addAlcodMap(alcmap);
1027 vamsasSet.addAlcodonFrame(alc);
1030 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1032 // AlcodonFrame alc = new AlcodonFrame();
1033 // vamsasSet.addAlcodonFrame(alc);
1034 // for (int p = 0; p < acf.aaWidth; p++)
1036 // Alcodon cmap = new Alcodon();
1037 // if (acf.codons[p] != null)
1039 // // Null codons indicate a gapped column in the translated peptide
1041 // cmap.setPos1(acf.codons[p][0]);
1042 // cmap.setPos2(acf.codons[p][1]);
1043 // cmap.setPos3(acf.codons[p][2]);
1045 // alc.addAlcodon(cmap);
1047 // if (acf.getProtMappings() != null
1048 // && acf.getProtMappings().length > 0)
1050 // SequenceI[] dnas = acf.getdnaSeqs();
1051 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1052 // for (int m = 0; m < pmaps.length; m++)
1054 // AlcodMap alcmap = new AlcodMap();
1055 // alcmap.setDnasq(seqHash(dnas[m]));
1056 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1058 // alc.addAlcodMap(alcmap);
1065 // /////////////////////////////////
1066 if (!storeDS && av.currentTree != null)
1068 // FIND ANY ASSOCIATED TREES
1069 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1070 if (Desktop.desktop != null)
1072 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1074 for (int t = 0; t < frames.length; t++)
1076 if (frames[t] instanceof TreePanel)
1078 TreePanel tp = (TreePanel) frames[t];
1080 if (tp.treeCanvas.av.getAlignment() == jal)
1082 Tree tree = new Tree();
1083 tree.setTitle(tp.getTitle());
1084 tree.setCurrentTree((av.currentTree == tp.getTree()));
1085 tree.setNewick(tp.getTree().toString());
1086 tree.setThreshold(tp.treeCanvas.threshold);
1088 tree.setFitToWindow(tp.fitToWindow.getState());
1089 tree.setFontName(tp.getTreeFont().getName());
1090 tree.setFontSize(tp.getTreeFont().getSize());
1091 tree.setFontStyle(tp.getTreeFont().getStyle());
1092 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1094 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1095 tree.setShowDistances(tp.distanceMenu.getState());
1097 tree.setHeight(tp.getHeight());
1098 tree.setWidth(tp.getWidth());
1099 tree.setXpos(tp.getX());
1100 tree.setYpos(tp.getY());
1101 tree.setId(makeHashCode(tp, null));
1111 * store forward refs from an annotationRow to any groups
1113 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1116 for (SequenceI sq : jal.getSequences())
1118 // Store annotation on dataset sequences only
1119 AlignmentAnnotation[] aa = sq.getAnnotation();
1120 if (aa != null && aa.length > 0)
1122 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1129 if (jal.getAlignmentAnnotation() != null)
1131 // Store the annotation shown on the alignment.
1132 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1133 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1138 if (jal.getGroups() != null)
1140 JGroup[] groups = new JGroup[jal.getGroups().size()];
1142 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1144 JGroup jGroup = new JGroup();
1145 groups[++i] = jGroup;
1147 jGroup.setStart(sg.getStartRes());
1148 jGroup.setEnd(sg.getEndRes());
1149 jGroup.setName(sg.getName());
1150 if (groupRefs.containsKey(sg))
1152 // group has references so set its ID field
1153 jGroup.setId(groupRefs.get(sg));
1157 if (sg.cs.conservationApplied())
1159 jGroup.setConsThreshold(sg.cs.getConservationInc());
1161 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1163 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1167 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1170 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1172 jGroup.setColour("AnnotationColourGradient");
1173 jGroup.setAnnotationColours(constructAnnotationColours(
1174 (jalview.schemes.AnnotationColourGradient) sg.cs,
1177 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1179 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1183 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1186 jGroup.setPidThreshold(sg.cs.getThreshold());
1189 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1190 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1191 jGroup.setDisplayText(sg.getDisplayText());
1192 jGroup.setColourText(sg.getColourText());
1193 jGroup.setTextCol1(sg.textColour.getRGB());
1194 jGroup.setTextCol2(sg.textColour2.getRGB());
1195 jGroup.setTextColThreshold(sg.thresholdTextColour);
1196 jGroup.setShowUnconserved(sg.getShowNonconserved());
1197 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1198 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1199 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1200 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1201 for (SequenceI seq : sg.getSequences())
1203 jGroup.addSeq(seqHash(seq));
1207 jms.setJGroup(groups);
1211 // /////////SAVE VIEWPORT
1212 Viewport view = new Viewport();
1213 view.setTitle(ap.alignFrame.getTitle());
1214 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1215 av.getSequenceSetId()));
1216 view.setId(av.getViewId());
1217 if (av.getCodingComplement() != null)
1219 view.setComplementId(av.getCodingComplement().getViewId());
1221 view.setViewName(av.viewName);
1222 view.setGatheredViews(av.isGatherViewsHere());
1224 Rectangle size = ap.av.getExplodedGeometry();
1225 Rectangle position = size;
1228 size = ap.alignFrame.getBounds();
1229 if (av.getCodingComplement() != null)
1231 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1239 view.setXpos(position.x);
1240 view.setYpos(position.y);
1242 view.setWidth(size.width);
1243 view.setHeight(size.height);
1245 view.setStartRes(av.startRes);
1246 view.setStartSeq(av.startSeq);
1248 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1250 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1253 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1255 AnnotationColours ac = constructAnnotationColours(
1256 (jalview.schemes.AnnotationColourGradient) av
1257 .getGlobalColourScheme(),
1260 view.setAnnotationColours(ac);
1261 view.setBgColour("AnnotationColourGradient");
1265 view.setBgColour(ColourSchemeProperty.getColourName(av
1266 .getGlobalColourScheme()));
1269 ColourSchemeI cs = av.getGlobalColourScheme();
1273 if (cs.conservationApplied())
1275 view.setConsThreshold(cs.getConservationInc());
1276 if (cs instanceof jalview.schemes.UserColourScheme)
1278 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1282 if (cs instanceof ResidueColourScheme)
1284 view.setPidThreshold(cs.getThreshold());
1288 view.setConservationSelected(av.getConservationSelected());
1289 view.setPidSelected(av.getAbovePIDThreshold());
1290 view.setFontName(av.font.getName());
1291 view.setFontSize(av.font.getSize());
1292 view.setFontStyle(av.font.getStyle());
1293 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1294 view.setRenderGaps(av.isRenderGaps());
1295 view.setShowAnnotation(av.isShowAnnotation());
1296 view.setShowBoxes(av.getShowBoxes());
1297 view.setShowColourText(av.getColourText());
1298 view.setShowFullId(av.getShowJVSuffix());
1299 view.setRightAlignIds(av.isRightAlignIds());
1300 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1301 view.setShowText(av.getShowText());
1302 view.setShowUnconserved(av.getShowUnconserved());
1303 view.setWrapAlignment(av.getWrapAlignment());
1304 view.setTextCol1(av.getTextColour().getRGB());
1305 view.setTextCol2(av.getTextColour2().getRGB());
1306 view.setTextColThreshold(av.getThresholdTextColour());
1307 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1308 view.setShowSequenceLogo(av.isShowSequenceLogo());
1309 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1310 view.setShowGroupConsensus(av.isShowGroupConsensus());
1311 view.setShowGroupConservation(av.isShowGroupConservation());
1312 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1313 view.setShowDbRefTooltip(av.isShowDBRefs());
1314 view.setFollowHighlight(av.isFollowHighlight());
1315 view.setFollowSelection(av.followSelection);
1316 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1317 if (av.getFeaturesDisplayed() != null)
1319 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1321 String[] renderOrder = ap.getSeqPanel().seqCanvas
1322 .getFeatureRenderer().getRenderOrder()
1323 .toArray(new String[0]);
1325 Vector<String> settingsAdded = new Vector<String>();
1326 if (renderOrder != null)
1328 for (String featureType : renderOrder)
1330 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1331 .getFeatureRenderer()
1332 .getFeatureStyle(featureType);
1333 Setting setting = new Setting();
1334 setting.setType(featureType);
1335 if (!fcol.isSimpleColour())
1337 setting.setColour(fcol.getMaxColour().getRGB());
1338 setting.setMincolour(fcol.getMinColour().getRGB());
1339 setting.setMin(fcol.getMin());
1340 setting.setMax(fcol.getMax());
1341 setting.setColourByLabel(fcol.isColourByLabel());
1342 setting.setAutoScale(fcol.isAutoScaled());
1343 setting.setThreshold(fcol.getThreshold());
1344 // -1 = No threshold, 0 = Below, 1 = Above
1345 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1346 : (fcol.isBelowThreshold() ? 0 : -1));
1350 setting.setColour(fcol.getColour().getRGB());
1353 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1355 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1356 .getOrder(featureType);
1359 setting.setOrder(rorder);
1361 fs.addSetting(setting);
1362 settingsAdded.addElement(featureType);
1366 // is groups actually supposed to be a map here ?
1367 Iterator<String> en = ap.getSeqPanel().seqCanvas
1368 .getFeatureRenderer()
1369 .getFeatureGroups().iterator();
1370 Vector<String> groupsAdded = new Vector<String>();
1371 while (en.hasNext())
1373 String grp = en.next();
1374 if (groupsAdded.contains(grp))
1378 Group g = new Group();
1380 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1381 .getFeatureRenderer().checkGroupVisibility(grp, false))
1384 groupsAdded.addElement(grp);
1386 jms.setFeatureSettings(fs);
1389 if (av.hasHiddenColumns())
1391 if (av.getColumnSelection() == null
1392 || av.getColumnSelection().getHiddenColumns() == null)
1394 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1398 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1401 int[] region = av.getColumnSelection().getHiddenColumns()
1403 HiddenColumns hc = new HiddenColumns();
1404 hc.setStart(region[0]);
1405 hc.setEnd(region[1]);
1406 view.addHiddenColumns(hc);
1410 if (calcIdSet.size() > 0)
1412 for (String calcId : calcIdSet)
1414 if (calcId.trim().length() > 0)
1416 CalcIdParam cidp = createCalcIdParam(calcId, av);
1417 // Some calcIds have no parameters.
1420 view.addCalcIdParam(cidp);
1426 jms.addViewport(view);
1428 object.setJalviewModelSequence(jms);
1429 object.getVamsasModel().addSequenceSet(vamsasSet);
1431 if (jout != null && fileName != null)
1433 // We may not want to write the object to disk,
1434 // eg we can copy the alignViewport to a new view object
1435 // using save and then load
1438 System.out.println("Writing jar entry " + fileName);
1439 JarEntry entry = new JarEntry(fileName);
1440 jout.putNextEntry(entry);
1441 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1443 Marshaller marshaller = new Marshaller(pout);
1444 marshaller.marshal(object);
1447 } catch (Exception ex)
1449 // TODO: raise error in GUI if marshalling failed.
1450 ex.printStackTrace();
1457 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1458 * for each viewer, with
1460 * <li>viewer geometry (position, size, split pane divider location)</li>
1461 * <li>index of the selected structure in the viewer (currently shows gapped
1463 * <li>the id of the annotation holding RNA secondary structure</li>
1464 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1466 * Varna viewer state is also written out (in native Varna XML) to separate
1467 * project jar entries. A separate entry is written for each RNA structure
1468 * displayed, with the naming convention
1470 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1478 * @param storeDataset
1480 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1481 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1482 boolean storeDataset)
1484 if (Desktop.desktop == null)
1488 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1489 for (int f = frames.length - 1; f > -1; f--)
1491 if (frames[f] instanceof AppVarna)
1493 AppVarna varna = (AppVarna) frames[f];
1495 * link the sequence to every viewer that is showing it and is linked to
1496 * its alignment panel
1498 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1500 String viewId = varna.getViewId();
1501 RnaViewer rna = new RnaViewer();
1502 rna.setViewId(viewId);
1503 rna.setTitle(varna.getTitle());
1504 rna.setXpos(varna.getX());
1505 rna.setYpos(varna.getY());
1506 rna.setWidth(varna.getWidth());
1507 rna.setHeight(varna.getHeight());
1508 rna.setDividerLocation(varna.getDividerLocation());
1509 rna.setSelectedRna(varna.getSelectedIndex());
1510 jseq.addRnaViewer(rna);
1513 * Store each Varna panel's state once in the project per sequence.
1514 * First time through only (storeDataset==false)
1516 // boolean storeSessions = false;
1517 // String sequenceViewId = viewId + seqsToIds.get(jds);
1518 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1520 // viewIds.add(sequenceViewId);
1521 // storeSessions = true;
1523 for (RnaModel model : varna.getModels())
1525 if (model.seq == jds)
1528 * VARNA saves each view (sequence or alignment secondary
1529 * structure, gapped or trimmed) as a separate XML file
1531 String jarEntryName = rnaSessions.get(model);
1532 if (jarEntryName == null)
1535 String varnaStateFile = varna.getStateInfo(model.rna);
1536 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1537 copyFileToJar(jout, varnaStateFile, jarEntryName);
1538 rnaSessions.put(model, jarEntryName);
1540 SecondaryStructure ss = new SecondaryStructure();
1541 String annotationId = varna.getAnnotation(jds).annotationId;
1542 ss.setAnnotationId(annotationId);
1543 ss.setViewerState(jarEntryName);
1544 ss.setGapped(model.gapped);
1545 ss.setTitle(model.title);
1546 rna.addSecondaryStructure(ss);
1555 * Copy the contents of a file to a new entry added to the output jar
1559 * @param jarEntryName
1561 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1562 String jarEntryName)
1564 DataInputStream dis = null;
1567 File file = new File(infilePath);
1568 if (file.exists() && jout != null)
1570 dis = new DataInputStream(new FileInputStream(file));
1571 byte[] data = new byte[(int) file.length()];
1572 dis.readFully(data);
1573 writeJarEntry(jout, jarEntryName, data);
1575 } catch (Exception ex)
1577 ex.printStackTrace();
1585 } catch (IOException e)
1594 * Write the data to a new entry of given name in the output jar file
1597 * @param jarEntryName
1599 * @throws IOException
1601 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1602 byte[] data) throws IOException
1606 System.out.println("Writing jar entry " + jarEntryName);
1607 jout.putNextEntry(new JarEntry(jarEntryName));
1608 DataOutputStream dout = new DataOutputStream(jout);
1609 dout.write(data, 0, data.length);
1616 * Save the state of a structure viewer
1621 * the archive XML element under which to save the state
1624 * @param matchedFile
1628 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1629 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1630 String matchedFile, StructureViewerBase viewFrame)
1632 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1635 * Look for any bindings for this viewer to the PDB file of interest
1636 * (including part matches excluding chain id)
1638 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1640 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1641 final String pdbId = pdbentry.getId();
1642 if (!pdbId.equals(entry.getId())
1643 && !(entry.getId().length() > 4 && entry.getId()
1644 .toLowerCase().startsWith(pdbId.toLowerCase())))
1647 * not interested in a binding to a different PDB entry here
1651 if (matchedFile == null)
1653 matchedFile = pdbentry.getFile();
1655 else if (!matchedFile.equals(pdbentry.getFile()))
1658 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1659 + pdbentry.getFile());
1663 // can get at it if the ID
1664 // match is ambiguous (e.g.
1667 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1669 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1670 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1672 StructureState state = new StructureState();
1673 state.setVisible(true);
1674 state.setXpos(viewFrame.getX());
1675 state.setYpos(viewFrame.getY());
1676 state.setWidth(viewFrame.getWidth());
1677 state.setHeight(viewFrame.getHeight());
1678 final String viewId = viewFrame.getViewId();
1679 state.setViewId(viewId);
1680 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1681 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1682 state.setColourByJmol(viewFrame.isColouredByViewer());
1683 state.setType(viewFrame.getViewerType().toString());
1684 pdb.addStructureState(state);
1691 private AnnotationColours constructAnnotationColours(
1692 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1693 JalviewModelSequence jms)
1695 AnnotationColours ac = new AnnotationColours();
1696 ac.setAboveThreshold(acg.getAboveThreshold());
1697 ac.setThreshold(acg.getAnnotationThreshold());
1698 ac.setAnnotation(acg.getAnnotation());
1699 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1701 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1706 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1710 ac.setMaxColour(acg.getMaxColour().getRGB());
1711 ac.setMinColour(acg.getMinColour().getRGB());
1712 ac.setPerSequence(acg.isSeqAssociated());
1713 ac.setPredefinedColours(acg.isPredefinedColours());
1717 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1718 IdentityHashMap<SequenceGroup, String> groupRefs,
1719 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1720 SequenceSet vamsasSet)
1723 for (int i = 0; i < aa.length; i++)
1725 Annotation an = new Annotation();
1727 AlignmentAnnotation annotation = aa[i];
1728 if (annotation.annotationId != null)
1730 annotationIds.put(annotation.annotationId, annotation);
1733 an.setId(annotation.annotationId);
1735 an.setVisible(annotation.visible);
1737 an.setDescription(annotation.description);
1739 if (annotation.sequenceRef != null)
1741 // 2.9 JAL-1781 xref on sequence id rather than name
1742 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1744 if (annotation.groupRef != null)
1746 String groupIdr = groupRefs.get(annotation.groupRef);
1747 if (groupIdr == null)
1749 // make a locally unique String
1751 annotation.groupRef,
1752 groupIdr = ("" + System.currentTimeMillis()
1753 + annotation.groupRef.getName() + groupRefs
1756 an.setGroupRef(groupIdr.toString());
1759 // store all visualization attributes for annotation
1760 an.setGraphHeight(annotation.graphHeight);
1761 an.setCentreColLabels(annotation.centreColLabels);
1762 an.setScaleColLabels(annotation.scaleColLabel);
1763 an.setShowAllColLabels(annotation.showAllColLabels);
1764 an.setBelowAlignment(annotation.belowAlignment);
1766 if (annotation.graph > 0)
1769 an.setGraphType(annotation.graph);
1770 an.setGraphGroup(annotation.graphGroup);
1771 if (annotation.getThreshold() != null)
1773 ThresholdLine line = new ThresholdLine();
1774 line.setLabel(annotation.getThreshold().label);
1775 line.setValue(annotation.getThreshold().value);
1776 line.setColour(annotation.getThreshold().colour.getRGB());
1777 an.setThresholdLine(line);
1785 an.setLabel(annotation.label);
1787 if (annotation == av.getAlignmentQualityAnnot()
1788 || annotation == av.getAlignmentConservationAnnotation()
1789 || annotation == av.getAlignmentConsensusAnnotation()
1790 || annotation.autoCalculated)
1792 // new way of indicating autocalculated annotation -
1793 an.setAutoCalculated(annotation.autoCalculated);
1795 if (annotation.hasScore())
1797 an.setScore(annotation.getScore());
1800 if (annotation.getCalcId() != null)
1802 calcIdSet.add(annotation.getCalcId());
1803 an.setCalcId(annotation.getCalcId());
1805 if (annotation.hasProperties())
1807 for (String pr : annotation.getProperties())
1809 Property prop = new Property();
1811 prop.setValue(annotation.getProperty(pr));
1812 an.addProperty(prop);
1816 AnnotationElement ae;
1817 if (annotation.annotations != null)
1819 an.setScoreOnly(false);
1820 for (int a = 0; a < annotation.annotations.length; a++)
1822 if ((annotation == null) || (annotation.annotations[a] == null))
1827 ae = new AnnotationElement();
1828 if (annotation.annotations[a].description != null)
1830 ae.setDescription(annotation.annotations[a].description);
1832 if (annotation.annotations[a].displayCharacter != null)
1834 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1837 if (!Float.isNaN(annotation.annotations[a].value))
1839 ae.setValue(annotation.annotations[a].value);
1843 if (annotation.annotations[a].secondaryStructure > ' ')
1845 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1849 if (annotation.annotations[a].colour != null
1850 && annotation.annotations[a].colour != java.awt.Color.black)
1852 ae.setColour(annotation.annotations[a].colour.getRGB());
1855 an.addAnnotationElement(ae);
1856 if (annotation.autoCalculated)
1858 // only write one non-null entry into the annotation row -
1859 // sufficient to get the visualization attributes necessary to
1867 an.setScoreOnly(true);
1869 if (!storeDS || (storeDS && !annotation.autoCalculated))
1871 // skip autocalculated annotation - these are only provided for
1873 vamsasSet.addAnnotation(an);
1879 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1881 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1882 if (settings != null)
1884 CalcIdParam vCalcIdParam = new CalcIdParam();
1885 vCalcIdParam.setCalcId(calcId);
1886 vCalcIdParam.addServiceURL(settings.getServiceURI());
1887 // generic URI allowing a third party to resolve another instance of the
1888 // service used for this calculation
1889 for (String urls : settings.getServiceURLs())
1891 vCalcIdParam.addServiceURL(urls);
1893 vCalcIdParam.setVersion("1.0");
1894 if (settings.getPreset() != null)
1896 WsParamSetI setting = settings.getPreset();
1897 vCalcIdParam.setName(setting.getName());
1898 vCalcIdParam.setDescription(setting.getDescription());
1902 vCalcIdParam.setName("");
1903 vCalcIdParam.setDescription("Last used parameters");
1905 // need to be able to recover 1) settings 2) user-defined presets or
1906 // recreate settings from preset 3) predefined settings provided by
1907 // service - or settings that can be transferred (or discarded)
1908 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1910 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1911 // todo - decide if updateImmediately is needed for any projects.
1913 return vCalcIdParam;
1918 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1921 if (calcIdParam.getVersion().equals("1.0"))
1923 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1924 .getPreferredServiceFor(calcIdParam.getServiceURL());
1925 if (service != null)
1927 WsParamSetI parmSet = null;
1930 parmSet = service.getParamStore().parseServiceParameterFile(
1931 calcIdParam.getName(), calcIdParam.getDescription(),
1932 calcIdParam.getServiceURL(),
1933 calcIdParam.getParameters().replace("|\\n|", "\n"));
1934 } catch (IOException x)
1936 warn("Couldn't parse parameter data for "
1937 + calcIdParam.getCalcId(), x);
1940 List<ArgumentI> argList = null;
1941 if (calcIdParam.getName().length() > 0)
1943 parmSet = service.getParamStore()
1944 .getPreset(calcIdParam.getName());
1945 if (parmSet != null)
1947 // TODO : check we have a good match with settings in AACon -
1948 // otherwise we'll need to create a new preset
1953 argList = parmSet.getArguments();
1956 AAConSettings settings = new AAConSettings(
1957 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1958 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1959 calcIdParam.isNeedsUpdate());
1964 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1968 throw new Error(MessageManager.formatMessage(
1969 "error.unsupported_version_calcIdparam",
1970 new Object[] { calcIdParam.toString() }));
1974 * External mapping between jalview objects and objects yielding a valid and
1975 * unique object ID string. This is null for normal Jalview project IO, but
1976 * non-null when a jalview project is being read or written as part of a
1979 IdentityHashMap jv2vobj = null;
1982 * Construct a unique ID for jvobj using either existing bindings or if none
1983 * exist, the result of the hashcode call for the object.
1986 * jalview data object
1987 * @return unique ID for referring to jvobj
1989 private String makeHashCode(Object jvobj, String altCode)
1991 if (jv2vobj != null)
1993 Object id = jv2vobj.get(jvobj);
1996 return id.toString();
1998 // check string ID mappings
1999 if (jvids2vobj != null && jvobj instanceof String)
2001 id = jvids2vobj.get(jvobj);
2005 return id.toString();
2007 // give up and warn that something has gone wrong
2008 warn("Cannot find ID for object in external mapping : " + jvobj);
2014 * return local jalview object mapped to ID, if it exists
2018 * @return null or object bound to idcode
2020 private Object retrieveExistingObj(String idcode)
2022 if (idcode != null && vobj2jv != null)
2024 return vobj2jv.get(idcode);
2030 * binding from ID strings from external mapping table to jalview data model
2033 private Hashtable vobj2jv;
2035 private Sequence createVamsasSequence(String id, SequenceI jds)
2037 return createVamsasSequence(true, id, jds, null);
2040 private Sequence createVamsasSequence(boolean recurse, String id,
2041 SequenceI jds, SequenceI parentseq)
2043 Sequence vamsasSeq = new Sequence();
2044 vamsasSeq.setId(id);
2045 vamsasSeq.setName(jds.getName());
2046 vamsasSeq.setSequence(jds.getSequenceAsString());
2047 vamsasSeq.setDescription(jds.getDescription());
2048 jalview.datamodel.DBRefEntry[] dbrefs = null;
2049 if (jds.getDatasetSequence() != null)
2051 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2052 if (jds.getDatasetSequence().getDBRefs() != null)
2054 dbrefs = jds.getDatasetSequence().getDBRefs();
2059 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
2060 // dataset sequences only
2061 dbrefs = jds.getDBRefs();
2065 for (int d = 0; d < dbrefs.length; d++)
2067 DBRef dbref = new DBRef();
2068 dbref.setSource(dbrefs[d].getSource());
2069 dbref.setVersion(dbrefs[d].getVersion());
2070 dbref.setAccessionId(dbrefs[d].getAccessionId());
2071 if (dbrefs[d].hasMap())
2073 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2075 dbref.setMapping(mp);
2077 vamsasSeq.addDBRef(dbref);
2083 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2084 SequenceI parentseq, SequenceI jds, boolean recurse)
2087 if (jmp.getMap() != null)
2091 jalview.util.MapList mlst = jmp.getMap();
2092 List<int[]> r = mlst.getFromRanges();
2093 for (int[] range : r)
2095 MapListFrom mfrom = new MapListFrom();
2096 mfrom.setStart(range[0]);
2097 mfrom.setEnd(range[1]);
2098 mp.addMapListFrom(mfrom);
2100 r = mlst.getToRanges();
2101 for (int[] range : r)
2103 MapListTo mto = new MapListTo();
2104 mto.setStart(range[0]);
2105 mto.setEnd(range[1]);
2106 mp.addMapListTo(mto);
2108 mp.setMapFromUnit(mlst.getFromRatio());
2109 mp.setMapToUnit(mlst.getToRatio());
2110 if (jmp.getTo() != null)
2112 MappingChoice mpc = new MappingChoice();
2114 && (parentseq != jmp.getTo() || parentseq
2115 .getDatasetSequence() != jmp.getTo()))
2117 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2123 SequenceI ps = null;
2124 if (parentseq != jmp.getTo()
2125 && parentseq.getDatasetSequence() != jmp.getTo())
2127 // chaining dbref rather than a handshaking one
2128 jmpid = seqHash(ps = jmp.getTo());
2132 jmpid = seqHash(ps = parentseq);
2134 mpc.setDseqFor(jmpid);
2135 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2137 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2138 seqRefIds.put(mpc.getDseqFor(), ps);
2142 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2145 mp.setMappingChoice(mpc);
2151 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2152 List<UserColourScheme> userColours, JalviewModelSequence jms)
2155 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2156 boolean newucs = false;
2157 if (!userColours.contains(ucs))
2159 userColours.add(ucs);
2162 id = "ucs" + userColours.indexOf(ucs);
2165 // actually create the scheme's entry in the XML model
2166 java.awt.Color[] colours = ucs.getColours();
2167 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2168 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2170 for (int i = 0; i < colours.length; i++)
2172 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2173 col.setName(ResidueProperties.aa[i]);
2174 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2175 jbucs.addColour(col);
2177 if (ucs.getLowerCaseColours() != null)
2179 colours = ucs.getLowerCaseColours();
2180 for (int i = 0; i < colours.length; i++)
2182 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2183 col.setName(ResidueProperties.aa[i].toLowerCase());
2184 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2185 jbucs.addColour(col);
2190 uc.setUserColourScheme(jbucs);
2191 jms.addUserColours(uc);
2197 jalview.schemes.UserColourScheme getUserColourScheme(
2198 JalviewModelSequence jms, String id)
2200 UserColours[] uc = jms.getUserColours();
2201 UserColours colours = null;
2203 for (int i = 0; i < uc.length; i++)
2205 if (uc[i].getId().equals(id))
2213 java.awt.Color[] newColours = new java.awt.Color[24];
2215 for (int i = 0; i < 24; i++)
2217 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2218 .getUserColourScheme().getColour(i).getRGB(), 16));
2221 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2224 if (colours.getUserColourScheme().getColourCount() > 24)
2226 newColours = new java.awt.Color[23];
2227 for (int i = 0; i < 23; i++)
2229 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2230 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2232 ucs.setLowerCaseColours(newColours);
2239 * contains last error message (if any) encountered by XML loader.
2241 String errorMessage = null;
2244 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2245 * exceptions are raised during project XML parsing
2247 public boolean attemptversion1parse = true;
2250 * Load a jalview project archive from a jar file
2253 * - HTTP URL or filename
2255 public AlignFrame loadJalviewAlign(final String file)
2258 jalview.gui.AlignFrame af = null;
2262 // create list to store references for any new Jmol viewers created
2263 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2264 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2265 // Workaround is to make sure caller implements the JarInputStreamProvider
2267 // so we can re-open the jar input stream for each entry.
2269 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2270 af = loadJalviewAlign(jprovider);
2272 } catch (MalformedURLException e)
2274 errorMessage = "Invalid URL format for '" + file + "'";
2280 SwingUtilities.invokeAndWait(new Runnable()
2285 setLoadingFinishedForNewStructureViewers();
2288 } catch (Exception x)
2290 System.err.println("Error loading alignment: " + x.getMessage());
2296 private jarInputStreamProvider createjarInputStreamProvider(
2297 final String file) throws MalformedURLException
2300 errorMessage = null;
2301 uniqueSetSuffix = null;
2303 viewportsAdded.clear();
2304 frefedSequence = null;
2306 if (file.startsWith("http://"))
2308 url = new URL(file);
2310 final URL _url = url;
2311 return new jarInputStreamProvider()
2315 public JarInputStream getJarInputStream() throws IOException
2319 return new JarInputStream(_url.openStream());
2323 return new JarInputStream(new FileInputStream(file));
2328 public String getFilename()
2336 * Recover jalview session from a jalview project archive. Caller may
2337 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2338 * themselves. Any null fields will be initialised with default values,
2339 * non-null fields are left alone.
2344 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2346 errorMessage = null;
2347 if (uniqueSetSuffix == null)
2349 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2351 if (seqRefIds == null)
2355 AlignFrame af = null, _af = null;
2356 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2357 final String file = jprovider.getFilename();
2360 JarInputStream jin = null;
2361 JarEntry jarentry = null;
2366 jin = jprovider.getJarInputStream();
2367 for (int i = 0; i < entryCount; i++)
2369 jarentry = jin.getNextJarEntry();
2372 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2374 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2375 JalviewModel object = new JalviewModel();
2377 Unmarshaller unmar = new Unmarshaller(object);
2378 unmar.setValidation(false);
2379 object = (JalviewModel) unmar.unmarshal(in);
2380 if (true) // !skipViewport(object))
2382 _af = loadFromObject(object, file, true, jprovider);
2383 if (object.getJalviewModelSequence().getViewportCount() > 0)
2386 if (af.viewport.isGatherViewsHere())
2388 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2394 else if (jarentry != null)
2396 // Some other file here.
2399 } while (jarentry != null);
2400 resolveFrefedSequences();
2401 } catch (IOException ex)
2403 ex.printStackTrace();
2404 errorMessage = "Couldn't locate Jalview XML file : " + file;
2405 System.err.println("Exception whilst loading jalview XML file : "
2407 } catch (Exception ex)
2409 System.err.println("Parsing as Jalview Version 2 file failed.");
2410 ex.printStackTrace(System.err);
2411 if (attemptversion1parse)
2413 // Is Version 1 Jar file?
2416 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2417 } catch (Exception ex2)
2419 System.err.println("Exception whilst loading as jalviewXMLV1:");
2420 ex2.printStackTrace();
2424 if (Desktop.instance != null)
2426 Desktop.instance.stopLoading();
2430 System.out.println("Successfully loaded archive file");
2433 ex.printStackTrace();
2435 System.err.println("Exception whilst loading jalview XML file : "
2437 } catch (OutOfMemoryError e)
2439 // Don't use the OOM Window here
2440 errorMessage = "Out of memory loading jalview XML file";
2441 System.err.println("Out of memory whilst loading jalview XML file");
2442 e.printStackTrace();
2445 if (Desktop.instance != null)
2447 Desktop.instance.stopLoading();
2451 * Regather multiple views (with the same sequence set id) to the frame (if
2452 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2453 * views instead of separate frames. Note this doesn't restore a state where
2454 * some expanded views in turn have tabbed views - the last "first tab" read
2455 * in will play the role of gatherer for all.
2457 for (AlignFrame fr : gatherToThisFrame.values())
2459 Desktop.instance.gatherViews(fr);
2462 restoreSplitFrames();
2464 if (errorMessage != null)
2472 * Try to reconstruct and display SplitFrame windows, where each contains
2473 * complementary dna and protein alignments. Done by pairing up AlignFrame
2474 * objects (created earlier) which have complementary viewport ids associated.
2476 protected void restoreSplitFrames()
2478 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2479 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2480 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2483 * Identify the DNA alignments
2485 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2488 AlignFrame af = candidate.getValue();
2489 if (af.getViewport().getAlignment().isNucleotide())
2491 dna.put(candidate.getKey().getId(), af);
2496 * Try to match up the protein complements
2498 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2501 AlignFrame af = candidate.getValue();
2502 if (!af.getViewport().getAlignment().isNucleotide())
2504 String complementId = candidate.getKey().getComplementId();
2505 // only non-null complements should be in the Map
2506 if (complementId != null && dna.containsKey(complementId))
2508 final AlignFrame dnaFrame = dna.get(complementId);
2509 SplitFrame sf = createSplitFrame(dnaFrame, af);
2510 addedToSplitFrames.add(dnaFrame);
2511 addedToSplitFrames.add(af);
2512 if (af.viewport.isGatherViewsHere())
2521 * Open any that we failed to pair up (which shouldn't happen!) as
2522 * standalone AlignFrame's.
2524 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2527 AlignFrame af = candidate.getValue();
2528 if (!addedToSplitFrames.contains(af))
2530 Viewport view = candidate.getKey();
2531 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2533 System.err.println("Failed to restore view " + view.getTitle()
2534 + " to split frame");
2539 * Gather back into tabbed views as flagged.
2541 for (SplitFrame sf : gatherTo)
2543 Desktop.instance.gatherViews(sf);
2546 splitFrameCandidates.clear();
2550 * Construct and display one SplitFrame holding DNA and protein alignments.
2553 * @param proteinFrame
2556 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2557 AlignFrame proteinFrame)
2559 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2560 String title = MessageManager.getString("label.linked_view_title");
2561 int width = (int) dnaFrame.getBounds().getWidth();
2562 int height = (int) (dnaFrame.getBounds().getHeight()
2563 + proteinFrame.getBounds().getHeight() + 50);
2566 * SplitFrame location is saved to both enclosed frames
2568 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2569 Desktop.addInternalFrame(splitFrame, title, width, height);
2572 * And compute cDNA consensus (couldn't do earlier with consensus as
2573 * mappings were not yet present)
2575 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2581 * check errorMessage for a valid error message and raise an error box in the
2582 * GUI or write the current errorMessage to stderr and then clear the error
2585 protected void reportErrors()
2587 reportErrors(false);
2590 protected void reportErrors(final boolean saving)
2592 if (errorMessage != null)
2594 final String finalErrorMessage = errorMessage;
2597 javax.swing.SwingUtilities.invokeLater(new Runnable()
2602 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2603 finalErrorMessage, "Error "
2604 + (saving ? "saving" : "loading")
2605 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2611 System.err.println("Problem loading Jalview file: " + errorMessage);
2614 errorMessage = null;
2617 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2620 * when set, local views will be updated from view stored in JalviewXML
2621 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2622 * sync if this is set to true.
2624 private final boolean updateLocalViews = false;
2627 * Returns the path to a temporary file holding the PDB file for the given PDB
2628 * id. The first time of asking, searches for a file of that name in the
2629 * Jalview project jar, and copies it to a new temporary file. Any repeat
2630 * requests just return the path to the file previously created.
2636 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2638 if (alreadyLoadedPDB.containsKey(pdbId))
2640 return alreadyLoadedPDB.get(pdbId).toString();
2643 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2644 if (tempFile != null)
2646 alreadyLoadedPDB.put(pdbId, tempFile);
2652 * Copies the jar entry of given name to a new temporary file and returns the
2653 * path to the file, or null if the entry is not found.
2656 * @param jarEntryName
2658 * a prefix for the temporary file name, must be at least three
2662 protected String copyJarEntry(jarInputStreamProvider jprovider,
2663 String jarEntryName, String prefix)
2665 BufferedReader in = null;
2666 PrintWriter out = null;
2670 JarInputStream jin = jprovider.getJarInputStream();
2672 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2673 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2674 * FileInputStream(jprovider)); }
2677 JarEntry entry = null;
2680 entry = jin.getNextJarEntry();
2681 } while (entry != null && !entry.getName().equals(jarEntryName));
2684 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2685 File outFile = File.createTempFile(prefix, ".tmp");
2686 outFile.deleteOnExit();
2687 out = new PrintWriter(new FileOutputStream(outFile));
2690 while ((data = in.readLine()) != null)
2695 String t = outFile.getAbsolutePath();
2700 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2702 } catch (Exception ex)
2704 ex.printStackTrace();
2712 } catch (IOException e)
2726 private class JvAnnotRow
2728 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2735 * persisted version of annotation row from which to take vis properties
2737 public jalview.datamodel.AlignmentAnnotation template;
2740 * original position of the annotation row in the alignment
2746 * Load alignment frame from jalview XML DOM object
2751 * filename source string
2752 * @param loadTreesAndStructures
2753 * when false only create Viewport
2755 * data source provider
2756 * @return alignment frame created from view stored in DOM
2758 AlignFrame loadFromObject(JalviewModel object, String file,
2759 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2761 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2762 Sequence[] vamsasSeq = vamsasSet.getSequence();
2764 JalviewModelSequence jms = object.getJalviewModelSequence();
2766 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2769 // ////////////////////////////////
2772 List<SequenceI> hiddenSeqs = null;
2775 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2777 boolean multipleView = false;
2778 SequenceI referenceseqForView = null;
2779 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2780 int vi = 0; // counter in vamsasSeq array
2781 for (int i = 0; i < jseqs.length; i++)
2783 String seqId = jseqs[i].getId();
2785 SequenceI tmpSeq = seqRefIds.get(seqId);
2788 if (!incompleteSeqs.containsKey(seqId))
2790 // may not need this check, but keep it for at least 2.9,1 release
2791 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2794 .println("Warning JAL-2154 regression: updating start/end for sequence "
2795 + tmpSeq.toString());
2798 incompleteSeqs.remove(seqId);
2800 tmpSeq.setStart(jseqs[i].getStart());
2801 tmpSeq.setEnd(jseqs[i].getEnd());
2802 tmpseqs.add(tmpSeq);
2803 multipleView = true;
2807 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2808 vamsasSeq[vi].getSequence());
2809 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2810 tmpSeq.setStart(jseqs[i].getStart());
2811 tmpSeq.setEnd(jseqs[i].getEnd());
2812 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2813 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2814 tmpseqs.add(tmpSeq);
2818 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2820 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2823 if (jseqs[i].getHidden())
2825 if (hiddenSeqs == null)
2827 hiddenSeqs = new ArrayList<SequenceI>();
2830 hiddenSeqs.add(tmpSeq);
2835 // Create the alignment object from the sequence set
2836 // ///////////////////////////////
2837 SequenceI[] orderedSeqs = tmpseqs
2838 .toArray(new SequenceI[tmpseqs.size()]);
2840 AlignmentI al = new Alignment(orderedSeqs);
2842 if (referenceseqForView != null)
2844 al.setSeqrep(referenceseqForView);
2846 // / Add the alignment properties
2847 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2849 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2850 al.setProperty(ssp.getKey(), ssp.getValue());
2854 // SequenceFeatures are added to the DatasetSequence,
2855 // so we must create or recover the dataset before loading features
2856 // ///////////////////////////////
2857 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2859 // older jalview projects do not have a dataset id.
2860 al.setDataset(null);
2864 // recover dataset - passing on flag indicating if this a 'viewless'
2865 // sequence set (a.k.a. a stored dataset for the project)
2866 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2867 .getViewportCount() == 0);
2869 // ///////////////////////////////
2871 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2874 // load sequence features, database references and any associated PDB
2875 // structures for the alignment
2876 for (int i = 0; i < vamsasSeq.length; i++)
2878 if (jseqs[i].getFeaturesCount() > 0)
2880 Features[] features = jseqs[i].getFeatures();
2881 for (int f = 0; f < features.length; f++)
2883 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2884 features[f].getType(), features[f].getDescription(),
2885 features[f].getStatus(), features[f].getBegin(),
2886 features[f].getEnd(), features[f].getFeatureGroup());
2888 sf.setScore(features[f].getScore());
2889 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2891 OtherData keyValue = features[f].getOtherData(od);
2892 if (keyValue.getKey().startsWith("LINK"))
2894 sf.addLink(keyValue.getValue());
2898 sf.setValue(keyValue.getKey(), keyValue.getValue());
2903 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2906 if (vamsasSeq[i].getDBRefCount() > 0)
2908 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2910 if (jseqs[i].getPdbidsCount() > 0)
2912 Pdbids[] ids = jseqs[i].getPdbids();
2913 for (int p = 0; p < ids.length; p++)
2915 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2916 entry.setId(ids[p].getId());
2917 if (ids[p].getType() != null)
2919 if (ids[p].getType().equalsIgnoreCase("PDB"))
2921 entry.setType(PDBEntry.Type.PDB);
2925 entry.setType(PDBEntry.Type.FILE);
2928 if (ids[p].getFile() != null)
2930 if (!pdbloaded.containsKey(ids[p].getFile()))
2932 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2936 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2939 StructureSelectionManager.getStructureSelectionManager(
2940 Desktop.instance).registerPDBEntry(entry);
2941 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2945 } // end !multipleview
2947 // ///////////////////////////////
2948 // LOAD SEQUENCE MAPPINGS
2950 if (vamsasSet.getAlcodonFrameCount() > 0)
2952 // TODO Potentially this should only be done once for all views of an
2954 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2955 for (int i = 0; i < alc.length; i++)
2957 AlignedCodonFrame cf = new AlignedCodonFrame();
2958 if (alc[i].getAlcodMapCount() > 0)
2960 AlcodMap[] maps = alc[i].getAlcodMap();
2961 for (int m = 0; m < maps.length; m++)
2963 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2965 jalview.datamodel.Mapping mapping = null;
2966 // attach to dna sequence reference.
2967 if (maps[m].getMapping() != null)
2969 mapping = addMapping(maps[m].getMapping());
2971 if (dnaseq != null && mapping.getTo() != null)
2973 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2978 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
2982 al.addCodonFrame(cf);
2987 // ////////////////////////////////
2989 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2992 * store any annotations which forward reference a group's ID
2994 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2996 if (vamsasSet.getAnnotationCount() > 0)
2998 Annotation[] an = vamsasSet.getAnnotation();
3000 for (int i = 0; i < an.length; i++)
3002 Annotation annotation = an[i];
3005 * test if annotation is automatically calculated for this view only
3007 boolean autoForView = false;
3008 if (annotation.getLabel().equals("Quality")
3009 || annotation.getLabel().equals("Conservation")
3010 || annotation.getLabel().equals("Consensus"))
3012 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3014 if (!annotation.hasAutoCalculated())
3016 annotation.setAutoCalculated(true);
3020 || (annotation.hasAutoCalculated() && annotation
3021 .isAutoCalculated()))
3023 // remove ID - we don't recover annotation from other views for
3024 // view-specific annotation
3025 annotation.setId(null);
3028 // set visiblity for other annotation in this view
3029 String annotationId = annotation.getId();
3030 if (annotationId != null && annotationIds.containsKey(annotationId))
3032 AlignmentAnnotation jda = annotationIds.get(annotationId);
3033 // in principle Visible should always be true for annotation displayed
3034 // in multiple views
3035 if (annotation.hasVisible())
3037 jda.visible = annotation.getVisible();
3040 al.addAnnotation(jda);
3044 // Construct new annotation from model.
3045 AnnotationElement[] ae = annotation.getAnnotationElement();
3046 jalview.datamodel.Annotation[] anot = null;
3047 java.awt.Color firstColour = null;
3049 if (!annotation.getScoreOnly())
3051 anot = new jalview.datamodel.Annotation[al.getWidth()];
3052 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3054 anpos = ae[aa].getPosition();
3056 if (anpos >= anot.length)
3061 anot[anpos] = new jalview.datamodel.Annotation(
3063 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3064 (ae[aa].getSecondaryStructure() == null || ae[aa]
3065 .getSecondaryStructure().length() == 0) ? ' '
3066 : ae[aa].getSecondaryStructure().charAt(0),
3070 // JBPNote: Consider verifying dataflow for IO of secondary
3071 // structure annotation read from Stockholm files
3072 // this was added to try to ensure that
3073 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3075 // anot[ae[aa].getPosition()].displayCharacter = "";
3077 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3078 if (firstColour == null)
3080 firstColour = anot[anpos].colour;
3084 jalview.datamodel.AlignmentAnnotation jaa = null;
3086 if (annotation.getGraph())
3088 float llim = 0, hlim = 0;
3089 // if (autoForView || an[i].isAutoCalculated()) {
3092 jaa = new jalview.datamodel.AlignmentAnnotation(
3093 annotation.getLabel(), annotation.getDescription(), anot,
3094 llim, hlim, annotation.getGraphType());
3096 jaa.graphGroup = annotation.getGraphGroup();
3097 jaa._linecolour = firstColour;
3098 if (annotation.getThresholdLine() != null)
3100 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3101 .getThresholdLine().getValue(), annotation
3102 .getThresholdLine().getLabel(), new java.awt.Color(
3103 annotation.getThresholdLine().getColour())));
3106 if (autoForView || annotation.isAutoCalculated())
3108 // Hardwire the symbol display line to ensure that labels for
3109 // histograms are displayed
3115 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3116 an[i].getDescription(), anot);
3117 jaa._linecolour = firstColour;
3119 // register new annotation
3120 if (an[i].getId() != null)
3122 annotationIds.put(an[i].getId(), jaa);
3123 jaa.annotationId = an[i].getId();
3125 // recover sequence association
3126 String sequenceRef = an[i].getSequenceRef();
3127 if (sequenceRef != null)
3129 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3130 SequenceI sequence = seqRefIds.get(sequenceRef);
3131 if (sequence == null)
3133 // in pre-2.9 projects sequence ref is to sequence name
3134 sequence = al.findName(sequenceRef);
3136 if (sequence != null)
3138 jaa.createSequenceMapping(sequence, 1, true);
3139 sequence.addAlignmentAnnotation(jaa);
3142 // and make a note of any group association
3143 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3145 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3146 .get(an[i].getGroupRef());
3149 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3150 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3155 if (an[i].hasScore())
3157 jaa.setScore(an[i].getScore());
3159 if (an[i].hasVisible())
3161 jaa.visible = an[i].getVisible();
3164 if (an[i].hasCentreColLabels())
3166 jaa.centreColLabels = an[i].getCentreColLabels();
3169 if (an[i].hasScaleColLabels())
3171 jaa.scaleColLabel = an[i].getScaleColLabels();
3173 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3175 // newer files have an 'autoCalculated' flag and store calculation
3176 // state in viewport properties
3177 jaa.autoCalculated = true; // means annotation will be marked for
3178 // update at end of load.
3180 if (an[i].hasGraphHeight())
3182 jaa.graphHeight = an[i].getGraphHeight();
3184 if (an[i].hasBelowAlignment())
3186 jaa.belowAlignment = an[i].isBelowAlignment();
3188 jaa.setCalcId(an[i].getCalcId());
3189 if (an[i].getPropertyCount() > 0)
3191 for (jalview.schemabinding.version2.Property prop : an[i]
3194 jaa.setProperty(prop.getName(), prop.getValue());
3197 if (jaa.autoCalculated)
3199 autoAlan.add(new JvAnnotRow(i, jaa));
3202 // if (!autoForView)
3204 // add autocalculated group annotation and any user created annotation
3206 al.addAnnotation(jaa);
3210 // ///////////////////////
3212 // Create alignment markup and styles for this view
3213 if (jms.getJGroupCount() > 0)
3215 JGroup[] groups = jms.getJGroup();
3216 boolean addAnnotSchemeGroup = false;
3217 for (int i = 0; i < groups.length; i++)
3219 JGroup jGroup = groups[i];
3220 ColourSchemeI cs = null;
3221 if (jGroup.getColour() != null)
3223 if (jGroup.getColour().startsWith("ucs"))
3225 cs = getUserColourScheme(jms, jGroup.getColour());
3227 else if (jGroup.getColour().equals("AnnotationColourGradient")
3228 && jGroup.getAnnotationColours() != null)
3230 addAnnotSchemeGroup = true;
3235 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3240 cs.setThreshold(jGroup.getPidThreshold(), true);
3244 Vector<SequenceI> seqs = new Vector<SequenceI>();
3246 for (int s = 0; s < jGroup.getSeqCount(); s++)
3248 String seqId = jGroup.getSeq(s) + "";
3249 SequenceI ts = seqRefIds.get(seqId);
3253 seqs.addElement(ts);
3257 if (seqs.size() < 1)
3262 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3263 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3264 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3266 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3268 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3269 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3270 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3271 .isShowUnconserved() : false);
3272 sg.thresholdTextColour = jGroup.getTextColThreshold();
3273 if (jGroup.hasShowConsensusHistogram())
3275 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3278 if (jGroup.hasShowSequenceLogo())
3280 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3282 if (jGroup.hasNormaliseSequenceLogo())
3284 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3286 if (jGroup.hasIgnoreGapsinConsensus())
3288 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3290 if (jGroup.getConsThreshold() != 0)
3292 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3293 "All", ResidueProperties.propHash, 3,
3294 sg.getSequences(null), 0, sg.getWidth() - 1);
3296 c.verdict(false, 25);
3297 sg.cs.setConservation(c);
3300 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3302 // re-instate unique group/annotation row reference
3303 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3307 for (AlignmentAnnotation jaa : jaal)
3310 if (jaa.autoCalculated)
3312 // match up and try to set group autocalc alignment row for this
3314 if (jaa.label.startsWith("Consensus for "))
3316 sg.setConsensus(jaa);
3318 // match up and try to set group autocalc alignment row for this
3320 if (jaa.label.startsWith("Conservation for "))
3322 sg.setConservationRow(jaa);
3329 if (addAnnotSchemeGroup)
3331 // reconstruct the annotation colourscheme
3332 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3333 null, al, jms, false);
3339 // only dataset in this model, so just return.
3342 // ///////////////////////////////
3345 // If we just load in the same jar file again, the sequenceSetId
3346 // will be the same, and we end up with multiple references
3347 // to the same sequenceSet. We must modify this id on load
3348 // so that each load of the file gives a unique id
3349 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3350 String viewId = (view.getId() == null ? null : view.getId()
3352 AlignFrame af = null;
3353 AlignViewport av = null;
3354 // now check to see if we really need to create a new viewport.
3355 if (multipleView && viewportsAdded.size() == 0)
3357 // We recovered an alignment for which a viewport already exists.
3358 // TODO: fix up any settings necessary for overlaying stored state onto
3359 // state recovered from another document. (may not be necessary).
3360 // we may need a binding from a viewport in memory to one recovered from
3362 // and then recover its containing af to allow the settings to be applied.
3363 // TODO: fix for vamsas demo
3365 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3367 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3368 if (seqsetobj != null)
3370 if (seqsetobj instanceof String)
3372 uniqueSeqSetId = (String) seqsetobj;
3374 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3380 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3386 * indicate that annotation colours are applied across all groups (pre
3387 * Jalview 2.8.1 behaviour)
3389 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3390 "2.8.1", object.getVersion());
3392 AlignmentPanel ap = null;
3393 boolean isnewview = true;
3396 // Check to see if this alignment already has a view id == viewId
3397 jalview.gui.AlignmentPanel views[] = Desktop
3398 .getAlignmentPanels(uniqueSeqSetId);
3399 if (views != null && views.length > 0)
3401 for (int v = 0; v < views.length; v++)
3403 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3405 // recover the existing alignpanel, alignframe, viewport
3406 af = views[v].alignFrame;
3409 // TODO: could even skip resetting view settings if we don't want to
3410 // change the local settings from other jalview processes
3419 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3420 uniqueSeqSetId, viewId, autoAlan);
3426 * Load any trees, PDB structures and viewers
3428 * Not done if flag is false (when this method is used for New View)
3430 if (loadTreesAndStructures)
3432 loadTrees(jms, view, af, av, ap);
3433 loadPDBStructures(jprovider, jseqs, af, ap);
3434 loadRnaViewers(jprovider, jseqs, ap);
3436 // and finally return.
3441 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3442 * panel is restored from separate jar entries, two (gapped and trimmed) per
3443 * sequence and secondary structure.
3445 * Currently each viewer shows just one sequence and structure (gapped and
3446 * trimmed), however this method is designed to support multiple sequences or
3447 * structures in viewers if wanted in future.
3453 private void loadRnaViewers(jarInputStreamProvider jprovider,
3454 JSeq[] jseqs, AlignmentPanel ap)
3457 * scan the sequences for references to viewers; create each one the first
3458 * time it is referenced, add Rna models to existing viewers
3460 for (JSeq jseq : jseqs)
3462 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3464 RnaViewer viewer = jseq.getRnaViewer(i);
3465 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3466 uniqueSetSuffix, ap);
3468 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3470 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3471 SequenceI seq = seqRefIds.get(jseq.getId());
3472 AlignmentAnnotation ann = this.annotationIds.get(ss
3473 .getAnnotationId());
3476 * add the structure to the Varna display (with session state copied
3477 * from the jar to a temporary file)
3479 boolean gapped = ss.isGapped();
3480 String rnaTitle = ss.getTitle();
3481 String sessionState = ss.getViewerState();
3482 String tempStateFile = copyJarEntry(jprovider, sessionState,
3484 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3485 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3487 appVarna.setInitialSelection(viewer.getSelectedRna());
3493 * Locate and return an already instantiated matching AppVarna, or create one
3497 * @param viewIdSuffix
3501 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3502 String viewIdSuffix, AlignmentPanel ap)
3505 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3506 * if load is repeated
3508 String postLoadId = viewer.getViewId() + viewIdSuffix;
3509 for (JInternalFrame frame : getAllFrames())
3511 if (frame instanceof AppVarna)
3513 AppVarna varna = (AppVarna) frame;
3514 if (postLoadId.equals(varna.getViewId()))
3516 // this viewer is already instantiated
3517 // could in future here add ap as another 'parent' of the
3518 // AppVarna window; currently just 1-to-many
3525 * viewer not found - make it
3527 RnaViewerModel model = new RnaViewerModel(postLoadId,
3528 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3529 viewer.getWidth(), viewer.getHeight(),
3530 viewer.getDividerLocation());
3531 AppVarna varna = new AppVarna(model, ap);
3537 * Load any saved trees
3545 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3546 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3548 // TODO result of automated refactoring - are all these parameters needed?
3551 for (int t = 0; t < jms.getTreeCount(); t++)
3554 Tree tree = jms.getTree(t);
3556 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3559 tp = af.ShowNewickTree(
3560 new jalview.io.NewickFile(tree.getNewick()),
3561 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3562 tree.getXpos(), tree.getYpos());
3563 if (tree.getId() != null)
3565 // perhaps bind the tree id to something ?
3570 // update local tree attributes ?
3571 // TODO: should check if tp has been manipulated by user - if so its
3572 // settings shouldn't be modified
3573 tp.setTitle(tree.getTitle());
3574 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3575 .getWidth(), tree.getHeight()));
3576 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3579 tp.treeCanvas.av = av; // af.viewport;
3580 tp.treeCanvas.ap = ap; // af.alignPanel;
3585 warn("There was a problem recovering stored Newick tree: \n"
3586 + tree.getNewick());
3590 tp.fitToWindow.setState(tree.getFitToWindow());
3591 tp.fitToWindow_actionPerformed(null);
3593 if (tree.getFontName() != null)
3595 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3596 .getFontStyle(), tree.getFontSize()));
3600 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3601 .getFontStyle(), tree.getFontSize()));
3604 tp.showPlaceholders(tree.getMarkUnlinked());
3605 tp.showBootstrap(tree.getShowBootstrap());
3606 tp.showDistances(tree.getShowDistances());
3608 tp.treeCanvas.threshold = tree.getThreshold();
3610 if (tree.getCurrentTree())
3612 af.viewport.setCurrentTree(tp.getTree());
3616 } catch (Exception ex)
3618 ex.printStackTrace();
3623 * Load and link any saved structure viewers.
3630 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3631 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3634 * Run through all PDB ids on the alignment, and collect mappings between
3635 * distinct view ids and all sequences referring to that view.
3637 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3639 for (int i = 0; i < jseqs.length; i++)
3641 if (jseqs[i].getPdbidsCount() > 0)
3643 Pdbids[] ids = jseqs[i].getPdbids();
3644 for (int p = 0; p < ids.length; p++)
3646 final int structureStateCount = ids[p].getStructureStateCount();
3647 for (int s = 0; s < structureStateCount; s++)
3649 // check to see if we haven't already created this structure view
3650 final StructureState structureState = ids[p]
3651 .getStructureState(s);
3652 String sviewid = (structureState.getViewId() == null) ? null
3653 : structureState.getViewId() + uniqueSetSuffix;
3654 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3655 // Originally : ids[p].getFile()
3656 // : TODO: verify external PDB file recovery still works in normal
3657 // jalview project load
3658 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3659 jpdb.setId(ids[p].getId());
3661 int x = structureState.getXpos();
3662 int y = structureState.getYpos();
3663 int width = structureState.getWidth();
3664 int height = structureState.getHeight();
3666 // Probably don't need to do this anymore...
3667 // Desktop.desktop.getComponentAt(x, y);
3668 // TODO: NOW: check that this recovers the PDB file correctly.
3669 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3670 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3672 if (sviewid == null)
3674 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3677 if (!structureViewers.containsKey(sviewid))
3679 structureViewers.put(sviewid,
3680 new StructureViewerModel(x, y, width, height, false,
3681 false, true, structureState.getViewId(),
3682 structureState.getType()));
3683 // Legacy pre-2.7 conversion JAL-823 :
3684 // do not assume any view has to be linked for colour by
3688 // assemble String[] { pdb files }, String[] { id for each
3689 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3690 // seqs_file 2}, boolean[] {
3691 // linkAlignPanel,superposeWithAlignpanel}} from hash
3692 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3693 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3694 | (structureState.hasAlignwithAlignPanel() ? structureState
3695 .getAlignwithAlignPanel() : false));
3698 * Default colour by linked panel to false if not specified (e.g.
3699 * for pre-2.7 projects)
3701 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3702 colourWithAlignPanel |= (structureState
3703 .hasColourwithAlignPanel() ? structureState
3704 .getColourwithAlignPanel() : false);
3705 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3708 * Default colour by viewer to true if not specified (e.g. for
3711 boolean colourByViewer = jmoldat.isColourByViewer();
3712 colourByViewer &= structureState.hasColourByJmol() ? structureState
3713 .getColourByJmol() : true;
3714 jmoldat.setColourByViewer(colourByViewer);
3716 if (jmoldat.getStateData().length() < structureState
3717 .getContent().length())
3720 jmoldat.setStateData(structureState.getContent());
3723 if (ids[p].getFile() != null)
3725 File mapkey = new File(ids[p].getFile());
3726 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3727 if (seqstrmaps == null)
3729 jmoldat.getFileData().put(
3731 seqstrmaps = jmoldat.new StructureData(pdbFile,
3734 if (!seqstrmaps.getSeqList().contains(seq))
3736 seqstrmaps.getSeqList().add(seq);
3742 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");
3749 // Instantiate the associated structure views
3750 for (Entry<String, StructureViewerModel> entry : structureViewers
3755 createOrLinkStructureViewer(entry, af, ap, jprovider);
3756 } catch (Exception e)
3758 System.err.println("Error loading structure viewer: "
3760 // failed - try the next one
3772 protected void createOrLinkStructureViewer(
3773 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3774 AlignmentPanel ap, jarInputStreamProvider jprovider)
3776 final StructureViewerModel stateData = viewerData.getValue();
3779 * Search for any viewer windows already open from other alignment views
3780 * that exactly match the stored structure state
3782 StructureViewerBase comp = findMatchingViewer(viewerData);
3786 linkStructureViewer(ap, comp, stateData);
3791 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3792 * "viewer_"+stateData.viewId
3794 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3796 createChimeraViewer(viewerData, af, jprovider);
3801 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3803 createJmolViewer(viewerData, af, jprovider);
3808 * Create a new Chimera viewer.
3814 protected void createChimeraViewer(
3815 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3816 jarInputStreamProvider jprovider)
3818 StructureViewerModel data = viewerData.getValue();
3819 String chimeraSessionFile = data.getStateData();
3822 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3824 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3825 * 'uniquified' sviewid used to reconstruct the viewer here
3827 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3828 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3831 Set<Entry<File, StructureData>> fileData = data.getFileData()
3833 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3834 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3835 for (Entry<File, StructureData> pdb : fileData)
3837 String filePath = pdb.getValue().getFilePath();
3838 String pdbId = pdb.getValue().getPdbId();
3839 // pdbs.add(new PDBEntry(filePath, pdbId));
3840 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3841 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3842 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3846 boolean colourByChimera = data.isColourByViewer();
3847 boolean colourBySequence = data.isColourWithAlignPanel();
3849 // TODO use StructureViewer as a factory here, see JAL-1761
3850 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3851 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3853 String newViewId = viewerData.getKey();
3855 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3856 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3857 colourBySequence, newViewId);
3858 cvf.setSize(data.getWidth(), data.getHeight());
3859 cvf.setLocation(data.getX(), data.getY());
3863 * Create a new Jmol window. First parse the Jmol state to translate filenames
3864 * loaded into the view, and record the order in which files are shown in the
3865 * Jmol view, so we can add the sequence mappings in same order.
3871 protected void createJmolViewer(
3872 final Entry<String, StructureViewerModel> viewerData,
3873 AlignFrame af, jarInputStreamProvider jprovider)
3875 final StructureViewerModel svattrib = viewerData.getValue();
3876 String state = svattrib.getStateData();
3879 * Pre-2.9: state element value is the Jmol state string
3881 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3884 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3886 state = readJarEntry(jprovider,
3887 getViewerJarEntryName(svattrib.getViewId()));
3890 List<String> pdbfilenames = new ArrayList<String>();
3891 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3892 List<String> pdbids = new ArrayList<String>();
3893 StringBuilder newFileLoc = new StringBuilder(64);
3894 int cp = 0, ncp, ecp;
3895 Map<File, StructureData> oldFiles = svattrib.getFileData();
3896 while ((ncp = state.indexOf("load ", cp)) > -1)
3900 // look for next filename in load statement
3901 newFileLoc.append(state.substring(cp,
3902 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3903 String oldfilenam = state.substring(ncp,
3904 ecp = state.indexOf("\"", ncp));
3905 // recover the new mapping data for this old filename
3906 // have to normalize filename - since Jmol and jalview do
3908 // translation differently.
3909 StructureData filedat = oldFiles.get(new File(oldfilenam));
3910 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3911 pdbfilenames.add(filedat.getFilePath());
3912 pdbids.add(filedat.getPdbId());
3913 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3914 newFileLoc.append("\"");
3915 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3916 // look for next file statement.
3917 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3921 // just append rest of state
3922 newFileLoc.append(state.substring(cp));
3926 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3927 newFileLoc = new StringBuilder(state);
3928 newFileLoc.append("; load append ");
3929 for (File id : oldFiles.keySet())
3931 // add this and any other pdb files that should be present in
3933 StructureData filedat = oldFiles.get(id);
3934 newFileLoc.append(filedat.getFilePath());
3935 pdbfilenames.add(filedat.getFilePath());
3936 pdbids.add(filedat.getPdbId());
3937 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3938 newFileLoc.append(" \"");
3939 newFileLoc.append(filedat.getFilePath());
3940 newFileLoc.append("\"");
3943 newFileLoc.append(";");
3946 if (newFileLoc.length() == 0)
3950 int histbug = newFileLoc.indexOf("history = ");
3954 * change "history = [true|false];" to "history = [1|0];"
3957 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3958 String val = (diff == -1) ? null : newFileLoc
3959 .substring(histbug, diff);
3960 if (val != null && val.length() >= 4)
3962 if (val.contains("e")) // eh? what can it be?
3964 if (val.trim().equals("true"))
3972 newFileLoc.replace(histbug, diff, val);
3977 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3979 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3980 final SequenceI[][] sq = seqmaps
3981 .toArray(new SequenceI[seqmaps.size()][]);
3982 final String fileloc = newFileLoc.toString();
3983 final String sviewid = viewerData.getKey();
3984 final AlignFrame alf = af;
3985 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3986 svattrib.getWidth(), svattrib.getHeight());
3989 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3994 JalviewStructureDisplayI sview = null;
3997 sview = new StructureViewer(alf.alignPanel
3998 .getStructureSelectionManager()).createView(
3999 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4000 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4001 addNewStructureViewer(sview);
4002 } catch (OutOfMemoryError ex)
4004 new OOMWarning("restoring structure view for PDB id " + id,
4005 (OutOfMemoryError) ex.getCause());
4006 if (sview != null && sview.isVisible())
4008 sview.closeViewer(false);
4009 sview.setVisible(false);
4015 } catch (InvocationTargetException ex)
4017 warn("Unexpected error when opening Jmol view.", ex);
4019 } catch (InterruptedException e)
4021 // e.printStackTrace();
4027 * Generates a name for the entry in the project jar file to hold state
4028 * information for a structure viewer
4033 protected String getViewerJarEntryName(String viewId)
4035 return VIEWER_PREFIX + viewId;
4039 * Returns any open frame that matches given structure viewer data. The match
4040 * is based on the unique viewId, or (for older project versions) the frame's
4046 protected StructureViewerBase findMatchingViewer(
4047 Entry<String, StructureViewerModel> viewerData)
4049 final String sviewid = viewerData.getKey();
4050 final StructureViewerModel svattrib = viewerData.getValue();
4051 StructureViewerBase comp = null;
4052 JInternalFrame[] frames = getAllFrames();
4053 for (JInternalFrame frame : frames)
4055 if (frame instanceof StructureViewerBase)
4058 * Post jalview 2.4 schema includes structure view id
4061 && ((StructureViewerBase) frame).getViewId()
4064 comp = (StructureViewerBase) frame;
4065 break; // break added in 2.9
4068 * Otherwise test for matching position and size of viewer frame
4070 else if (frame.getX() == svattrib.getX()
4071 && frame.getY() == svattrib.getY()
4072 && frame.getHeight() == svattrib.getHeight()
4073 && frame.getWidth() == svattrib.getWidth())
4075 comp = (StructureViewerBase) frame;
4076 // no break in faint hope of an exact match on viewId
4084 * Link an AlignmentPanel to an existing structure viewer.
4089 * @param useinViewerSuperpos
4090 * @param usetoColourbyseq
4091 * @param viewerColouring
4093 protected void linkStructureViewer(AlignmentPanel ap,
4094 StructureViewerBase viewer, StructureViewerModel stateData)
4096 // NOTE: if the jalview project is part of a shared session then
4097 // view synchronization should/could be done here.
4099 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4100 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4101 final boolean viewerColouring = stateData.isColourByViewer();
4102 Map<File, StructureData> oldFiles = stateData.getFileData();
4105 * Add mapping for sequences in this view to an already open viewer
4107 final AAStructureBindingModel binding = viewer.getBinding();
4108 for (File id : oldFiles.keySet())
4110 // add this and any other pdb files that should be present in the
4112 StructureData filedat = oldFiles.get(id);
4113 String pdbFile = filedat.getFilePath();
4114 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4115 binding.getSsm().setMapping(seq, null, pdbFile,
4116 jalview.io.AppletFormatAdapter.FILE);
4117 binding.addSequenceForStructFile(pdbFile, seq);
4119 // and add the AlignmentPanel's reference to the view panel
4120 viewer.addAlignmentPanel(ap);
4121 if (useinViewerSuperpos)
4123 viewer.useAlignmentPanelForSuperposition(ap);
4127 viewer.excludeAlignmentPanelForSuperposition(ap);
4129 if (usetoColourbyseq)
4131 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4135 viewer.excludeAlignmentPanelForColourbyseq(ap);
4140 * Get all frames within the Desktop.
4144 protected JInternalFrame[] getAllFrames()
4146 JInternalFrame[] frames = null;
4147 // TODO is this necessary - is it safe - risk of hanging?
4152 frames = Desktop.desktop.getAllFrames();
4153 } catch (ArrayIndexOutOfBoundsException e)
4155 // occasional No such child exceptions are thrown here...
4159 } catch (InterruptedException f)
4163 } while (frames == null);
4168 * Answers true if 'version' is equal to or later than 'supported', where each
4169 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4170 * changes. Development and test values for 'version' are leniently treated
4174 * - minimum version we are comparing against
4176 * - version of data being processsed
4179 public static boolean isVersionStringLaterThan(String supported,
4182 if (supported == null || version == null
4183 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4184 || version.equalsIgnoreCase("Test")
4185 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4187 System.err.println("Assuming project file with "
4188 + (version == null ? "null" : version)
4189 + " is compatible with Jalview version " + supported);
4194 return StringUtils.compareVersions(version, supported, "b") >= 0;
4198 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4200 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4202 if (newStructureViewers != null)
4204 sview.getBinding().setFinishedLoadingFromArchive(false);
4205 newStructureViewers.add(sview);
4209 protected void setLoadingFinishedForNewStructureViewers()
4211 if (newStructureViewers != null)
4213 for (JalviewStructureDisplayI sview : newStructureViewers)
4215 sview.getBinding().setFinishedLoadingFromArchive(true);
4217 newStructureViewers.clear();
4218 newStructureViewers = null;
4222 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4223 List<SequenceI> hiddenSeqs, AlignmentI al,
4224 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4225 String viewId, List<JvAnnotRow> autoAlan)
4227 AlignFrame af = null;
4228 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4229 uniqueSeqSetId, viewId);
4231 af.setFileName(file, "Jalview");
4233 for (int i = 0; i < JSEQ.length; i++)
4235 af.viewport.setSequenceColour(af.viewport.getAlignment()
4236 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4241 af.getViewport().setColourByReferenceSeq(true);
4242 af.getViewport().setDisplayReferenceSeq(true);
4245 af.viewport.setGatherViewsHere(view.getGatheredViews());
4247 if (view.getSequenceSetId() != null)
4249 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4251 af.viewport.setSequenceSetId(uniqueSeqSetId);
4254 // propagate shared settings to this new view
4255 af.viewport.setHistoryList(av.getHistoryList());
4256 af.viewport.setRedoList(av.getRedoList());
4260 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4262 // TODO: check if this method can be called repeatedly without
4263 // side-effects if alignpanel already registered.
4264 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4266 // apply Hidden regions to view.
4267 if (hiddenSeqs != null)
4269 for (int s = 0; s < JSEQ.length; s++)
4271 SequenceGroup hidden = new SequenceGroup();
4272 boolean isRepresentative = false;
4273 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4275 isRepresentative = true;
4276 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4277 .getHiddenSequences(r));
4278 hidden.addSequence(sequenceToHide, false);
4279 // remove from hiddenSeqs list so we don't try to hide it twice
4280 hiddenSeqs.remove(sequenceToHide);
4282 if (isRepresentative)
4284 SequenceI representativeSequence = al.getSequenceAt(s);
4285 hidden.addSequence(representativeSequence, false);
4286 af.viewport.hideRepSequences(representativeSequence, hidden);
4290 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4292 af.viewport.hideSequence(hseqs);
4295 // recover view properties and display parameters
4296 if (view.getViewName() != null)
4298 af.viewport.viewName = view.getViewName();
4299 af.setInitialTabVisible();
4301 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4304 af.viewport.setShowAnnotation(view.getShowAnnotation());
4305 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4307 af.viewport.setColourText(view.getShowColourText());
4309 af.viewport.setConservationSelected(view.getConservationSelected());
4310 af.viewport.setShowJVSuffix(view.getShowFullId());
4311 af.viewport.setRightAlignIds(view.getRightAlignIds());
4312 af.viewport.setFont(
4313 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4314 .getFontSize()), true);
4315 ViewStyleI vs = af.viewport.getViewStyle();
4316 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4317 af.viewport.setViewStyle(vs);
4318 // TODO: allow custom charWidth/Heights to be restored by updating them
4319 // after setting font - which means set above to false
4320 af.viewport.setRenderGaps(view.getRenderGaps());
4321 af.viewport.setWrapAlignment(view.getWrapAlignment());
4322 af.viewport.setShowAnnotation(view.getShowAnnotation());
4324 af.viewport.setShowBoxes(view.getShowBoxes());
4326 af.viewport.setShowText(view.getShowText());
4328 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4329 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4330 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4331 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4332 .isShowUnconserved() : false);
4333 af.viewport.setStartRes(view.getStartRes());
4334 af.viewport.setStartSeq(view.getStartSeq());
4335 af.alignPanel.updateLayout();
4336 ColourSchemeI cs = null;
4337 // apply colourschemes
4338 if (view.getBgColour() != null)
4340 if (view.getBgColour().startsWith("ucs"))
4342 cs = getUserColourScheme(jms, view.getBgColour());
4344 else if (view.getBgColour().startsWith("Annotation"))
4346 AnnotationColours viewAnnColour = view.getAnnotationColours();
4347 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4354 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4359 cs.setThreshold(view.getPidThreshold(), true);
4360 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4364 af.viewport.setGlobalColourScheme(cs);
4365 af.viewport.setColourAppliesToAllGroups(false);
4367 if (view.getConservationSelected() && cs != null)
4369 cs.setConservationInc(view.getConsThreshold());
4372 af.changeColour(cs);
4374 af.viewport.setColourAppliesToAllGroups(true);
4376 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4378 if (view.hasCentreColumnLabels())
4380 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4382 if (view.hasIgnoreGapsinConsensus())
4384 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4387 if (view.hasFollowHighlight())
4389 af.viewport.setFollowHighlight(view.getFollowHighlight());
4391 if (view.hasFollowSelection())
4393 af.viewport.followSelection = view.getFollowSelection();
4395 if (view.hasShowConsensusHistogram())
4397 af.viewport.setShowConsensusHistogram(view
4398 .getShowConsensusHistogram());
4402 af.viewport.setShowConsensusHistogram(true);
4404 if (view.hasShowSequenceLogo())
4406 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4410 af.viewport.setShowSequenceLogo(false);
4412 if (view.hasNormaliseSequenceLogo())
4414 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4416 if (view.hasShowDbRefTooltip())
4418 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4420 if (view.hasShowNPfeatureTooltip())
4422 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4424 if (view.hasShowGroupConsensus())
4426 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4430 af.viewport.setShowGroupConsensus(false);
4432 if (view.hasShowGroupConservation())
4434 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4438 af.viewport.setShowGroupConservation(false);
4441 // recover featre settings
4442 if (jms.getFeatureSettings() != null)
4444 FeaturesDisplayed fdi;
4445 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4446 String[] renderOrder = new String[jms.getFeatureSettings()
4447 .getSettingCount()];
4448 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4449 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4451 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4453 Setting setting = jms.getFeatureSettings().getSetting(fs);
4454 if (setting.hasMincolour())
4456 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4457 new Color(setting.getMincolour()), new Color(
4458 setting.getColour()), setting.getMin(),
4459 setting.getMax()) : new FeatureColour(new Color(
4460 setting.getMincolour()), new Color(setting.getColour()),
4462 if (setting.hasThreshold())
4464 gc.setThreshold(setting.getThreshold());
4465 int threshstate = setting.getThreshstate();
4466 // -1 = None, 0 = Below, 1 = Above threshold
4467 if (threshstate == 0)
4469 gc.setBelowThreshold(true);
4471 else if (threshstate == 1)
4473 gc.setAboveThreshold(true);
4476 gc.setAutoScaled(true); // default
4477 if (setting.hasAutoScale())
4479 gc.setAutoScaled(setting.getAutoScale());
4481 if (setting.hasColourByLabel())
4483 gc.setColourByLabel(setting.getColourByLabel());
4485 // and put in the feature colour table.
4486 featureColours.put(setting.getType(), gc);
4490 featureColours.put(setting.getType(), new FeatureColour(
4491 new Color(setting.getColour())));
4493 renderOrder[fs] = setting.getType();
4494 if (setting.hasOrder())
4496 featureOrder.put(setting.getType(), setting.getOrder());
4500 featureOrder.put(setting.getType(), new Float(fs
4501 / jms.getFeatureSettings().getSettingCount()));
4503 if (setting.getDisplay())
4505 fdi.setVisible(setting.getType());
4508 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4509 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4511 Group grp = jms.getFeatureSettings().getGroup(gs);
4512 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4514 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4515 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4516 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4517 FeatureRendererSettings frs = new FeatureRendererSettings(
4518 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4519 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4520 .transferSettings(frs);
4524 if (view.getHiddenColumnsCount() > 0)
4526 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4528 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4529 .getHiddenColumns(c).getEnd() // +1
4533 if (view.getCalcIdParam() != null)
4535 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4537 if (calcIdParam != null)
4539 if (recoverCalcIdParam(calcIdParam, af.viewport))
4544 warn("Couldn't recover parameters for "
4545 + calcIdParam.getCalcId());
4550 af.setMenusFromViewport(af.viewport);
4551 af.setTitle(view.getTitle());
4552 // TODO: we don't need to do this if the viewport is aready visible.
4554 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4555 * has a 'cdna/protein complement' view, in which case save it in order to
4556 * populate a SplitFrame once all views have been read in.
4558 String complementaryViewId = view.getComplementId();
4559 if (complementaryViewId == null)
4561 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4563 // recompute any autoannotation
4564 af.alignPanel.updateAnnotation(false, true);
4565 reorderAutoannotation(af, al, autoAlan);
4566 af.alignPanel.alignmentChanged();
4570 splitFrameCandidates.put(view, af);
4575 private ColourSchemeI constructAnnotationColour(
4576 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4577 JalviewModelSequence jms, boolean checkGroupAnnColour)
4579 boolean propagateAnnColour = false;
4580 ColourSchemeI cs = null;
4581 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4582 if (checkGroupAnnColour && al.getGroups() != null
4583 && al.getGroups().size() > 0)
4585 // pre 2.8.1 behaviour
4586 // check to see if we should transfer annotation colours
4587 propagateAnnColour = true;
4588 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4590 if (sg.cs instanceof AnnotationColourGradient)
4592 propagateAnnColour = false;
4596 // int find annotation
4597 if (annAlignment.getAlignmentAnnotation() != null)
4599 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4601 if (annAlignment.getAlignmentAnnotation()[i].label
4602 .equals(viewAnnColour.getAnnotation()))
4604 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4606 annAlignment.getAlignmentAnnotation()[i]
4607 .setThreshold(new jalview.datamodel.GraphLine(
4608 viewAnnColour.getThreshold(), "Threshold",
4609 java.awt.Color.black)
4614 if (viewAnnColour.getColourScheme().equals("None"))
4616 cs = new AnnotationColourGradient(
4617 annAlignment.getAlignmentAnnotation()[i],
4618 new java.awt.Color(viewAnnColour.getMinColour()),
4619 new java.awt.Color(viewAnnColour.getMaxColour()),
4620 viewAnnColour.getAboveThreshold());
4622 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4624 cs = new AnnotationColourGradient(
4625 annAlignment.getAlignmentAnnotation()[i],
4626 getUserColourScheme(jms,
4627 viewAnnColour.getColourScheme()),
4628 viewAnnColour.getAboveThreshold());
4632 cs = new AnnotationColourGradient(
4633 annAlignment.getAlignmentAnnotation()[i],
4634 ColourSchemeProperty.getColour(al,
4635 viewAnnColour.getColourScheme()),
4636 viewAnnColour.getAboveThreshold());
4638 if (viewAnnColour.hasPerSequence())
4640 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4643 if (viewAnnColour.hasPredefinedColours())
4645 ((AnnotationColourGradient) cs)
4646 .setPredefinedColours(viewAnnColour
4647 .isPredefinedColours());
4649 if (propagateAnnColour && al.getGroups() != null)
4651 // Also use these settings for all the groups
4652 for (int g = 0; g < al.getGroups().size(); g++)
4654 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4662 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4663 * new AnnotationColourGradient(
4664 * annAlignment.getAlignmentAnnotation()[i], new
4665 * java.awt.Color(viewAnnColour. getMinColour()), new
4666 * java.awt.Color(viewAnnColour. getMaxColour()),
4667 * viewAnnColour.getAboveThreshold()); } else
4670 sg.cs = new AnnotationColourGradient(
4671 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4672 viewAnnColour.getAboveThreshold());
4673 if (cs instanceof AnnotationColourGradient)
4675 if (viewAnnColour.hasPerSequence())
4677 ((AnnotationColourGradient) cs)
4678 .setSeqAssociated(viewAnnColour.isPerSequence());
4680 if (viewAnnColour.hasPredefinedColours())
4682 ((AnnotationColourGradient) cs)
4683 .setPredefinedColours(viewAnnColour
4684 .isPredefinedColours());
4700 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4701 List<JvAnnotRow> autoAlan)
4703 // copy over visualization settings for autocalculated annotation in the
4705 if (al.getAlignmentAnnotation() != null)
4708 * Kludge for magic autoannotation names (see JAL-811)
4710 String[] magicNames = new String[] { "Consensus", "Quality",
4712 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4713 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4714 for (String nm : magicNames)
4716 visan.put(nm, nullAnnot);
4718 for (JvAnnotRow auan : autoAlan)
4720 visan.put(auan.template.label
4721 + (auan.template.getCalcId() == null ? "" : "\t"
4722 + auan.template.getCalcId()), auan);
4724 int hSize = al.getAlignmentAnnotation().length;
4725 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4726 // work through any autoCalculated annotation already on the view
4727 // removing it if it should be placed in a different location on the
4728 // annotation panel.
4729 List<String> remains = new ArrayList<String>(visan.keySet());
4730 for (int h = 0; h < hSize; h++)
4732 jalview.datamodel.AlignmentAnnotation jalan = al
4733 .getAlignmentAnnotation()[h];
4734 if (jalan.autoCalculated)
4737 JvAnnotRow valan = visan.get(k = jalan.label);
4738 if (jalan.getCalcId() != null)
4740 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4745 // delete the auto calculated row from the alignment
4746 al.deleteAnnotation(jalan, false);
4750 if (valan != nullAnnot)
4752 if (jalan != valan.template)
4754 // newly created autoannotation row instance
4755 // so keep a reference to the visible annotation row
4756 // and copy over all relevant attributes
4757 if (valan.template.graphHeight >= 0)
4760 jalan.graphHeight = valan.template.graphHeight;
4762 jalan.visible = valan.template.visible;
4764 reorder.add(new JvAnnotRow(valan.order, jalan));
4769 // Add any (possibly stale) autocalculated rows that were not appended to
4770 // the view during construction
4771 for (String other : remains)
4773 JvAnnotRow othera = visan.get(other);
4774 if (othera != nullAnnot && othera.template.getCalcId() != null
4775 && othera.template.getCalcId().length() > 0)
4777 reorder.add(othera);
4780 // now put the automatic annotation in its correct place
4781 int s = 0, srt[] = new int[reorder.size()];
4782 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4783 for (JvAnnotRow jvar : reorder)
4786 srt[s++] = jvar.order;
4789 jalview.util.QuickSort.sort(srt, rws);
4790 // and re-insert the annotation at its correct position
4791 for (JvAnnotRow jvar : rws)
4793 al.addAnnotation(jvar.template, jvar.order);
4795 af.alignPanel.adjustAnnotationHeight();
4799 Hashtable skipList = null;
4802 * TODO remove this method
4805 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4806 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4807 * throw new Error("Implementation Error. No skipList defined for this
4808 * Jalview2XML instance."); } return (AlignFrame)
4809 * skipList.get(view.getSequenceSetId()); }
4813 * Check if the Jalview view contained in object should be skipped or not.
4816 * @return true if view's sequenceSetId is a key in skipList
4818 private boolean skipViewport(JalviewModel object)
4820 if (skipList == null)
4825 if (skipList.containsKey(id = object.getJalviewModelSequence()
4826 .getViewport()[0].getSequenceSetId()))
4828 if (Cache.log != null && Cache.log.isDebugEnabled())
4830 Cache.log.debug("Skipping seuqence set id " + id);
4837 public void addToSkipList(AlignFrame af)
4839 if (skipList == null)
4841 skipList = new Hashtable();
4843 skipList.put(af.getViewport().getSequenceSetId(), af);
4846 public void clearSkipList()
4848 if (skipList != null)
4855 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4856 boolean ignoreUnrefed)
4858 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4860 Vector dseqs = null;
4863 // create a list of new dataset sequences
4864 dseqs = new Vector();
4866 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4868 Sequence vamsasSeq = vamsasSet.getSequence(i);
4869 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4871 // create a new dataset
4874 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4875 dseqs.copyInto(dsseqs);
4876 ds = new jalview.datamodel.Alignment(dsseqs);
4877 debug("Created new dataset " + vamsasSet.getDatasetId()
4878 + " for alignment " + System.identityHashCode(al));
4879 addDatasetRef(vamsasSet.getDatasetId(), ds);
4881 // set the dataset for the newly imported alignment.
4882 if (al.getDataset() == null && !ignoreUnrefed)
4891 * sequence definition to create/merge dataset sequence for
4895 * vector to add new dataset sequence to
4897 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4898 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4900 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4902 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4903 SequenceI dsq = null;
4904 if (sq != null && sq.getDatasetSequence() != null)
4906 dsq = sq.getDatasetSequence();
4908 if (sq == null && ignoreUnrefed)
4912 String sqid = vamsasSeq.getDsseqid();
4915 // need to create or add a new dataset sequence reference to this sequence
4918 dsq = seqRefIds.get(sqid);
4923 // make a new dataset sequence
4924 dsq = sq.createDatasetSequence();
4927 // make up a new dataset reference for this sequence
4928 sqid = seqHash(dsq);
4930 dsq.setVamsasId(uniqueSetSuffix + sqid);
4931 seqRefIds.put(sqid, dsq);
4936 dseqs.addElement(dsq);
4941 ds.addSequence(dsq);
4947 { // make this dataset sequence sq's dataset sequence
4948 sq.setDatasetSequence(dsq);
4949 // and update the current dataset alignment
4954 if (!dseqs.contains(dsq))
4961 if (ds.findIndex(dsq) < 0)
4963 ds.addSequence(dsq);
4970 // TODO: refactor this as a merge dataset sequence function
4971 // now check that sq (the dataset sequence) sequence really is the union of
4972 // all references to it
4973 // boolean pre = sq.getStart() < dsq.getStart();
4974 // boolean post = sq.getEnd() > dsq.getEnd();
4978 // StringBuffer sb = new StringBuffer();
4979 String newres = jalview.analysis.AlignSeq.extractGaps(
4980 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4981 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4982 && newres.length() > dsq.getLength())
4984 // Update with the longer sequence.
4988 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4989 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4990 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4991 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4993 dsq.setSequence(newres);
4995 // TODO: merges will never happen if we 'know' we have the real dataset
4996 // sequence - this should be detected when id==dssid
4998 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4999 // + (pre ? "prepended" : "") + " "
5000 // + (post ? "appended" : ""));
5006 * TODO use AlignmentI here and in related methods - needs
5007 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5009 Hashtable<String, AlignmentI> datasetIds = null;
5011 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5013 private AlignmentI getDatasetFor(String datasetId)
5015 if (datasetIds == null)
5017 datasetIds = new Hashtable<String, AlignmentI>();
5020 if (datasetIds.containsKey(datasetId))
5022 return datasetIds.get(datasetId);
5027 private void addDatasetRef(String datasetId, AlignmentI dataset)
5029 if (datasetIds == null)
5031 datasetIds = new Hashtable<String, AlignmentI>();
5033 datasetIds.put(datasetId, dataset);
5037 * make a new dataset ID for this jalview dataset alignment
5042 private String getDatasetIdRef(AlignmentI dataset)
5044 if (dataset.getDataset() != null)
5046 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5048 String datasetId = makeHashCode(dataset, null);
5049 if (datasetId == null)
5051 // make a new datasetId and record it
5052 if (dataset2Ids == null)
5054 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5058 datasetId = dataset2Ids.get(dataset);
5060 if (datasetId == null)
5062 datasetId = "ds" + dataset2Ids.size() + 1;
5063 dataset2Ids.put(dataset, datasetId);
5069 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5071 for (int d = 0; d < sequence.getDBRefCount(); d++)
5073 DBRef dr = sequence.getDBRef(d);
5074 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5075 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5076 .getVersion(), sequence.getDBRef(d).getAccessionId());
5077 if (dr.getMapping() != null)
5079 entry.setMap(addMapping(dr.getMapping()));
5081 datasetSequence.addDBRef(entry);
5085 private jalview.datamodel.Mapping addMapping(Mapping m)
5087 SequenceI dsto = null;
5088 // Mapping m = dr.getMapping();
5089 int fr[] = new int[m.getMapListFromCount() * 2];
5090 Enumeration f = m.enumerateMapListFrom();
5091 for (int _i = 0; f.hasMoreElements(); _i += 2)
5093 MapListFrom mf = (MapListFrom) f.nextElement();
5094 fr[_i] = mf.getStart();
5095 fr[_i + 1] = mf.getEnd();
5097 int fto[] = new int[m.getMapListToCount() * 2];
5098 f = m.enumerateMapListTo();
5099 for (int _i = 0; f.hasMoreElements(); _i += 2)
5101 MapListTo mf = (MapListTo) f.nextElement();
5102 fto[_i] = mf.getStart();
5103 fto[_i + 1] = mf.getEnd();
5105 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5106 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5107 if (m.getMappingChoice() != null)
5109 MappingChoice mc = m.getMappingChoice();
5110 if (mc.getDseqFor() != null)
5112 String dsfor = "" + mc.getDseqFor();
5113 if (seqRefIds.containsKey(dsfor))
5118 jmap.setTo(seqRefIds.get(dsfor));
5122 frefedSequence.add(newMappingRef(dsfor, jmap));
5128 * local sequence definition
5130 Sequence ms = mc.getSequence();
5131 SequenceI djs = null;
5132 String sqid = ms.getDsseqid();
5133 if (sqid != null && sqid.length() > 0)
5136 * recover dataset sequence
5138 djs = seqRefIds.get(sqid);
5143 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5144 sqid = ((Object) ms).toString(); // make up a new hascode for
5145 // undefined dataset sequence hash
5146 // (unlikely to happen)
5152 * make a new dataset sequence and add it to refIds hash
5154 djs = new jalview.datamodel.Sequence(ms.getName(),
5156 djs.setStart(jmap.getMap().getToLowest());
5157 djs.setEnd(jmap.getMap().getToHighest());
5158 djs.setVamsasId(uniqueSetSuffix + sqid);
5160 incompleteSeqs.put(sqid, djs);
5161 seqRefIds.put(sqid, djs);
5164 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5173 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5174 boolean keepSeqRefs)
5177 JalviewModel jm = saveState(ap, null, null, null);
5182 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5186 uniqueSetSuffix = "";
5187 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5192 if (this.frefedSequence == null)
5194 frefedSequence = new Vector();
5197 viewportsAdded.clear();
5199 AlignFrame af = loadFromObject(jm, null, false, null);
5200 af.alignPanels.clear();
5201 af.closeMenuItem_actionPerformed(true);
5204 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5205 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5206 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5207 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5208 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5211 return af.alignPanel;
5215 * flag indicating if hashtables should be cleared on finalization TODO this
5216 * flag may not be necessary
5218 private final boolean _cleartables = true;
5220 private Hashtable jvids2vobj;
5225 * @see java.lang.Object#finalize()
5228 protected void finalize() throws Throwable
5230 // really make sure we have no buried refs left.
5235 this.seqRefIds = null;
5236 this.seqsToIds = null;
5240 private void warn(String msg)
5245 private void warn(String msg, Exception e)
5247 if (Cache.log != null)
5251 Cache.log.warn(msg, e);
5255 Cache.log.warn(msg);
5260 System.err.println("Warning: " + msg);
5263 e.printStackTrace();
5268 private void debug(String string)
5270 debug(string, null);
5273 private void debug(String msg, Exception e)
5275 if (Cache.log != null)
5279 Cache.log.debug(msg, e);
5283 Cache.log.debug(msg);
5288 System.err.println("Warning: " + msg);
5291 e.printStackTrace();
5297 * set the object to ID mapping tables used to write/recover objects and XML
5298 * ID strings for the jalview project. If external tables are provided then
5299 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5300 * object goes out of scope. - also populates the datasetIds hashtable with
5301 * alignment objects containing dataset sequences
5304 * Map from ID strings to jalview datamodel
5306 * Map from jalview datamodel to ID strings
5310 public void setObjectMappingTables(Hashtable vobj2jv,
5311 IdentityHashMap jv2vobj)
5313 this.jv2vobj = jv2vobj;
5314 this.vobj2jv = vobj2jv;
5315 Iterator ds = jv2vobj.keySet().iterator();
5317 while (ds.hasNext())
5319 Object jvobj = ds.next();
5320 id = jv2vobj.get(jvobj).toString();
5321 if (jvobj instanceof jalview.datamodel.Alignment)
5323 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5325 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5328 else if (jvobj instanceof jalview.datamodel.Sequence)
5330 // register sequence object so the XML parser can recover it.
5331 if (seqRefIds == null)
5333 seqRefIds = new HashMap<String, SequenceI>();
5335 if (seqsToIds == null)
5337 seqsToIds = new IdentityHashMap<SequenceI, String>();
5339 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5340 seqsToIds.put((SequenceI) jvobj, id);
5342 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5345 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5346 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5347 if (jvann.annotationId == null)
5349 jvann.annotationId = anid;
5351 if (!jvann.annotationId.equals(anid))
5353 // TODO verify that this is the correct behaviour
5354 this.warn("Overriding Annotation ID for " + anid
5355 + " from different id : " + jvann.annotationId);
5356 jvann.annotationId = anid;
5359 else if (jvobj instanceof String)
5361 if (jvids2vobj == null)
5363 jvids2vobj = new Hashtable();
5364 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5369 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5375 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5376 * objects created from the project archive. If string is null (default for
5377 * construction) then suffix will be set automatically.
5381 public void setUniqueSetSuffix(String string)
5383 uniqueSetSuffix = string;
5388 * uses skipList2 as the skipList for skipping views on sequence sets
5389 * associated with keys in the skipList
5393 public void setSkipList(Hashtable skipList2)
5395 skipList = skipList2;
5399 * Reads the jar entry of given name and returns its contents, or null if the
5400 * entry is not found.
5403 * @param jarEntryName
5406 protected String readJarEntry(jarInputStreamProvider jprovider,
5407 String jarEntryName)
5409 String result = null;
5410 BufferedReader in = null;
5415 * Reopen the jar input stream and traverse its entries to find a matching
5418 JarInputStream jin = jprovider.getJarInputStream();
5419 JarEntry entry = null;
5422 entry = jin.getNextJarEntry();
5423 } while (entry != null && !entry.getName().equals(jarEntryName));
5427 StringBuilder out = new StringBuilder(256);
5428 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5431 while ((data = in.readLine()) != null)
5435 result = out.toString();
5439 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5441 } catch (Exception ex)
5443 ex.printStackTrace();
5451 } catch (IOException e)
5462 * Returns an incrementing counter (0, 1, 2...)
5466 private synchronized int nextCounter()