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
281 public SeqFref(String _sref)
286 public String getSref()
291 public SequenceI getSrefSeq()
293 return seqRefIds.get(sref);
296 public boolean isResolvable()
298 return seqRefIds.get(sref) != null;
301 public SequenceI getSrefDatasetSeq()
303 SequenceI sq = seqRefIds.get(sref);
306 while (sq.getDatasetSequence() != null)
308 sq = sq.getDatasetSequence();
314 * @return true if the forward reference was fully resolved
316 abstract boolean resolve();
320 * create forward reference for a mapping
326 public SeqFref newMappingRef(final String sref,
327 final jalview.datamodel.Mapping _jmap)
329 SeqFref fref = new SeqFref(sref)
331 public jalview.datamodel.Mapping jmap = _jmap;
336 SequenceI seq = getSrefDatasetSeq();
348 public SeqFref newAlcodMapRef(final String sref,
349 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
352 SeqFref fref = new SeqFref(sref)
354 AlignedCodonFrame cf = _cf;
356 public jalview.datamodel.Mapping mp = _jmap;
361 SequenceI seq = getSrefDatasetSeq();
366 cf.addMap(seq, mp.getTo(), mp.getMap());
373 public void resolveFrefedSequences()
375 Iterator<SeqFref> nextFref=frefedSequence.iterator();
376 int toresolve=frefedSequence.size();
377 int unresolved=0,failedtoresolve=0;
378 while (nextFref.hasNext()) {
379 SeqFref ref = nextFref.next();
380 if (ref.isResolvable())
389 } catch (Exception x) {
390 System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
400 System.err.println("Jalview Project Import: There were " + unresolved
401 + " forward references left unresolved on the stack.");
403 if (failedtoresolve>0)
405 System.err.println("SERIOUS! " + failedtoresolve
406 + " resolvable forward references failed to resolve.");
408 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
410 System.err.println("Jalview Project Import: There are "
411 + incompleteSeqs.size()
412 + " sequences which may have incomplete metadata.");
413 if (incompleteSeqs.size() < 10)
415 for (SequenceI s : incompleteSeqs.values())
417 System.err.println(s.toString());
423 .println("Too many to report. Skipping output of incomplete sequences.");
429 * This maintains a map of viewports, the key being the seqSetId. Important to
430 * set historyItem and redoList for multiple views
432 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
434 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
436 String uniqueSetSuffix = "";
439 * List of pdbfiles added to Jar
441 List<String> pdbfiles = null;
443 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
444 public void saveState(File statefile)
446 FileOutputStream fos = null;
449 fos = new FileOutputStream(statefile);
450 JarOutputStream jout = new JarOutputStream(fos);
453 } catch (Exception e)
455 // TODO: inform user of the problem - they need to know if their data was
457 if (errorMessage == null)
459 errorMessage = "Couldn't write Jalview Archive to output file '"
460 + statefile + "' - See console error log for details";
464 errorMessage += "(output file was '" + statefile + "')";
474 } catch (IOException e)
484 * Writes a jalview project archive to the given Jar output stream.
488 public void saveState(JarOutputStream jout)
490 AlignFrame[] frames = Desktop.getAlignFrames();
496 saveAllFrames(Arrays.asList(frames), jout);
500 * core method for storing state for a set of AlignFrames.
503 * - frames involving all data to be exported (including containing
506 * - project output stream
508 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
510 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
513 * ensure cached data is clear before starting
515 // todo tidy up seqRefIds, seqsToIds initialisation / reset
517 splitFrameCandidates.clear();
522 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
523 // //////////////////////////////////////////////////
525 List<String> shortNames = new ArrayList<String>();
526 List<String> viewIds = new ArrayList<String>();
529 for (int i = frames.size() - 1; i > -1; i--)
531 AlignFrame af = frames.get(i);
535 .containsKey(af.getViewport().getSequenceSetId()))
540 String shortName = makeFilename(af, shortNames);
542 int ap, apSize = af.alignPanels.size();
544 for (ap = 0; ap < apSize; ap++)
546 AlignmentPanel apanel = af.alignPanels.get(ap);
547 String fileName = apSize == 1 ? shortName : ap + shortName;
548 if (!fileName.endsWith(".xml"))
550 fileName = fileName + ".xml";
553 saveState(apanel, fileName, jout, viewIds);
555 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
557 if (!dsses.containsKey(dssid))
559 dsses.put(dssid, af);
564 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
570 } catch (Exception foo)
575 } catch (Exception ex)
577 // TODO: inform user of the problem - they need to know if their data was
579 if (errorMessage == null)
581 errorMessage = "Couldn't write Jalview Archive - see error output for details";
583 ex.printStackTrace();
588 * Generates a distinct file name, based on the title of the AlignFrame, by
589 * appending _n for increasing n until an unused name is generated. The new
590 * name (without its extension) is added to the list.
594 * @return the generated name, with .xml extension
596 protected String makeFilename(AlignFrame af, List<String> namesUsed)
598 String shortName = af.getTitle();
600 if (shortName.indexOf(File.separatorChar) > -1)
602 shortName = shortName.substring(shortName
603 .lastIndexOf(File.separatorChar) + 1);
608 while (namesUsed.contains(shortName))
610 if (shortName.endsWith("_" + (count - 1)))
612 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
615 shortName = shortName.concat("_" + count);
619 namesUsed.add(shortName);
621 if (!shortName.endsWith(".xml"))
623 shortName = shortName + ".xml";
628 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
629 public boolean saveAlignment(AlignFrame af, String jarFile,
634 FileOutputStream fos = new FileOutputStream(jarFile);
635 JarOutputStream jout = new JarOutputStream(fos);
636 List<AlignFrame> frames = new ArrayList<AlignFrame>();
641 saveAllFrames(frames, jout);
645 } catch (Exception foo)
651 } catch (Exception ex)
653 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
654 ex.printStackTrace();
659 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
660 String fileName, JarOutputStream jout)
663 for (String dssids : dsses.keySet())
665 AlignFrame _af = dsses.get(dssids);
666 String jfileName = fileName + " Dataset for " + _af.getTitle();
667 if (!jfileName.endsWith(".xml"))
669 jfileName = jfileName + ".xml";
671 saveState(_af.alignPanel, jfileName, true, jout, null);
676 * create a JalviewModel from an alignment view and marshall it to a
680 * panel to create jalview model for
682 * name of alignment panel written to output stream
689 public JalviewModel saveState(AlignmentPanel ap, String fileName,
690 JarOutputStream jout, List<String> viewIds)
692 return saveState(ap, fileName, false, jout, viewIds);
696 * create a JalviewModel from an alignment view and marshall it to a
700 * panel to create jalview model for
702 * name of alignment panel written to output stream
704 * when true, only write the dataset for the alignment, not the data
705 * associated with the view.
711 public JalviewModel saveState(AlignmentPanel ap, String fileName,
712 boolean storeDS, JarOutputStream jout, List<String> viewIds)
716 viewIds = new ArrayList<String>();
721 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
723 AlignViewport av = ap.av;
725 JalviewModel object = new JalviewModel();
726 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
728 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
729 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
730 "Development Build"));
733 * rjal is full height alignment, jal is actual alignment with full metadata
734 * but excludes hidden sequences.
736 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
738 if (av.hasHiddenRows())
740 rjal = jal.getHiddenSequences().getFullAlignment();
743 SequenceSet vamsasSet = new SequenceSet();
745 JalviewModelSequence jms = new JalviewModelSequence();
747 vamsasSet.setGapChar(jal.getGapCharacter() + "");
749 if (jal.getDataset() != null)
751 // dataset id is the dataset's hashcode
752 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
755 // switch jal and the dataset
756 jal = jal.getDataset();
760 if (jal.getProperties() != null)
762 Enumeration en = jal.getProperties().keys();
763 while (en.hasMoreElements())
765 String key = en.nextElement().toString();
766 SequenceSetProperties ssp = new SequenceSetProperties();
768 ssp.setValue(jal.getProperties().get(key).toString());
769 vamsasSet.addSequenceSetProperties(ssp);
774 Set<String> calcIdSet = new HashSet<String>();
777 for (final SequenceI jds : rjal.getSequences())
779 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
780 : jds.getDatasetSequence();
781 String id = seqHash(jds);
783 if (seqRefIds.get(id) != null)
785 // This happens for two reasons: 1. multiple views are being serialised.
786 // 2. the hashCode has collided with another sequence's code. This DOES
787 // HAPPEN! (PF00072.15.stk does this)
788 // JBPNote: Uncomment to debug writing out of files that do not read
789 // back in due to ArrayOutOfBoundExceptions.
790 // System.err.println("vamsasSeq backref: "+id+"");
791 // System.err.println(jds.getName()+"
792 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
793 // System.err.println("Hashcode: "+seqHash(jds));
794 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
795 // System.err.println(rsq.getName()+"
796 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
797 // System.err.println("Hashcode: "+seqHash(rsq));
801 vamsasSeq = createVamsasSequence(id, jds);
802 vamsasSet.addSequence(vamsasSeq);
803 seqRefIds.put(id, jds);
807 jseq.setStart(jds.getStart());
808 jseq.setEnd(jds.getEnd());
809 jseq.setColour(av.getSequenceColour(jds).getRGB());
811 jseq.setId(id); // jseq id should be a string not a number
814 // Store any sequences this sequence represents
815 if (av.hasHiddenRows())
817 // use rjal, contains the full height alignment
818 jseq.setHidden(av.getAlignment().getHiddenSequences()
821 if (av.isHiddenRepSequence(jds))
823 jalview.datamodel.SequenceI[] reps = av
824 .getRepresentedSequences(jds)
825 .getSequencesInOrder(rjal);
827 for (int h = 0; h < reps.length; h++)
831 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
836 // mark sequence as reference - if it is the reference for this view
839 jseq.setViewreference(jds == jal.getSeqrep());
843 // TODO: omit sequence features from each alignment view's XML dump if we
844 // are storing dataset
845 if (jds.getSequenceFeatures() != null)
847 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
849 while (index < sf.length)
851 Features features = new Features();
853 features.setBegin(sf[index].getBegin());
854 features.setEnd(sf[index].getEnd());
855 features.setDescription(sf[index].getDescription());
856 features.setType(sf[index].getType());
857 features.setFeatureGroup(sf[index].getFeatureGroup());
858 features.setScore(sf[index].getScore());
859 if (sf[index].links != null)
861 for (int l = 0; l < sf[index].links.size(); l++)
863 OtherData keyValue = new OtherData();
864 keyValue.setKey("LINK_" + l);
865 keyValue.setValue(sf[index].links.elementAt(l).toString());
866 features.addOtherData(keyValue);
869 if (sf[index].otherDetails != null)
872 Iterator<String> keys = sf[index].otherDetails.keySet()
874 while (keys.hasNext())
877 OtherData keyValue = new OtherData();
878 keyValue.setKey(key);
879 keyValue.setValue(sf[index].otherDetails.get(key).toString());
880 features.addOtherData(keyValue);
884 jseq.addFeatures(features);
889 if (jdatasq.getAllPDBEntries() != null)
891 Enumeration en = jdatasq.getAllPDBEntries().elements();
892 while (en.hasMoreElements())
894 Pdbids pdb = new Pdbids();
895 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
898 String pdbId = entry.getId();
900 pdb.setType(entry.getType());
903 * Store any structure views associated with this sequence. This
904 * section copes with duplicate entries in the project, so a dataset
905 * only view *should* be coped with sensibly.
907 // This must have been loaded, is it still visible?
908 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
909 String matchedFile = null;
910 for (int f = frames.length - 1; f > -1; f--)
912 if (frames[f] instanceof StructureViewerBase)
914 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
915 matchedFile = saveStructureState(ap, jds, pdb, entry,
916 viewIds, matchedFile, viewFrame);
918 * Only store each structure viewer's state once in the project
919 * jar. First time through only (storeDS==false)
921 String viewId = viewFrame.getViewId();
922 if (!storeDS && !viewIds.contains(viewId))
927 String viewerState = viewFrame.getStateInfo();
928 writeJarEntry(jout, getViewerJarEntryName(viewId),
929 viewerState.getBytes());
930 } catch (IOException e)
932 System.err.println("Error saving viewer state: "
939 if (matchedFile != null || entry.getFile() != null)
941 if (entry.getFile() != null)
944 matchedFile = entry.getFile();
946 pdb.setFile(matchedFile); // entry.getFile());
947 if (pdbfiles == null)
949 pdbfiles = new ArrayList<String>();
952 if (!pdbfiles.contains(pdbId))
955 copyFileToJar(jout, matchedFile, pdbId);
959 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
961 PdbentryItem item = new PdbentryItem();
962 Hashtable properties = entry.getProperty();
963 Enumeration en2 = properties.keys();
964 while (en2.hasMoreElements())
966 Property prop = new Property();
967 String key = en2.nextElement().toString();
969 prop.setValue(properties.get(key).toString());
970 item.addProperty(prop);
972 pdb.addPdbentryItem(item);
979 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
984 if (!storeDS && av.hasHiddenRows())
986 jal = av.getAlignment();
989 if (jal.getCodonFrames() != null)
991 List<AlignedCodonFrame> jac = jal.getCodonFrames();
992 for (AlignedCodonFrame acf : jac)
994 AlcodonFrame alc = new AlcodonFrame();
995 if (acf.getProtMappings() != null
996 && acf.getProtMappings().length > 0)
998 boolean hasMap = false;
999 SequenceI[] dnas = acf.getdnaSeqs();
1000 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1001 for (int m = 0; m < pmaps.length; m++)
1003 AlcodMap alcmap = new AlcodMap();
1004 alcmap.setDnasq(seqHash(dnas[m]));
1005 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1007 alc.addAlcodMap(alcmap);
1012 vamsasSet.addAlcodonFrame(alc);
1015 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1017 // AlcodonFrame alc = new AlcodonFrame();
1018 // vamsasSet.addAlcodonFrame(alc);
1019 // for (int p = 0; p < acf.aaWidth; p++)
1021 // Alcodon cmap = new Alcodon();
1022 // if (acf.codons[p] != null)
1024 // // Null codons indicate a gapped column in the translated peptide
1026 // cmap.setPos1(acf.codons[p][0]);
1027 // cmap.setPos2(acf.codons[p][1]);
1028 // cmap.setPos3(acf.codons[p][2]);
1030 // alc.addAlcodon(cmap);
1032 // if (acf.getProtMappings() != null
1033 // && acf.getProtMappings().length > 0)
1035 // SequenceI[] dnas = acf.getdnaSeqs();
1036 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1037 // for (int m = 0; m < pmaps.length; m++)
1039 // AlcodMap alcmap = new AlcodMap();
1040 // alcmap.setDnasq(seqHash(dnas[m]));
1041 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1043 // alc.addAlcodMap(alcmap);
1050 // /////////////////////////////////
1051 if (!storeDS && av.currentTree != null)
1053 // FIND ANY ASSOCIATED TREES
1054 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1055 if (Desktop.desktop != null)
1057 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1059 for (int t = 0; t < frames.length; t++)
1061 if (frames[t] instanceof TreePanel)
1063 TreePanel tp = (TreePanel) frames[t];
1065 if (tp.treeCanvas.av.getAlignment() == jal)
1067 Tree tree = new Tree();
1068 tree.setTitle(tp.getTitle());
1069 tree.setCurrentTree((av.currentTree == tp.getTree()));
1070 tree.setNewick(tp.getTree().toString());
1071 tree.setThreshold(tp.treeCanvas.threshold);
1073 tree.setFitToWindow(tp.fitToWindow.getState());
1074 tree.setFontName(tp.getTreeFont().getName());
1075 tree.setFontSize(tp.getTreeFont().getSize());
1076 tree.setFontStyle(tp.getTreeFont().getStyle());
1077 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1079 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1080 tree.setShowDistances(tp.distanceMenu.getState());
1082 tree.setHeight(tp.getHeight());
1083 tree.setWidth(tp.getWidth());
1084 tree.setXpos(tp.getX());
1085 tree.setYpos(tp.getY());
1086 tree.setId(makeHashCode(tp, null));
1096 * store forward refs from an annotationRow to any groups
1098 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1101 for (SequenceI sq : jal.getSequences())
1103 // Store annotation on dataset sequences only
1104 AlignmentAnnotation[] aa = sq.getAnnotation();
1105 if (aa != null && aa.length > 0)
1107 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1114 if (jal.getAlignmentAnnotation() != null)
1116 // Store the annotation shown on the alignment.
1117 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1118 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1123 if (jal.getGroups() != null)
1125 JGroup[] groups = new JGroup[jal.getGroups().size()];
1127 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1129 JGroup jGroup = new JGroup();
1130 groups[++i] = jGroup;
1132 jGroup.setStart(sg.getStartRes());
1133 jGroup.setEnd(sg.getEndRes());
1134 jGroup.setName(sg.getName());
1135 if (groupRefs.containsKey(sg))
1137 // group has references so set its ID field
1138 jGroup.setId(groupRefs.get(sg));
1142 if (sg.cs.conservationApplied())
1144 jGroup.setConsThreshold(sg.cs.getConservationInc());
1146 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1148 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1152 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1155 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1157 jGroup.setColour("AnnotationColourGradient");
1158 jGroup.setAnnotationColours(constructAnnotationColours(
1159 (jalview.schemes.AnnotationColourGradient) sg.cs,
1162 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1164 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1168 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1171 jGroup.setPidThreshold(sg.cs.getThreshold());
1174 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1175 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1176 jGroup.setDisplayText(sg.getDisplayText());
1177 jGroup.setColourText(sg.getColourText());
1178 jGroup.setTextCol1(sg.textColour.getRGB());
1179 jGroup.setTextCol2(sg.textColour2.getRGB());
1180 jGroup.setTextColThreshold(sg.thresholdTextColour);
1181 jGroup.setShowUnconserved(sg.getShowNonconserved());
1182 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1183 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1184 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1185 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1186 for (SequenceI seq : sg.getSequences())
1188 jGroup.addSeq(seqHash(seq));
1192 jms.setJGroup(groups);
1196 // /////////SAVE VIEWPORT
1197 Viewport view = new Viewport();
1198 view.setTitle(ap.alignFrame.getTitle());
1199 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1200 av.getSequenceSetId()));
1201 view.setId(av.getViewId());
1202 if (av.getCodingComplement() != null)
1204 view.setComplementId(av.getCodingComplement().getViewId());
1206 view.setViewName(av.viewName);
1207 view.setGatheredViews(av.isGatherViewsHere());
1209 Rectangle size = ap.av.getExplodedGeometry();
1210 Rectangle position = size;
1213 size = ap.alignFrame.getBounds();
1214 if (av.getCodingComplement() != null)
1216 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1224 view.setXpos(position.x);
1225 view.setYpos(position.y);
1227 view.setWidth(size.width);
1228 view.setHeight(size.height);
1230 view.setStartRes(av.startRes);
1231 view.setStartSeq(av.startSeq);
1233 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1235 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1238 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1240 AnnotationColours ac = constructAnnotationColours(
1241 (jalview.schemes.AnnotationColourGradient) av
1242 .getGlobalColourScheme(),
1245 view.setAnnotationColours(ac);
1246 view.setBgColour("AnnotationColourGradient");
1250 view.setBgColour(ColourSchemeProperty.getColourName(av
1251 .getGlobalColourScheme()));
1254 ColourSchemeI cs = av.getGlobalColourScheme();
1258 if (cs.conservationApplied())
1260 view.setConsThreshold(cs.getConservationInc());
1261 if (cs instanceof jalview.schemes.UserColourScheme)
1263 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1267 if (cs instanceof ResidueColourScheme)
1269 view.setPidThreshold(cs.getThreshold());
1273 view.setConservationSelected(av.getConservationSelected());
1274 view.setPidSelected(av.getAbovePIDThreshold());
1275 view.setFontName(av.font.getName());
1276 view.setFontSize(av.font.getSize());
1277 view.setFontStyle(av.font.getStyle());
1278 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1279 view.setRenderGaps(av.isRenderGaps());
1280 view.setShowAnnotation(av.isShowAnnotation());
1281 view.setShowBoxes(av.getShowBoxes());
1282 view.setShowColourText(av.getColourText());
1283 view.setShowFullId(av.getShowJVSuffix());
1284 view.setRightAlignIds(av.isRightAlignIds());
1285 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1286 view.setShowText(av.getShowText());
1287 view.setShowUnconserved(av.getShowUnconserved());
1288 view.setWrapAlignment(av.getWrapAlignment());
1289 view.setTextCol1(av.getTextColour().getRGB());
1290 view.setTextCol2(av.getTextColour2().getRGB());
1291 view.setTextColThreshold(av.getThresholdTextColour());
1292 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1293 view.setShowSequenceLogo(av.isShowSequenceLogo());
1294 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1295 view.setShowGroupConsensus(av.isShowGroupConsensus());
1296 view.setShowGroupConservation(av.isShowGroupConservation());
1297 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1298 view.setShowDbRefTooltip(av.isShowDBRefs());
1299 view.setFollowHighlight(av.isFollowHighlight());
1300 view.setFollowSelection(av.followSelection);
1301 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1302 if (av.getFeaturesDisplayed() != null)
1304 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1306 String[] renderOrder = ap.getSeqPanel().seqCanvas
1307 .getFeatureRenderer().getRenderOrder()
1308 .toArray(new String[0]);
1310 Vector<String> settingsAdded = new Vector<String>();
1311 if (renderOrder != null)
1313 for (String featureType : renderOrder)
1315 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1316 .getFeatureRenderer()
1317 .getFeatureStyle(featureType);
1318 Setting setting = new Setting();
1319 setting.setType(featureType);
1320 if (!fcol.isSimpleColour())
1322 setting.setColour(fcol.getMaxColour().getRGB());
1323 setting.setMincolour(fcol.getMinColour().getRGB());
1324 setting.setMin(fcol.getMin());
1325 setting.setMax(fcol.getMax());
1326 setting.setColourByLabel(fcol.isColourByLabel());
1327 setting.setAutoScale(fcol.isAutoScaled());
1328 setting.setThreshold(fcol.getThreshold());
1329 // -1 = No threshold, 0 = Below, 1 = Above
1330 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1331 : (fcol.isBelowThreshold() ? 0 : -1));
1335 setting.setColour(fcol.getColour().getRGB());
1338 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1340 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1341 .getOrder(featureType);
1344 setting.setOrder(rorder);
1346 fs.addSetting(setting);
1347 settingsAdded.addElement(featureType);
1351 // is groups actually supposed to be a map here ?
1352 Iterator<String> en = ap.getSeqPanel().seqCanvas
1353 .getFeatureRenderer()
1354 .getFeatureGroups().iterator();
1355 Vector<String> groupsAdded = new Vector<String>();
1356 while (en.hasNext())
1358 String grp = en.next();
1359 if (groupsAdded.contains(grp))
1363 Group g = new Group();
1365 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1366 .getFeatureRenderer().checkGroupVisibility(grp, false))
1369 groupsAdded.addElement(grp);
1371 jms.setFeatureSettings(fs);
1374 if (av.hasHiddenColumns())
1376 if (av.getColumnSelection() == null
1377 || av.getColumnSelection().getHiddenColumns() == null)
1379 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1383 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1386 int[] region = av.getColumnSelection().getHiddenColumns()
1388 HiddenColumns hc = new HiddenColumns();
1389 hc.setStart(region[0]);
1390 hc.setEnd(region[1]);
1391 view.addHiddenColumns(hc);
1395 if (calcIdSet.size() > 0)
1397 for (String calcId : calcIdSet)
1399 if (calcId.trim().length() > 0)
1401 CalcIdParam cidp = createCalcIdParam(calcId, av);
1402 // Some calcIds have no parameters.
1405 view.addCalcIdParam(cidp);
1411 jms.addViewport(view);
1413 object.setJalviewModelSequence(jms);
1414 object.getVamsasModel().addSequenceSet(vamsasSet);
1416 if (jout != null && fileName != null)
1418 // We may not want to write the object to disk,
1419 // eg we can copy the alignViewport to a new view object
1420 // using save and then load
1423 System.out.println("Writing jar entry " + fileName);
1424 JarEntry entry = new JarEntry(fileName);
1425 jout.putNextEntry(entry);
1426 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1428 Marshaller marshaller = new Marshaller(pout);
1429 marshaller.marshal(object);
1432 } catch (Exception ex)
1434 // TODO: raise error in GUI if marshalling failed.
1435 ex.printStackTrace();
1442 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1443 * for each viewer, with
1445 * <li>viewer geometry (position, size, split pane divider location)</li>
1446 * <li>index of the selected structure in the viewer (currently shows gapped
1448 * <li>the id of the annotation holding RNA secondary structure</li>
1449 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1451 * Varna viewer state is also written out (in native Varna XML) to separate
1452 * project jar entries. A separate entry is written for each RNA structure
1453 * displayed, with the naming convention
1455 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1463 * @param storeDataset
1465 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1466 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1467 boolean storeDataset)
1469 if (Desktop.desktop == null)
1473 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1474 for (int f = frames.length - 1; f > -1; f--)
1476 if (frames[f] instanceof AppVarna)
1478 AppVarna varna = (AppVarna) frames[f];
1480 * link the sequence to every viewer that is showing it and is linked to
1481 * its alignment panel
1483 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1485 String viewId = varna.getViewId();
1486 RnaViewer rna = new RnaViewer();
1487 rna.setViewId(viewId);
1488 rna.setTitle(varna.getTitle());
1489 rna.setXpos(varna.getX());
1490 rna.setYpos(varna.getY());
1491 rna.setWidth(varna.getWidth());
1492 rna.setHeight(varna.getHeight());
1493 rna.setDividerLocation(varna.getDividerLocation());
1494 rna.setSelectedRna(varna.getSelectedIndex());
1495 jseq.addRnaViewer(rna);
1498 * Store each Varna panel's state once in the project per sequence.
1499 * First time through only (storeDataset==false)
1501 // boolean storeSessions = false;
1502 // String sequenceViewId = viewId + seqsToIds.get(jds);
1503 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1505 // viewIds.add(sequenceViewId);
1506 // storeSessions = true;
1508 for (RnaModel model : varna.getModels())
1510 if (model.seq == jds)
1513 * VARNA saves each view (sequence or alignment secondary
1514 * structure, gapped or trimmed) as a separate XML file
1516 String jarEntryName = rnaSessions.get(model);
1517 if (jarEntryName == null)
1520 String varnaStateFile = varna.getStateInfo(model.rna);
1521 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1522 copyFileToJar(jout, varnaStateFile, jarEntryName);
1523 rnaSessions.put(model, jarEntryName);
1525 SecondaryStructure ss = new SecondaryStructure();
1526 String annotationId = varna.getAnnotation(jds).annotationId;
1527 ss.setAnnotationId(annotationId);
1528 ss.setViewerState(jarEntryName);
1529 ss.setGapped(model.gapped);
1530 ss.setTitle(model.title);
1531 rna.addSecondaryStructure(ss);
1540 * Copy the contents of a file to a new entry added to the output jar
1544 * @param jarEntryName
1546 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1547 String jarEntryName)
1549 DataInputStream dis = null;
1552 File file = new File(infilePath);
1553 if (file.exists() && jout != null)
1555 dis = new DataInputStream(new FileInputStream(file));
1556 byte[] data = new byte[(int) file.length()];
1557 dis.readFully(data);
1558 writeJarEntry(jout, jarEntryName, data);
1560 } catch (Exception ex)
1562 ex.printStackTrace();
1570 } catch (IOException e)
1579 * Write the data to a new entry of given name in the output jar file
1582 * @param jarEntryName
1584 * @throws IOException
1586 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1587 byte[] data) throws IOException
1591 System.out.println("Writing jar entry " + jarEntryName);
1592 jout.putNextEntry(new JarEntry(jarEntryName));
1593 DataOutputStream dout = new DataOutputStream(jout);
1594 dout.write(data, 0, data.length);
1601 * Save the state of a structure viewer
1606 * the archive XML element under which to save the state
1609 * @param matchedFile
1613 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1614 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1615 String matchedFile, StructureViewerBase viewFrame)
1617 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1620 * Look for any bindings for this viewer to the PDB file of interest
1621 * (including part matches excluding chain id)
1623 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1625 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1626 final String pdbId = pdbentry.getId();
1627 if (!pdbId.equals(entry.getId())
1628 && !(entry.getId().length() > 4 && entry.getId()
1629 .toLowerCase().startsWith(pdbId.toLowerCase())))
1632 * not interested in a binding to a different PDB entry here
1636 if (matchedFile == null)
1638 matchedFile = pdbentry.getFile();
1640 else if (!matchedFile.equals(pdbentry.getFile()))
1643 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1644 + pdbentry.getFile());
1648 // can get at it if the ID
1649 // match is ambiguous (e.g.
1652 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1654 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1655 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1657 StructureState state = new StructureState();
1658 state.setVisible(true);
1659 state.setXpos(viewFrame.getX());
1660 state.setYpos(viewFrame.getY());
1661 state.setWidth(viewFrame.getWidth());
1662 state.setHeight(viewFrame.getHeight());
1663 final String viewId = viewFrame.getViewId();
1664 state.setViewId(viewId);
1665 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1666 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1667 state.setColourByJmol(viewFrame.isColouredByViewer());
1668 state.setType(viewFrame.getViewerType().toString());
1669 pdb.addStructureState(state);
1676 private AnnotationColours constructAnnotationColours(
1677 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1678 JalviewModelSequence jms)
1680 AnnotationColours ac = new AnnotationColours();
1681 ac.setAboveThreshold(acg.getAboveThreshold());
1682 ac.setThreshold(acg.getAnnotationThreshold());
1683 ac.setAnnotation(acg.getAnnotation());
1684 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1686 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1691 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1695 ac.setMaxColour(acg.getMaxColour().getRGB());
1696 ac.setMinColour(acg.getMinColour().getRGB());
1697 ac.setPerSequence(acg.isSeqAssociated());
1698 ac.setPredefinedColours(acg.isPredefinedColours());
1702 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1703 IdentityHashMap<SequenceGroup, String> groupRefs,
1704 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1705 SequenceSet vamsasSet)
1708 for (int i = 0; i < aa.length; i++)
1710 Annotation an = new Annotation();
1712 AlignmentAnnotation annotation = aa[i];
1713 if (annotation.annotationId != null)
1715 annotationIds.put(annotation.annotationId, annotation);
1718 an.setId(annotation.annotationId);
1720 an.setVisible(annotation.visible);
1722 an.setDescription(annotation.description);
1724 if (annotation.sequenceRef != null)
1726 // 2.9 JAL-1781 xref on sequence id rather than name
1727 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1729 if (annotation.groupRef != null)
1731 String groupIdr = groupRefs.get(annotation.groupRef);
1732 if (groupIdr == null)
1734 // make a locally unique String
1736 annotation.groupRef,
1737 groupIdr = ("" + System.currentTimeMillis()
1738 + annotation.groupRef.getName() + groupRefs
1741 an.setGroupRef(groupIdr.toString());
1744 // store all visualization attributes for annotation
1745 an.setGraphHeight(annotation.graphHeight);
1746 an.setCentreColLabels(annotation.centreColLabels);
1747 an.setScaleColLabels(annotation.scaleColLabel);
1748 an.setShowAllColLabels(annotation.showAllColLabels);
1749 an.setBelowAlignment(annotation.belowAlignment);
1751 if (annotation.graph > 0)
1754 an.setGraphType(annotation.graph);
1755 an.setGraphGroup(annotation.graphGroup);
1756 if (annotation.getThreshold() != null)
1758 ThresholdLine line = new ThresholdLine();
1759 line.setLabel(annotation.getThreshold().label);
1760 line.setValue(annotation.getThreshold().value);
1761 line.setColour(annotation.getThreshold().colour.getRGB());
1762 an.setThresholdLine(line);
1770 an.setLabel(annotation.label);
1772 if (annotation == av.getAlignmentQualityAnnot()
1773 || annotation == av.getAlignmentConservationAnnotation()
1774 || annotation == av.getAlignmentConsensusAnnotation()
1775 || annotation.autoCalculated)
1777 // new way of indicating autocalculated annotation -
1778 an.setAutoCalculated(annotation.autoCalculated);
1780 if (annotation.hasScore())
1782 an.setScore(annotation.getScore());
1785 if (annotation.getCalcId() != null)
1787 calcIdSet.add(annotation.getCalcId());
1788 an.setCalcId(annotation.getCalcId());
1790 if (annotation.hasProperties())
1792 for (String pr : annotation.getProperties())
1794 Property prop = new Property();
1796 prop.setValue(annotation.getProperty(pr));
1797 an.addProperty(prop);
1801 AnnotationElement ae;
1802 if (annotation.annotations != null)
1804 an.setScoreOnly(false);
1805 for (int a = 0; a < annotation.annotations.length; a++)
1807 if ((annotation == null) || (annotation.annotations[a] == null))
1812 ae = new AnnotationElement();
1813 if (annotation.annotations[a].description != null)
1815 ae.setDescription(annotation.annotations[a].description);
1817 if (annotation.annotations[a].displayCharacter != null)
1819 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1822 if (!Float.isNaN(annotation.annotations[a].value))
1824 ae.setValue(annotation.annotations[a].value);
1828 if (annotation.annotations[a].secondaryStructure > ' ')
1830 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1834 if (annotation.annotations[a].colour != null
1835 && annotation.annotations[a].colour != java.awt.Color.black)
1837 ae.setColour(annotation.annotations[a].colour.getRGB());
1840 an.addAnnotationElement(ae);
1841 if (annotation.autoCalculated)
1843 // only write one non-null entry into the annotation row -
1844 // sufficient to get the visualization attributes necessary to
1852 an.setScoreOnly(true);
1854 if (!storeDS || (storeDS && !annotation.autoCalculated))
1856 // skip autocalculated annotation - these are only provided for
1858 vamsasSet.addAnnotation(an);
1864 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1866 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1867 if (settings != null)
1869 CalcIdParam vCalcIdParam = new CalcIdParam();
1870 vCalcIdParam.setCalcId(calcId);
1871 vCalcIdParam.addServiceURL(settings.getServiceURI());
1872 // generic URI allowing a third party to resolve another instance of the
1873 // service used for this calculation
1874 for (String urls : settings.getServiceURLs())
1876 vCalcIdParam.addServiceURL(urls);
1878 vCalcIdParam.setVersion("1.0");
1879 if (settings.getPreset() != null)
1881 WsParamSetI setting = settings.getPreset();
1882 vCalcIdParam.setName(setting.getName());
1883 vCalcIdParam.setDescription(setting.getDescription());
1887 vCalcIdParam.setName("");
1888 vCalcIdParam.setDescription("Last used parameters");
1890 // need to be able to recover 1) settings 2) user-defined presets or
1891 // recreate settings from preset 3) predefined settings provided by
1892 // service - or settings that can be transferred (or discarded)
1893 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1895 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1896 // todo - decide if updateImmediately is needed for any projects.
1898 return vCalcIdParam;
1903 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1906 if (calcIdParam.getVersion().equals("1.0"))
1908 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1909 .getPreferredServiceFor(calcIdParam.getServiceURL());
1910 if (service != null)
1912 WsParamSetI parmSet = null;
1915 parmSet = service.getParamStore().parseServiceParameterFile(
1916 calcIdParam.getName(), calcIdParam.getDescription(),
1917 calcIdParam.getServiceURL(),
1918 calcIdParam.getParameters().replace("|\\n|", "\n"));
1919 } catch (IOException x)
1921 warn("Couldn't parse parameter data for "
1922 + calcIdParam.getCalcId(), x);
1925 List<ArgumentI> argList = null;
1926 if (calcIdParam.getName().length() > 0)
1928 parmSet = service.getParamStore()
1929 .getPreset(calcIdParam.getName());
1930 if (parmSet != null)
1932 // TODO : check we have a good match with settings in AACon -
1933 // otherwise we'll need to create a new preset
1938 argList = parmSet.getArguments();
1941 AAConSettings settings = new AAConSettings(
1942 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1943 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1944 calcIdParam.isNeedsUpdate());
1949 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1953 throw new Error(MessageManager.formatMessage(
1954 "error.unsupported_version_calcIdparam",
1955 new Object[] { calcIdParam.toString() }));
1959 * External mapping between jalview objects and objects yielding a valid and
1960 * unique object ID string. This is null for normal Jalview project IO, but
1961 * non-null when a jalview project is being read or written as part of a
1964 IdentityHashMap jv2vobj = null;
1967 * Construct a unique ID for jvobj using either existing bindings or if none
1968 * exist, the result of the hashcode call for the object.
1971 * jalview data object
1972 * @return unique ID for referring to jvobj
1974 private String makeHashCode(Object jvobj, String altCode)
1976 if (jv2vobj != null)
1978 Object id = jv2vobj.get(jvobj);
1981 return id.toString();
1983 // check string ID mappings
1984 if (jvids2vobj != null && jvobj instanceof String)
1986 id = jvids2vobj.get(jvobj);
1990 return id.toString();
1992 // give up and warn that something has gone wrong
1993 warn("Cannot find ID for object in external mapping : " + jvobj);
1999 * return local jalview object mapped to ID, if it exists
2003 * @return null or object bound to idcode
2005 private Object retrieveExistingObj(String idcode)
2007 if (idcode != null && vobj2jv != null)
2009 return vobj2jv.get(idcode);
2015 * binding from ID strings from external mapping table to jalview data model
2018 private Hashtable vobj2jv;
2020 private Sequence createVamsasSequence(String id, SequenceI jds)
2022 return createVamsasSequence(true, id, jds, null);
2025 private Sequence createVamsasSequence(boolean recurse, String id,
2026 SequenceI jds, SequenceI parentseq)
2028 Sequence vamsasSeq = new Sequence();
2029 vamsasSeq.setId(id);
2030 vamsasSeq.setName(jds.getName());
2031 vamsasSeq.setSequence(jds.getSequenceAsString());
2032 vamsasSeq.setDescription(jds.getDescription());
2033 jalview.datamodel.DBRefEntry[] dbrefs = null;
2034 if (jds.getDatasetSequence() != null)
2036 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2037 if (jds.getDatasetSequence().getDBRefs() != null)
2039 dbrefs = jds.getDatasetSequence().getDBRefs();
2044 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
2045 // dataset sequences only
2046 dbrefs = jds.getDBRefs();
2050 for (int d = 0; d < dbrefs.length; d++)
2052 DBRef dbref = new DBRef();
2053 dbref.setSource(dbrefs[d].getSource());
2054 dbref.setVersion(dbrefs[d].getVersion());
2055 dbref.setAccessionId(dbrefs[d].getAccessionId());
2056 if (dbrefs[d].hasMap())
2058 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2060 dbref.setMapping(mp);
2062 vamsasSeq.addDBRef(dbref);
2068 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2069 SequenceI parentseq, SequenceI jds, boolean recurse)
2072 if (jmp.getMap() != null)
2076 jalview.util.MapList mlst = jmp.getMap();
2077 List<int[]> r = mlst.getFromRanges();
2078 for (int[] range : r)
2080 MapListFrom mfrom = new MapListFrom();
2081 mfrom.setStart(range[0]);
2082 mfrom.setEnd(range[1]);
2083 mp.addMapListFrom(mfrom);
2085 r = mlst.getToRanges();
2086 for (int[] range : r)
2088 MapListTo mto = new MapListTo();
2089 mto.setStart(range[0]);
2090 mto.setEnd(range[1]);
2091 mp.addMapListTo(mto);
2093 mp.setMapFromUnit(mlst.getFromRatio());
2094 mp.setMapToUnit(mlst.getToRatio());
2095 if (jmp.getTo() != null)
2097 MappingChoice mpc = new MappingChoice();
2099 && (parentseq != jmp.getTo() || parentseq
2100 .getDatasetSequence() != jmp.getTo()))
2102 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2108 SequenceI ps = null;
2109 if (parentseq != jmp.getTo()
2110 && parentseq.getDatasetSequence() != jmp.getTo())
2112 // chaining dbref rather than a handshaking one
2113 jmpid = seqHash(ps = jmp.getTo());
2117 jmpid = seqHash(ps = parentseq);
2119 mpc.setDseqFor(jmpid);
2120 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2122 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2123 seqRefIds.put(mpc.getDseqFor(), ps);
2127 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2130 mp.setMappingChoice(mpc);
2136 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2137 List<UserColourScheme> userColours, JalviewModelSequence jms)
2140 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2141 boolean newucs = false;
2142 if (!userColours.contains(ucs))
2144 userColours.add(ucs);
2147 id = "ucs" + userColours.indexOf(ucs);
2150 // actually create the scheme's entry in the XML model
2151 java.awt.Color[] colours = ucs.getColours();
2152 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2153 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2155 for (int i = 0; i < colours.length; i++)
2157 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2158 col.setName(ResidueProperties.aa[i]);
2159 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2160 jbucs.addColour(col);
2162 if (ucs.getLowerCaseColours() != null)
2164 colours = ucs.getLowerCaseColours();
2165 for (int i = 0; i < colours.length; i++)
2167 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2168 col.setName(ResidueProperties.aa[i].toLowerCase());
2169 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2170 jbucs.addColour(col);
2175 uc.setUserColourScheme(jbucs);
2176 jms.addUserColours(uc);
2182 jalview.schemes.UserColourScheme getUserColourScheme(
2183 JalviewModelSequence jms, String id)
2185 UserColours[] uc = jms.getUserColours();
2186 UserColours colours = null;
2188 for (int i = 0; i < uc.length; i++)
2190 if (uc[i].getId().equals(id))
2198 java.awt.Color[] newColours = new java.awt.Color[24];
2200 for (int i = 0; i < 24; i++)
2202 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2203 .getUserColourScheme().getColour(i).getRGB(), 16));
2206 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2209 if (colours.getUserColourScheme().getColourCount() > 24)
2211 newColours = new java.awt.Color[23];
2212 for (int i = 0; i < 23; i++)
2214 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2215 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2217 ucs.setLowerCaseColours(newColours);
2224 * contains last error message (if any) encountered by XML loader.
2226 String errorMessage = null;
2229 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2230 * exceptions are raised during project XML parsing
2232 public boolean attemptversion1parse = true;
2235 * Load a jalview project archive from a jar file
2238 * - HTTP URL or filename
2240 public AlignFrame loadJalviewAlign(final String file)
2243 jalview.gui.AlignFrame af = null;
2247 // create list to store references for any new Jmol viewers created
2248 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2249 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2250 // Workaround is to make sure caller implements the JarInputStreamProvider
2252 // so we can re-open the jar input stream for each entry.
2254 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2255 af = loadJalviewAlign(jprovider);
2257 } catch (MalformedURLException e)
2259 errorMessage = "Invalid URL format for '" + file + "'";
2265 SwingUtilities.invokeAndWait(new Runnable()
2270 setLoadingFinishedForNewStructureViewers();
2273 } catch (Exception x)
2275 System.err.println("Error loading alignment: " + x.getMessage());
2281 private jarInputStreamProvider createjarInputStreamProvider(
2282 final String file) throws MalformedURLException
2285 errorMessage = null;
2286 uniqueSetSuffix = null;
2288 viewportsAdded.clear();
2289 frefedSequence = null;
2291 if (file.startsWith("http://"))
2293 url = new URL(file);
2295 final URL _url = url;
2296 return new jarInputStreamProvider()
2300 public JarInputStream getJarInputStream() throws IOException
2304 return new JarInputStream(_url.openStream());
2308 return new JarInputStream(new FileInputStream(file));
2313 public String getFilename()
2321 * Recover jalview session from a jalview project archive. Caller may
2322 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2323 * themselves. Any null fields will be initialised with default values,
2324 * non-null fields are left alone.
2329 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2331 errorMessage = null;
2332 if (uniqueSetSuffix == null)
2334 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2336 if (seqRefIds == null)
2340 AlignFrame af = null, _af = null;
2341 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2342 final String file = jprovider.getFilename();
2345 JarInputStream jin = null;
2346 JarEntry jarentry = null;
2351 jin = jprovider.getJarInputStream();
2352 for (int i = 0; i < entryCount; i++)
2354 jarentry = jin.getNextJarEntry();
2357 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2359 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2360 JalviewModel object = new JalviewModel();
2362 Unmarshaller unmar = new Unmarshaller(object);
2363 unmar.setValidation(false);
2364 object = (JalviewModel) unmar.unmarshal(in);
2365 if (true) // !skipViewport(object))
2367 _af = loadFromObject(object, file, true, jprovider);
2368 if (object.getJalviewModelSequence().getViewportCount() > 0)
2371 if (af.viewport.isGatherViewsHere())
2373 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2379 else if (jarentry != null)
2381 // Some other file here.
2384 } while (jarentry != null);
2385 resolveFrefedSequences();
2386 } catch (IOException ex)
2388 ex.printStackTrace();
2389 errorMessage = "Couldn't locate Jalview XML file : " + file;
2390 System.err.println("Exception whilst loading jalview XML file : "
2392 } catch (Exception ex)
2394 System.err.println("Parsing as Jalview Version 2 file failed.");
2395 ex.printStackTrace(System.err);
2396 if (attemptversion1parse)
2398 // Is Version 1 Jar file?
2401 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2402 } catch (Exception ex2)
2404 System.err.println("Exception whilst loading as jalviewXMLV1:");
2405 ex2.printStackTrace();
2409 if (Desktop.instance != null)
2411 Desktop.instance.stopLoading();
2415 System.out.println("Successfully loaded archive file");
2418 ex.printStackTrace();
2420 System.err.println("Exception whilst loading jalview XML file : "
2422 } catch (OutOfMemoryError e)
2424 // Don't use the OOM Window here
2425 errorMessage = "Out of memory loading jalview XML file";
2426 System.err.println("Out of memory whilst loading jalview XML file");
2427 e.printStackTrace();
2430 if (Desktop.instance != null)
2432 Desktop.instance.stopLoading();
2436 * Regather multiple views (with the same sequence set id) to the frame (if
2437 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2438 * views instead of separate frames. Note this doesn't restore a state where
2439 * some expanded views in turn have tabbed views - the last "first tab" read
2440 * in will play the role of gatherer for all.
2442 for (AlignFrame fr : gatherToThisFrame.values())
2444 Desktop.instance.gatherViews(fr);
2447 restoreSplitFrames();
2449 if (errorMessage != null)
2457 * Try to reconstruct and display SplitFrame windows, where each contains
2458 * complementary dna and protein alignments. Done by pairing up AlignFrame
2459 * objects (created earlier) which have complementary viewport ids associated.
2461 protected void restoreSplitFrames()
2463 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2464 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2465 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2468 * Identify the DNA alignments
2470 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2473 AlignFrame af = candidate.getValue();
2474 if (af.getViewport().getAlignment().isNucleotide())
2476 dna.put(candidate.getKey().getId(), af);
2481 * Try to match up the protein complements
2483 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2486 AlignFrame af = candidate.getValue();
2487 if (!af.getViewport().getAlignment().isNucleotide())
2489 String complementId = candidate.getKey().getComplementId();
2490 // only non-null complements should be in the Map
2491 if (complementId != null && dna.containsKey(complementId))
2493 final AlignFrame dnaFrame = dna.get(complementId);
2494 SplitFrame sf = createSplitFrame(dnaFrame, af);
2495 addedToSplitFrames.add(dnaFrame);
2496 addedToSplitFrames.add(af);
2497 if (af.viewport.isGatherViewsHere())
2506 * Open any that we failed to pair up (which shouldn't happen!) as
2507 * standalone AlignFrame's.
2509 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2512 AlignFrame af = candidate.getValue();
2513 if (!addedToSplitFrames.contains(af))
2515 Viewport view = candidate.getKey();
2516 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2518 System.err.println("Failed to restore view " + view.getTitle()
2519 + " to split frame");
2524 * Gather back into tabbed views as flagged.
2526 for (SplitFrame sf : gatherTo)
2528 Desktop.instance.gatherViews(sf);
2531 splitFrameCandidates.clear();
2535 * Construct and display one SplitFrame holding DNA and protein alignments.
2538 * @param proteinFrame
2541 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2542 AlignFrame proteinFrame)
2544 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2545 String title = MessageManager.getString("label.linked_view_title");
2546 int width = (int) dnaFrame.getBounds().getWidth();
2547 int height = (int) (dnaFrame.getBounds().getHeight()
2548 + proteinFrame.getBounds().getHeight() + 50);
2551 * SplitFrame location is saved to both enclosed frames
2553 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2554 Desktop.addInternalFrame(splitFrame, title, width, height);
2557 * And compute cDNA consensus (couldn't do earlier with consensus as
2558 * mappings were not yet present)
2560 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2566 * check errorMessage for a valid error message and raise an error box in the
2567 * GUI or write the current errorMessage to stderr and then clear the error
2570 protected void reportErrors()
2572 reportErrors(false);
2575 protected void reportErrors(final boolean saving)
2577 if (errorMessage != null)
2579 final String finalErrorMessage = errorMessage;
2582 javax.swing.SwingUtilities.invokeLater(new Runnable()
2587 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2588 finalErrorMessage, "Error "
2589 + (saving ? "saving" : "loading")
2590 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2596 System.err.println("Problem loading Jalview file: " + errorMessage);
2599 errorMessage = null;
2602 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2605 * when set, local views will be updated from view stored in JalviewXML
2606 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2607 * sync if this is set to true.
2609 private final boolean updateLocalViews = false;
2612 * Returns the path to a temporary file holding the PDB file for the given PDB
2613 * id. The first time of asking, searches for a file of that name in the
2614 * Jalview project jar, and copies it to a new temporary file. Any repeat
2615 * requests just return the path to the file previously created.
2621 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2623 if (alreadyLoadedPDB.containsKey(pdbId))
2625 return alreadyLoadedPDB.get(pdbId).toString();
2628 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2629 if (tempFile != null)
2631 alreadyLoadedPDB.put(pdbId, tempFile);
2637 * Copies the jar entry of given name to a new temporary file and returns the
2638 * path to the file, or null if the entry is not found.
2641 * @param jarEntryName
2643 * a prefix for the temporary file name, must be at least three
2647 protected String copyJarEntry(jarInputStreamProvider jprovider,
2648 String jarEntryName, String prefix)
2650 BufferedReader in = null;
2651 PrintWriter out = null;
2655 JarInputStream jin = jprovider.getJarInputStream();
2657 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2658 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2659 * FileInputStream(jprovider)); }
2662 JarEntry entry = null;
2665 entry = jin.getNextJarEntry();
2666 } while (entry != null && !entry.getName().equals(jarEntryName));
2669 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2670 File outFile = File.createTempFile(prefix, ".tmp");
2671 outFile.deleteOnExit();
2672 out = new PrintWriter(new FileOutputStream(outFile));
2675 while ((data = in.readLine()) != null)
2680 String t = outFile.getAbsolutePath();
2685 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2687 } catch (Exception ex)
2689 ex.printStackTrace();
2697 } catch (IOException e)
2711 private class JvAnnotRow
2713 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2720 * persisted version of annotation row from which to take vis properties
2722 public jalview.datamodel.AlignmentAnnotation template;
2725 * original position of the annotation row in the alignment
2731 * Load alignment frame from jalview XML DOM object
2736 * filename source string
2737 * @param loadTreesAndStructures
2738 * when false only create Viewport
2740 * data source provider
2741 * @return alignment frame created from view stored in DOM
2743 AlignFrame loadFromObject(JalviewModel object, String file,
2744 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2746 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2747 Sequence[] vamsasSeq = vamsasSet.getSequence();
2749 JalviewModelSequence jms = object.getJalviewModelSequence();
2751 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2754 // ////////////////////////////////
2757 List<SequenceI> hiddenSeqs = null;
2760 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2762 boolean multipleView = false;
2763 SequenceI referenceseqForView = null;
2764 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2765 int vi = 0; // counter in vamsasSeq array
2766 for (int i = 0; i < jseqs.length; i++)
2768 String seqId = jseqs[i].getId();
2770 SequenceI tmpSeq = seqRefIds.get(seqId);
2773 if (!incompleteSeqs.containsKey(seqId))
2775 // may not need this check, but keep it for at least 2.9,1 release
2776 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2779 .println("Warning JAL-2154 regression: updating start/end for sequence "
2780 + tmpSeq.toString());
2783 incompleteSeqs.remove(seqId);
2785 tmpSeq.setStart(jseqs[i].getStart());
2786 tmpSeq.setEnd(jseqs[i].getEnd());
2787 tmpseqs.add(tmpSeq);
2788 multipleView = true;
2792 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2793 vamsasSeq[vi].getSequence());
2794 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2795 tmpSeq.setStart(jseqs[i].getStart());
2796 tmpSeq.setEnd(jseqs[i].getEnd());
2797 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2798 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2799 tmpseqs.add(tmpSeq);
2803 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2805 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2808 if (jseqs[i].getHidden())
2810 if (hiddenSeqs == null)
2812 hiddenSeqs = new ArrayList<SequenceI>();
2815 hiddenSeqs.add(tmpSeq);
2820 // Create the alignment object from the sequence set
2821 // ///////////////////////////////
2822 SequenceI[] orderedSeqs = tmpseqs
2823 .toArray(new SequenceI[tmpseqs.size()]);
2825 AlignmentI al = new Alignment(orderedSeqs);
2827 if (referenceseqForView != null)
2829 al.setSeqrep(referenceseqForView);
2831 // / Add the alignment properties
2832 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2834 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2835 al.setProperty(ssp.getKey(), ssp.getValue());
2839 // SequenceFeatures are added to the DatasetSequence,
2840 // so we must create or recover the dataset before loading features
2841 // ///////////////////////////////
2842 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2844 // older jalview projects do not have a dataset id.
2845 al.setDataset(null);
2849 // recover dataset - passing on flag indicating if this a 'viewless'
2850 // sequence set (a.k.a. a stored dataset for the project)
2851 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2852 .getViewportCount() == 0);
2854 // ///////////////////////////////
2856 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2859 // load sequence features, database references and any associated PDB
2860 // structures for the alignment
2861 for (int i = 0; i < vamsasSeq.length; i++)
2863 if (jseqs[i].getFeaturesCount() > 0)
2865 Features[] features = jseqs[i].getFeatures();
2866 for (int f = 0; f < features.length; f++)
2868 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2869 features[f].getType(), features[f].getDescription(),
2870 features[f].getStatus(), features[f].getBegin(),
2871 features[f].getEnd(), features[f].getFeatureGroup());
2873 sf.setScore(features[f].getScore());
2874 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2876 OtherData keyValue = features[f].getOtherData(od);
2877 if (keyValue.getKey().startsWith("LINK"))
2879 sf.addLink(keyValue.getValue());
2883 sf.setValue(keyValue.getKey(), keyValue.getValue());
2888 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2891 if (vamsasSeq[i].getDBRefCount() > 0)
2893 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2895 if (jseqs[i].getPdbidsCount() > 0)
2897 Pdbids[] ids = jseqs[i].getPdbids();
2898 for (int p = 0; p < ids.length; p++)
2900 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2901 entry.setId(ids[p].getId());
2902 if (ids[p].getType() != null)
2904 if (ids[p].getType().equalsIgnoreCase("PDB"))
2906 entry.setType(PDBEntry.Type.PDB);
2910 entry.setType(PDBEntry.Type.FILE);
2913 if (ids[p].getFile() != null)
2915 if (!pdbloaded.containsKey(ids[p].getFile()))
2917 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2921 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2924 StructureSelectionManager.getStructureSelectionManager(
2925 Desktop.instance).registerPDBEntry(entry);
2926 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2930 } // end !multipleview
2932 // ///////////////////////////////
2933 // LOAD SEQUENCE MAPPINGS
2935 if (vamsasSet.getAlcodonFrameCount() > 0)
2937 // TODO Potentially this should only be done once for all views of an
2939 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2940 for (int i = 0; i < alc.length; i++)
2942 AlignedCodonFrame cf = new AlignedCodonFrame();
2943 if (alc[i].getAlcodMapCount() > 0)
2945 AlcodMap[] maps = alc[i].getAlcodMap();
2946 for (int m = 0; m < maps.length; m++)
2948 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2950 jalview.datamodel.Mapping mapping = null;
2951 // attach to dna sequence reference.
2952 if (maps[m].getMapping() != null)
2954 mapping = addMapping(maps[m].getMapping());
2956 if (dnaseq != null && mapping.getTo() != null)
2958 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2963 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
2967 al.addCodonFrame(cf);
2972 // ////////////////////////////////
2974 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2977 * store any annotations which forward reference a group's ID
2979 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2981 if (vamsasSet.getAnnotationCount() > 0)
2983 Annotation[] an = vamsasSet.getAnnotation();
2985 for (int i = 0; i < an.length; i++)
2987 Annotation annotation = an[i];
2990 * test if annotation is automatically calculated for this view only
2992 boolean autoForView = false;
2993 if (annotation.getLabel().equals("Quality")
2994 || annotation.getLabel().equals("Conservation")
2995 || annotation.getLabel().equals("Consensus"))
2997 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2999 if (!annotation.hasAutoCalculated())
3001 annotation.setAutoCalculated(true);
3005 || (annotation.hasAutoCalculated() && annotation
3006 .isAutoCalculated()))
3008 // remove ID - we don't recover annotation from other views for
3009 // view-specific annotation
3010 annotation.setId(null);
3013 // set visiblity for other annotation in this view
3014 String annotationId = annotation.getId();
3015 if (annotationId != null && annotationIds.containsKey(annotationId))
3017 AlignmentAnnotation jda = annotationIds.get(annotationId);
3018 // in principle Visible should always be true for annotation displayed
3019 // in multiple views
3020 if (annotation.hasVisible())
3022 jda.visible = annotation.getVisible();
3025 al.addAnnotation(jda);
3029 // Construct new annotation from model.
3030 AnnotationElement[] ae = annotation.getAnnotationElement();
3031 jalview.datamodel.Annotation[] anot = null;
3032 java.awt.Color firstColour = null;
3034 if (!annotation.getScoreOnly())
3036 anot = new jalview.datamodel.Annotation[al.getWidth()];
3037 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3039 anpos = ae[aa].getPosition();
3041 if (anpos >= anot.length)
3046 anot[anpos] = new jalview.datamodel.Annotation(
3048 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3049 (ae[aa].getSecondaryStructure() == null || ae[aa]
3050 .getSecondaryStructure().length() == 0) ? ' '
3051 : ae[aa].getSecondaryStructure().charAt(0),
3055 // JBPNote: Consider verifying dataflow for IO of secondary
3056 // structure annotation read from Stockholm files
3057 // this was added to try to ensure that
3058 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3060 // anot[ae[aa].getPosition()].displayCharacter = "";
3062 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3063 if (firstColour == null)
3065 firstColour = anot[anpos].colour;
3069 jalview.datamodel.AlignmentAnnotation jaa = null;
3071 if (annotation.getGraph())
3073 float llim = 0, hlim = 0;
3074 // if (autoForView || an[i].isAutoCalculated()) {
3077 jaa = new jalview.datamodel.AlignmentAnnotation(
3078 annotation.getLabel(), annotation.getDescription(), anot,
3079 llim, hlim, annotation.getGraphType());
3081 jaa.graphGroup = annotation.getGraphGroup();
3082 jaa._linecolour = firstColour;
3083 if (annotation.getThresholdLine() != null)
3085 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3086 .getThresholdLine().getValue(), annotation
3087 .getThresholdLine().getLabel(), new java.awt.Color(
3088 annotation.getThresholdLine().getColour())));
3091 if (autoForView || annotation.isAutoCalculated())
3093 // Hardwire the symbol display line to ensure that labels for
3094 // histograms are displayed
3100 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3101 an[i].getDescription(), anot);
3102 jaa._linecolour = firstColour;
3104 // register new annotation
3105 if (an[i].getId() != null)
3107 annotationIds.put(an[i].getId(), jaa);
3108 jaa.annotationId = an[i].getId();
3110 // recover sequence association
3111 String sequenceRef = an[i].getSequenceRef();
3112 if (sequenceRef != null)
3114 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3115 SequenceI sequence = seqRefIds.get(sequenceRef);
3116 if (sequence == null)
3118 // in pre-2.9 projects sequence ref is to sequence name
3119 sequence = al.findName(sequenceRef);
3121 if (sequence != null)
3123 jaa.createSequenceMapping(sequence, 1, true);
3124 sequence.addAlignmentAnnotation(jaa);
3127 // and make a note of any group association
3128 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3130 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3131 .get(an[i].getGroupRef());
3134 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3135 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3140 if (an[i].hasScore())
3142 jaa.setScore(an[i].getScore());
3144 if (an[i].hasVisible())
3146 jaa.visible = an[i].getVisible();
3149 if (an[i].hasCentreColLabels())
3151 jaa.centreColLabels = an[i].getCentreColLabels();
3154 if (an[i].hasScaleColLabels())
3156 jaa.scaleColLabel = an[i].getScaleColLabels();
3158 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3160 // newer files have an 'autoCalculated' flag and store calculation
3161 // state in viewport properties
3162 jaa.autoCalculated = true; // means annotation will be marked for
3163 // update at end of load.
3165 if (an[i].hasGraphHeight())
3167 jaa.graphHeight = an[i].getGraphHeight();
3169 if (an[i].hasBelowAlignment())
3171 jaa.belowAlignment = an[i].isBelowAlignment();
3173 jaa.setCalcId(an[i].getCalcId());
3174 if (an[i].getPropertyCount() > 0)
3176 for (jalview.schemabinding.version2.Property prop : an[i]
3179 jaa.setProperty(prop.getName(), prop.getValue());
3182 if (jaa.autoCalculated)
3184 autoAlan.add(new JvAnnotRow(i, jaa));
3187 // if (!autoForView)
3189 // add autocalculated group annotation and any user created annotation
3191 al.addAnnotation(jaa);
3195 // ///////////////////////
3197 // Create alignment markup and styles for this view
3198 if (jms.getJGroupCount() > 0)
3200 JGroup[] groups = jms.getJGroup();
3201 boolean addAnnotSchemeGroup = false;
3202 for (int i = 0; i < groups.length; i++)
3204 JGroup jGroup = groups[i];
3205 ColourSchemeI cs = null;
3206 if (jGroup.getColour() != null)
3208 if (jGroup.getColour().startsWith("ucs"))
3210 cs = getUserColourScheme(jms, jGroup.getColour());
3212 else if (jGroup.getColour().equals("AnnotationColourGradient")
3213 && jGroup.getAnnotationColours() != null)
3215 addAnnotSchemeGroup = true;
3220 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3225 cs.setThreshold(jGroup.getPidThreshold(), true);
3229 Vector<SequenceI> seqs = new Vector<SequenceI>();
3231 for (int s = 0; s < jGroup.getSeqCount(); s++)
3233 String seqId = jGroup.getSeq(s) + "";
3234 SequenceI ts = seqRefIds.get(seqId);
3238 seqs.addElement(ts);
3242 if (seqs.size() < 1)
3247 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3248 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3249 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3251 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3253 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3254 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3255 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3256 .isShowUnconserved() : false);
3257 sg.thresholdTextColour = jGroup.getTextColThreshold();
3258 if (jGroup.hasShowConsensusHistogram())
3260 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3263 if (jGroup.hasShowSequenceLogo())
3265 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3267 if (jGroup.hasNormaliseSequenceLogo())
3269 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3271 if (jGroup.hasIgnoreGapsinConsensus())
3273 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3275 if (jGroup.getConsThreshold() != 0)
3277 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3278 "All", ResidueProperties.propHash, 3,
3279 sg.getSequences(null), 0, sg.getWidth() - 1);
3281 c.verdict(false, 25);
3282 sg.cs.setConservation(c);
3285 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3287 // re-instate unique group/annotation row reference
3288 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3292 for (AlignmentAnnotation jaa : jaal)
3295 if (jaa.autoCalculated)
3297 // match up and try to set group autocalc alignment row for this
3299 if (jaa.label.startsWith("Consensus for "))
3301 sg.setConsensus(jaa);
3303 // match up and try to set group autocalc alignment row for this
3305 if (jaa.label.startsWith("Conservation for "))
3307 sg.setConservationRow(jaa);
3314 if (addAnnotSchemeGroup)
3316 // reconstruct the annotation colourscheme
3317 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3318 null, al, jms, false);
3324 // only dataset in this model, so just return.
3327 // ///////////////////////////////
3330 // If we just load in the same jar file again, the sequenceSetId
3331 // will be the same, and we end up with multiple references
3332 // to the same sequenceSet. We must modify this id on load
3333 // so that each load of the file gives a unique id
3334 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3335 String viewId = (view.getId() == null ? null : view.getId()
3337 AlignFrame af = null;
3338 AlignViewport av = null;
3339 // now check to see if we really need to create a new viewport.
3340 if (multipleView && viewportsAdded.size() == 0)
3342 // We recovered an alignment for which a viewport already exists.
3343 // TODO: fix up any settings necessary for overlaying stored state onto
3344 // state recovered from another document. (may not be necessary).
3345 // we may need a binding from a viewport in memory to one recovered from
3347 // and then recover its containing af to allow the settings to be applied.
3348 // TODO: fix for vamsas demo
3350 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3352 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3353 if (seqsetobj != null)
3355 if (seqsetobj instanceof String)
3357 uniqueSeqSetId = (String) seqsetobj;
3359 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3365 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3371 * indicate that annotation colours are applied across all groups (pre
3372 * Jalview 2.8.1 behaviour)
3374 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3375 "2.8.1", object.getVersion());
3377 AlignmentPanel ap = null;
3378 boolean isnewview = true;
3381 // Check to see if this alignment already has a view id == viewId
3382 jalview.gui.AlignmentPanel views[] = Desktop
3383 .getAlignmentPanels(uniqueSeqSetId);
3384 if (views != null && views.length > 0)
3386 for (int v = 0; v < views.length; v++)
3388 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3390 // recover the existing alignpanel, alignframe, viewport
3391 af = views[v].alignFrame;
3394 // TODO: could even skip resetting view settings if we don't want to
3395 // change the local settings from other jalview processes
3404 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3405 uniqueSeqSetId, viewId, autoAlan);
3411 * Load any trees, PDB structures and viewers
3413 * Not done if flag is false (when this method is used for New View)
3415 if (loadTreesAndStructures)
3417 loadTrees(jms, view, af, av, ap);
3418 loadPDBStructures(jprovider, jseqs, af, ap);
3419 loadRnaViewers(jprovider, jseqs, ap);
3421 // and finally return.
3426 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3427 * panel is restored from separate jar entries, two (gapped and trimmed) per
3428 * sequence and secondary structure.
3430 * Currently each viewer shows just one sequence and structure (gapped and
3431 * trimmed), however this method is designed to support multiple sequences or
3432 * structures in viewers if wanted in future.
3438 private void loadRnaViewers(jarInputStreamProvider jprovider,
3439 JSeq[] jseqs, AlignmentPanel ap)
3442 * scan the sequences for references to viewers; create each one the first
3443 * time it is referenced, add Rna models to existing viewers
3445 for (JSeq jseq : jseqs)
3447 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3449 RnaViewer viewer = jseq.getRnaViewer(i);
3450 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3451 uniqueSetSuffix, ap);
3453 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3455 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3456 SequenceI seq = seqRefIds.get(jseq.getId());
3457 AlignmentAnnotation ann = this.annotationIds.get(ss
3458 .getAnnotationId());
3461 * add the structure to the Varna display (with session state copied
3462 * from the jar to a temporary file)
3464 boolean gapped = ss.isGapped();
3465 String rnaTitle = ss.getTitle();
3466 String sessionState = ss.getViewerState();
3467 String tempStateFile = copyJarEntry(jprovider, sessionState,
3469 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3470 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3472 appVarna.setInitialSelection(viewer.getSelectedRna());
3478 * Locate and return an already instantiated matching AppVarna, or create one
3482 * @param viewIdSuffix
3486 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3487 String viewIdSuffix, AlignmentPanel ap)
3490 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3491 * if load is repeated
3493 String postLoadId = viewer.getViewId() + viewIdSuffix;
3494 for (JInternalFrame frame : getAllFrames())
3496 if (frame instanceof AppVarna)
3498 AppVarna varna = (AppVarna) frame;
3499 if (postLoadId.equals(varna.getViewId()))
3501 // this viewer is already instantiated
3502 // could in future here add ap as another 'parent' of the
3503 // AppVarna window; currently just 1-to-many
3510 * viewer not found - make it
3512 RnaViewerModel model = new RnaViewerModel(postLoadId,
3513 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3514 viewer.getWidth(), viewer.getHeight(),
3515 viewer.getDividerLocation());
3516 AppVarna varna = new AppVarna(model, ap);
3522 * Load any saved trees
3530 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3531 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3533 // TODO result of automated refactoring - are all these parameters needed?
3536 for (int t = 0; t < jms.getTreeCount(); t++)
3539 Tree tree = jms.getTree(t);
3541 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3544 tp = af.ShowNewickTree(
3545 new jalview.io.NewickFile(tree.getNewick()),
3546 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3547 tree.getXpos(), tree.getYpos());
3548 if (tree.getId() != null)
3550 // perhaps bind the tree id to something ?
3555 // update local tree attributes ?
3556 // TODO: should check if tp has been manipulated by user - if so its
3557 // settings shouldn't be modified
3558 tp.setTitle(tree.getTitle());
3559 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3560 .getWidth(), tree.getHeight()));
3561 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3564 tp.treeCanvas.av = av; // af.viewport;
3565 tp.treeCanvas.ap = ap; // af.alignPanel;
3570 warn("There was a problem recovering stored Newick tree: \n"
3571 + tree.getNewick());
3575 tp.fitToWindow.setState(tree.getFitToWindow());
3576 tp.fitToWindow_actionPerformed(null);
3578 if (tree.getFontName() != null)
3580 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3581 .getFontStyle(), tree.getFontSize()));
3585 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3586 .getFontStyle(), tree.getFontSize()));
3589 tp.showPlaceholders(tree.getMarkUnlinked());
3590 tp.showBootstrap(tree.getShowBootstrap());
3591 tp.showDistances(tree.getShowDistances());
3593 tp.treeCanvas.threshold = tree.getThreshold();
3595 if (tree.getCurrentTree())
3597 af.viewport.setCurrentTree(tp.getTree());
3601 } catch (Exception ex)
3603 ex.printStackTrace();
3608 * Load and link any saved structure viewers.
3615 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3616 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3619 * Run through all PDB ids on the alignment, and collect mappings between
3620 * distinct view ids and all sequences referring to that view.
3622 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3624 for (int i = 0; i < jseqs.length; i++)
3626 if (jseqs[i].getPdbidsCount() > 0)
3628 Pdbids[] ids = jseqs[i].getPdbids();
3629 for (int p = 0; p < ids.length; p++)
3631 final int structureStateCount = ids[p].getStructureStateCount();
3632 for (int s = 0; s < structureStateCount; s++)
3634 // check to see if we haven't already created this structure view
3635 final StructureState structureState = ids[p]
3636 .getStructureState(s);
3637 String sviewid = (structureState.getViewId() == null) ? null
3638 : structureState.getViewId() + uniqueSetSuffix;
3639 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3640 // Originally : ids[p].getFile()
3641 // : TODO: verify external PDB file recovery still works in normal
3642 // jalview project load
3643 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3644 jpdb.setId(ids[p].getId());
3646 int x = structureState.getXpos();
3647 int y = structureState.getYpos();
3648 int width = structureState.getWidth();
3649 int height = structureState.getHeight();
3651 // Probably don't need to do this anymore...
3652 // Desktop.desktop.getComponentAt(x, y);
3653 // TODO: NOW: check that this recovers the PDB file correctly.
3654 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3655 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3657 if (sviewid == null)
3659 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3662 if (!structureViewers.containsKey(sviewid))
3664 structureViewers.put(sviewid,
3665 new StructureViewerModel(x, y, width, height, false,
3666 false, true, structureState.getViewId(),
3667 structureState.getType()));
3668 // Legacy pre-2.7 conversion JAL-823 :
3669 // do not assume any view has to be linked for colour by
3673 // assemble String[] { pdb files }, String[] { id for each
3674 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3675 // seqs_file 2}, boolean[] {
3676 // linkAlignPanel,superposeWithAlignpanel}} from hash
3677 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3678 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3679 | (structureState.hasAlignwithAlignPanel() ? structureState
3680 .getAlignwithAlignPanel() : false));
3683 * Default colour by linked panel to false if not specified (e.g.
3684 * for pre-2.7 projects)
3686 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3687 colourWithAlignPanel |= (structureState
3688 .hasColourwithAlignPanel() ? structureState
3689 .getColourwithAlignPanel() : false);
3690 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3693 * Default colour by viewer to true if not specified (e.g. for
3696 boolean colourByViewer = jmoldat.isColourByViewer();
3697 colourByViewer &= structureState.hasColourByJmol() ? structureState
3698 .getColourByJmol() : true;
3699 jmoldat.setColourByViewer(colourByViewer);
3701 if (jmoldat.getStateData().length() < structureState
3702 .getContent().length())
3705 jmoldat.setStateData(structureState.getContent());
3708 if (ids[p].getFile() != null)
3710 File mapkey = new File(ids[p].getFile());
3711 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3712 if (seqstrmaps == null)
3714 jmoldat.getFileData().put(
3716 seqstrmaps = jmoldat.new StructureData(pdbFile,
3719 if (!seqstrmaps.getSeqList().contains(seq))
3721 seqstrmaps.getSeqList().add(seq);
3727 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");
3734 // Instantiate the associated structure views
3735 for (Entry<String, StructureViewerModel> entry : structureViewers
3740 createOrLinkStructureViewer(entry, af, ap, jprovider);
3741 } catch (Exception e)
3743 System.err.println("Error loading structure viewer: "
3745 // failed - try the next one
3757 protected void createOrLinkStructureViewer(
3758 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3759 AlignmentPanel ap, jarInputStreamProvider jprovider)
3761 final StructureViewerModel stateData = viewerData.getValue();
3764 * Search for any viewer windows already open from other alignment views
3765 * that exactly match the stored structure state
3767 StructureViewerBase comp = findMatchingViewer(viewerData);
3771 linkStructureViewer(ap, comp, stateData);
3776 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3777 * "viewer_"+stateData.viewId
3779 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3781 createChimeraViewer(viewerData, af, jprovider);
3786 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3788 createJmolViewer(viewerData, af, jprovider);
3793 * Create a new Chimera viewer.
3799 protected void createChimeraViewer(
3800 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3801 jarInputStreamProvider jprovider)
3803 StructureViewerModel data = viewerData.getValue();
3804 String chimeraSessionFile = data.getStateData();
3807 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3809 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3810 * 'uniquified' sviewid used to reconstruct the viewer here
3812 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3813 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3816 Set<Entry<File, StructureData>> fileData = data.getFileData()
3818 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3819 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3820 for (Entry<File, StructureData> pdb : fileData)
3822 String filePath = pdb.getValue().getFilePath();
3823 String pdbId = pdb.getValue().getPdbId();
3824 // pdbs.add(new PDBEntry(filePath, pdbId));
3825 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3826 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3827 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3831 boolean colourByChimera = data.isColourByViewer();
3832 boolean colourBySequence = data.isColourWithAlignPanel();
3834 // TODO use StructureViewer as a factory here, see JAL-1761
3835 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3836 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3838 String newViewId = viewerData.getKey();
3840 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3841 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3842 colourBySequence, newViewId);
3843 cvf.setSize(data.getWidth(), data.getHeight());
3844 cvf.setLocation(data.getX(), data.getY());
3848 * Create a new Jmol window. First parse the Jmol state to translate filenames
3849 * loaded into the view, and record the order in which files are shown in the
3850 * Jmol view, so we can add the sequence mappings in same order.
3856 protected void createJmolViewer(
3857 final Entry<String, StructureViewerModel> viewerData,
3858 AlignFrame af, jarInputStreamProvider jprovider)
3860 final StructureViewerModel svattrib = viewerData.getValue();
3861 String state = svattrib.getStateData();
3864 * Pre-2.9: state element value is the Jmol state string
3866 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3869 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3871 state = readJarEntry(jprovider,
3872 getViewerJarEntryName(svattrib.getViewId()));
3875 List<String> pdbfilenames = new ArrayList<String>();
3876 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3877 List<String> pdbids = new ArrayList<String>();
3878 StringBuilder newFileLoc = new StringBuilder(64);
3879 int cp = 0, ncp, ecp;
3880 Map<File, StructureData> oldFiles = svattrib.getFileData();
3881 while ((ncp = state.indexOf("load ", cp)) > -1)
3885 // look for next filename in load statement
3886 newFileLoc.append(state.substring(cp,
3887 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3888 String oldfilenam = state.substring(ncp,
3889 ecp = state.indexOf("\"", ncp));
3890 // recover the new mapping data for this old filename
3891 // have to normalize filename - since Jmol and jalview do
3893 // translation differently.
3894 StructureData filedat = oldFiles.get(new File(oldfilenam));
3895 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3896 pdbfilenames.add(filedat.getFilePath());
3897 pdbids.add(filedat.getPdbId());
3898 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3899 newFileLoc.append("\"");
3900 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3901 // look for next file statement.
3902 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3906 // just append rest of state
3907 newFileLoc.append(state.substring(cp));
3911 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3912 newFileLoc = new StringBuilder(state);
3913 newFileLoc.append("; load append ");
3914 for (File id : oldFiles.keySet())
3916 // add this and any other pdb files that should be present in
3918 StructureData filedat = oldFiles.get(id);
3919 newFileLoc.append(filedat.getFilePath());
3920 pdbfilenames.add(filedat.getFilePath());
3921 pdbids.add(filedat.getPdbId());
3922 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3923 newFileLoc.append(" \"");
3924 newFileLoc.append(filedat.getFilePath());
3925 newFileLoc.append("\"");
3928 newFileLoc.append(";");
3931 if (newFileLoc.length() == 0)
3935 int histbug = newFileLoc.indexOf("history = ");
3939 * change "history = [true|false];" to "history = [1|0];"
3942 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3943 String val = (diff == -1) ? null : newFileLoc
3944 .substring(histbug, diff);
3945 if (val != null && val.length() >= 4)
3947 if (val.contains("e")) // eh? what can it be?
3949 if (val.trim().equals("true"))
3957 newFileLoc.replace(histbug, diff, val);
3962 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3964 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3965 final SequenceI[][] sq = seqmaps
3966 .toArray(new SequenceI[seqmaps.size()][]);
3967 final String fileloc = newFileLoc.toString();
3968 final String sviewid = viewerData.getKey();
3969 final AlignFrame alf = af;
3970 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3971 svattrib.getWidth(), svattrib.getHeight());
3974 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3979 JalviewStructureDisplayI sview = null;
3982 sview = new StructureViewer(alf.alignPanel
3983 .getStructureSelectionManager()).createView(
3984 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3985 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3986 addNewStructureViewer(sview);
3987 } catch (OutOfMemoryError ex)
3989 new OOMWarning("restoring structure view for PDB id " + id,
3990 (OutOfMemoryError) ex.getCause());
3991 if (sview != null && sview.isVisible())
3993 sview.closeViewer(false);
3994 sview.setVisible(false);
4000 } catch (InvocationTargetException ex)
4002 warn("Unexpected error when opening Jmol view.", ex);
4004 } catch (InterruptedException e)
4006 // e.printStackTrace();
4012 * Generates a name for the entry in the project jar file to hold state
4013 * information for a structure viewer
4018 protected String getViewerJarEntryName(String viewId)
4020 return VIEWER_PREFIX + viewId;
4024 * Returns any open frame that matches given structure viewer data. The match
4025 * is based on the unique viewId, or (for older project versions) the frame's
4031 protected StructureViewerBase findMatchingViewer(
4032 Entry<String, StructureViewerModel> viewerData)
4034 final String sviewid = viewerData.getKey();
4035 final StructureViewerModel svattrib = viewerData.getValue();
4036 StructureViewerBase comp = null;
4037 JInternalFrame[] frames = getAllFrames();
4038 for (JInternalFrame frame : frames)
4040 if (frame instanceof StructureViewerBase)
4043 * Post jalview 2.4 schema includes structure view id
4046 && ((StructureViewerBase) frame).getViewId()
4049 comp = (StructureViewerBase) frame;
4050 break; // break added in 2.9
4053 * Otherwise test for matching position and size of viewer frame
4055 else if (frame.getX() == svattrib.getX()
4056 && frame.getY() == svattrib.getY()
4057 && frame.getHeight() == svattrib.getHeight()
4058 && frame.getWidth() == svattrib.getWidth())
4060 comp = (StructureViewerBase) frame;
4061 // no break in faint hope of an exact match on viewId
4069 * Link an AlignmentPanel to an existing structure viewer.
4074 * @param useinViewerSuperpos
4075 * @param usetoColourbyseq
4076 * @param viewerColouring
4078 protected void linkStructureViewer(AlignmentPanel ap,
4079 StructureViewerBase viewer, StructureViewerModel stateData)
4081 // NOTE: if the jalview project is part of a shared session then
4082 // view synchronization should/could be done here.
4084 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4085 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4086 final boolean viewerColouring = stateData.isColourByViewer();
4087 Map<File, StructureData> oldFiles = stateData.getFileData();
4090 * Add mapping for sequences in this view to an already open viewer
4092 final AAStructureBindingModel binding = viewer.getBinding();
4093 for (File id : oldFiles.keySet())
4095 // add this and any other pdb files that should be present in the
4097 StructureData filedat = oldFiles.get(id);
4098 String pdbFile = filedat.getFilePath();
4099 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4100 binding.getSsm().setMapping(seq, null, pdbFile,
4101 jalview.io.AppletFormatAdapter.FILE);
4102 binding.addSequenceForStructFile(pdbFile, seq);
4104 // and add the AlignmentPanel's reference to the view panel
4105 viewer.addAlignmentPanel(ap);
4106 if (useinViewerSuperpos)
4108 viewer.useAlignmentPanelForSuperposition(ap);
4112 viewer.excludeAlignmentPanelForSuperposition(ap);
4114 if (usetoColourbyseq)
4116 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4120 viewer.excludeAlignmentPanelForColourbyseq(ap);
4125 * Get all frames within the Desktop.
4129 protected JInternalFrame[] getAllFrames()
4131 JInternalFrame[] frames = null;
4132 // TODO is this necessary - is it safe - risk of hanging?
4137 frames = Desktop.desktop.getAllFrames();
4138 } catch (ArrayIndexOutOfBoundsException e)
4140 // occasional No such child exceptions are thrown here...
4144 } catch (InterruptedException f)
4148 } while (frames == null);
4153 * Answers true if 'version' is equal to or later than 'supported', where each
4154 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4155 * changes. Development and test values for 'version' are leniently treated
4159 * - minimum version we are comparing against
4161 * - version of data being processsed
4164 public static boolean isVersionStringLaterThan(String supported,
4167 if (supported == null || version == null
4168 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4169 || version.equalsIgnoreCase("Test")
4170 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4172 System.err.println("Assuming project file with "
4173 + (version == null ? "null" : version)
4174 + " is compatible with Jalview version " + supported);
4179 return StringUtils.compareVersions(version, supported, "b") >= 0;
4183 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4185 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4187 if (newStructureViewers != null)
4189 sview.getBinding().setFinishedLoadingFromArchive(false);
4190 newStructureViewers.add(sview);
4194 protected void setLoadingFinishedForNewStructureViewers()
4196 if (newStructureViewers != null)
4198 for (JalviewStructureDisplayI sview : newStructureViewers)
4200 sview.getBinding().setFinishedLoadingFromArchive(true);
4202 newStructureViewers.clear();
4203 newStructureViewers = null;
4207 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4208 List<SequenceI> hiddenSeqs, AlignmentI al,
4209 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4210 String viewId, List<JvAnnotRow> autoAlan)
4212 AlignFrame af = null;
4213 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4214 uniqueSeqSetId, viewId);
4216 af.setFileName(file, "Jalview");
4218 for (int i = 0; i < JSEQ.length; i++)
4220 af.viewport.setSequenceColour(af.viewport.getAlignment()
4221 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4226 af.getViewport().setColourByReferenceSeq(true);
4227 af.getViewport().setDisplayReferenceSeq(true);
4230 af.viewport.setGatherViewsHere(view.getGatheredViews());
4232 if (view.getSequenceSetId() != null)
4234 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4236 af.viewport.setSequenceSetId(uniqueSeqSetId);
4239 // propagate shared settings to this new view
4240 af.viewport.setHistoryList(av.getHistoryList());
4241 af.viewport.setRedoList(av.getRedoList());
4245 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4247 // TODO: check if this method can be called repeatedly without
4248 // side-effects if alignpanel already registered.
4249 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4251 // apply Hidden regions to view.
4252 if (hiddenSeqs != null)
4254 for (int s = 0; s < JSEQ.length; s++)
4256 SequenceGroup hidden = new SequenceGroup();
4257 boolean isRepresentative = false;
4258 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4260 isRepresentative = true;
4261 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4262 .getHiddenSequences(r));
4263 hidden.addSequence(sequenceToHide, false);
4264 // remove from hiddenSeqs list so we don't try to hide it twice
4265 hiddenSeqs.remove(sequenceToHide);
4267 if (isRepresentative)
4269 SequenceI representativeSequence = al.getSequenceAt(s);
4270 hidden.addSequence(representativeSequence, false);
4271 af.viewport.hideRepSequences(representativeSequence, hidden);
4275 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4277 af.viewport.hideSequence(hseqs);
4280 // recover view properties and display parameters
4281 if (view.getViewName() != null)
4283 af.viewport.viewName = view.getViewName();
4284 af.setInitialTabVisible();
4286 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4289 af.viewport.setShowAnnotation(view.getShowAnnotation());
4290 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4292 af.viewport.setColourText(view.getShowColourText());
4294 af.viewport.setConservationSelected(view.getConservationSelected());
4295 af.viewport.setShowJVSuffix(view.getShowFullId());
4296 af.viewport.setRightAlignIds(view.getRightAlignIds());
4297 af.viewport.setFont(
4298 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4299 .getFontSize()), true);
4300 ViewStyleI vs = af.viewport.getViewStyle();
4301 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4302 af.viewport.setViewStyle(vs);
4303 // TODO: allow custom charWidth/Heights to be restored by updating them
4304 // after setting font - which means set above to false
4305 af.viewport.setRenderGaps(view.getRenderGaps());
4306 af.viewport.setWrapAlignment(view.getWrapAlignment());
4307 af.viewport.setShowAnnotation(view.getShowAnnotation());
4309 af.viewport.setShowBoxes(view.getShowBoxes());
4311 af.viewport.setShowText(view.getShowText());
4313 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4314 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4315 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4316 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4317 .isShowUnconserved() : false);
4318 af.viewport.setStartRes(view.getStartRes());
4319 af.viewport.setStartSeq(view.getStartSeq());
4320 af.alignPanel.updateLayout();
4321 ColourSchemeI cs = null;
4322 // apply colourschemes
4323 if (view.getBgColour() != null)
4325 if (view.getBgColour().startsWith("ucs"))
4327 cs = getUserColourScheme(jms, view.getBgColour());
4329 else if (view.getBgColour().startsWith("Annotation"))
4331 AnnotationColours viewAnnColour = view.getAnnotationColours();
4332 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4339 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4344 cs.setThreshold(view.getPidThreshold(), true);
4345 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4349 af.viewport.setGlobalColourScheme(cs);
4350 af.viewport.setColourAppliesToAllGroups(false);
4352 if (view.getConservationSelected() && cs != null)
4354 cs.setConservationInc(view.getConsThreshold());
4357 af.changeColour(cs);
4359 af.viewport.setColourAppliesToAllGroups(true);
4361 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4363 if (view.hasCentreColumnLabels())
4365 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4367 if (view.hasIgnoreGapsinConsensus())
4369 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4372 if (view.hasFollowHighlight())
4374 af.viewport.setFollowHighlight(view.getFollowHighlight());
4376 if (view.hasFollowSelection())
4378 af.viewport.followSelection = view.getFollowSelection();
4380 if (view.hasShowConsensusHistogram())
4382 af.viewport.setShowConsensusHistogram(view
4383 .getShowConsensusHistogram());
4387 af.viewport.setShowConsensusHistogram(true);
4389 if (view.hasShowSequenceLogo())
4391 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4395 af.viewport.setShowSequenceLogo(false);
4397 if (view.hasNormaliseSequenceLogo())
4399 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4401 if (view.hasShowDbRefTooltip())
4403 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4405 if (view.hasShowNPfeatureTooltip())
4407 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4409 if (view.hasShowGroupConsensus())
4411 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4415 af.viewport.setShowGroupConsensus(false);
4417 if (view.hasShowGroupConservation())
4419 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4423 af.viewport.setShowGroupConservation(false);
4426 // recover featre settings
4427 if (jms.getFeatureSettings() != null)
4429 FeaturesDisplayed fdi;
4430 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4431 String[] renderOrder = new String[jms.getFeatureSettings()
4432 .getSettingCount()];
4433 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4434 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4436 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4438 Setting setting = jms.getFeatureSettings().getSetting(fs);
4439 if (setting.hasMincolour())
4441 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4442 new Color(setting.getMincolour()), new Color(
4443 setting.getColour()), setting.getMin(),
4444 setting.getMax()) : new FeatureColour(new Color(
4445 setting.getMincolour()), new Color(setting.getColour()),
4447 if (setting.hasThreshold())
4449 gc.setThreshold(setting.getThreshold());
4450 int threshstate = setting.getThreshstate();
4451 // -1 = None, 0 = Below, 1 = Above threshold
4452 if (threshstate == 0)
4454 gc.setBelowThreshold(true);
4456 else if (threshstate == 1)
4458 gc.setAboveThreshold(true);
4461 gc.setAutoScaled(true); // default
4462 if (setting.hasAutoScale())
4464 gc.setAutoScaled(setting.getAutoScale());
4466 if (setting.hasColourByLabel())
4468 gc.setColourByLabel(setting.getColourByLabel());
4470 // and put in the feature colour table.
4471 featureColours.put(setting.getType(), gc);
4475 featureColours.put(setting.getType(), new FeatureColour(
4476 new Color(setting.getColour())));
4478 renderOrder[fs] = setting.getType();
4479 if (setting.hasOrder())
4481 featureOrder.put(setting.getType(), setting.getOrder());
4485 featureOrder.put(setting.getType(), new Float(fs
4486 / jms.getFeatureSettings().getSettingCount()));
4488 if (setting.getDisplay())
4490 fdi.setVisible(setting.getType());
4493 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4494 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4496 Group grp = jms.getFeatureSettings().getGroup(gs);
4497 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4499 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4500 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4501 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4502 FeatureRendererSettings frs = new FeatureRendererSettings(
4503 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4504 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4505 .transferSettings(frs);
4509 if (view.getHiddenColumnsCount() > 0)
4511 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4513 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4514 .getHiddenColumns(c).getEnd() // +1
4518 if (view.getCalcIdParam() != null)
4520 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4522 if (calcIdParam != null)
4524 if (recoverCalcIdParam(calcIdParam, af.viewport))
4529 warn("Couldn't recover parameters for "
4530 + calcIdParam.getCalcId());
4535 af.setMenusFromViewport(af.viewport);
4537 // TODO: we don't need to do this if the viewport is aready visible.
4539 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4540 * has a 'cdna/protein complement' view, in which case save it in order to
4541 * populate a SplitFrame once all views have been read in.
4543 String complementaryViewId = view.getComplementId();
4544 if (complementaryViewId == null)
4546 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4548 // recompute any autoannotation
4549 af.alignPanel.updateAnnotation(false, true);
4550 reorderAutoannotation(af, al, autoAlan);
4551 af.alignPanel.alignmentChanged();
4555 splitFrameCandidates.put(view, af);
4560 private ColourSchemeI constructAnnotationColour(
4561 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4562 JalviewModelSequence jms, boolean checkGroupAnnColour)
4564 boolean propagateAnnColour = false;
4565 ColourSchemeI cs = null;
4566 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4567 if (checkGroupAnnColour && al.getGroups() != null
4568 && al.getGroups().size() > 0)
4570 // pre 2.8.1 behaviour
4571 // check to see if we should transfer annotation colours
4572 propagateAnnColour = true;
4573 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4575 if (sg.cs instanceof AnnotationColourGradient)
4577 propagateAnnColour = false;
4581 // int find annotation
4582 if (annAlignment.getAlignmentAnnotation() != null)
4584 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4586 if (annAlignment.getAlignmentAnnotation()[i].label
4587 .equals(viewAnnColour.getAnnotation()))
4589 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4591 annAlignment.getAlignmentAnnotation()[i]
4592 .setThreshold(new jalview.datamodel.GraphLine(
4593 viewAnnColour.getThreshold(), "Threshold",
4594 java.awt.Color.black)
4599 if (viewAnnColour.getColourScheme().equals("None"))
4601 cs = new AnnotationColourGradient(
4602 annAlignment.getAlignmentAnnotation()[i],
4603 new java.awt.Color(viewAnnColour.getMinColour()),
4604 new java.awt.Color(viewAnnColour.getMaxColour()),
4605 viewAnnColour.getAboveThreshold());
4607 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4609 cs = new AnnotationColourGradient(
4610 annAlignment.getAlignmentAnnotation()[i],
4611 getUserColourScheme(jms,
4612 viewAnnColour.getColourScheme()),
4613 viewAnnColour.getAboveThreshold());
4617 cs = new AnnotationColourGradient(
4618 annAlignment.getAlignmentAnnotation()[i],
4619 ColourSchemeProperty.getColour(al,
4620 viewAnnColour.getColourScheme()),
4621 viewAnnColour.getAboveThreshold());
4623 if (viewAnnColour.hasPerSequence())
4625 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4628 if (viewAnnColour.hasPredefinedColours())
4630 ((AnnotationColourGradient) cs)
4631 .setPredefinedColours(viewAnnColour
4632 .isPredefinedColours());
4634 if (propagateAnnColour && al.getGroups() != null)
4636 // Also use these settings for all the groups
4637 for (int g = 0; g < al.getGroups().size(); g++)
4639 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4647 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4648 * new AnnotationColourGradient(
4649 * annAlignment.getAlignmentAnnotation()[i], new
4650 * java.awt.Color(viewAnnColour. getMinColour()), new
4651 * java.awt.Color(viewAnnColour. getMaxColour()),
4652 * viewAnnColour.getAboveThreshold()); } else
4655 sg.cs = new AnnotationColourGradient(
4656 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4657 viewAnnColour.getAboveThreshold());
4658 if (cs instanceof AnnotationColourGradient)
4660 if (viewAnnColour.hasPerSequence())
4662 ((AnnotationColourGradient) cs)
4663 .setSeqAssociated(viewAnnColour.isPerSequence());
4665 if (viewAnnColour.hasPredefinedColours())
4667 ((AnnotationColourGradient) cs)
4668 .setPredefinedColours(viewAnnColour
4669 .isPredefinedColours());
4685 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4686 List<JvAnnotRow> autoAlan)
4688 // copy over visualization settings for autocalculated annotation in the
4690 if (al.getAlignmentAnnotation() != null)
4693 * Kludge for magic autoannotation names (see JAL-811)
4695 String[] magicNames = new String[] { "Consensus", "Quality",
4697 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4698 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4699 for (String nm : magicNames)
4701 visan.put(nm, nullAnnot);
4703 for (JvAnnotRow auan : autoAlan)
4705 visan.put(auan.template.label
4706 + (auan.template.getCalcId() == null ? "" : "\t"
4707 + auan.template.getCalcId()), auan);
4709 int hSize = al.getAlignmentAnnotation().length;
4710 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4711 // work through any autoCalculated annotation already on the view
4712 // removing it if it should be placed in a different location on the
4713 // annotation panel.
4714 List<String> remains = new ArrayList<String>(visan.keySet());
4715 for (int h = 0; h < hSize; h++)
4717 jalview.datamodel.AlignmentAnnotation jalan = al
4718 .getAlignmentAnnotation()[h];
4719 if (jalan.autoCalculated)
4722 JvAnnotRow valan = visan.get(k = jalan.label);
4723 if (jalan.getCalcId() != null)
4725 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4730 // delete the auto calculated row from the alignment
4731 al.deleteAnnotation(jalan, false);
4735 if (valan != nullAnnot)
4737 if (jalan != valan.template)
4739 // newly created autoannotation row instance
4740 // so keep a reference to the visible annotation row
4741 // and copy over all relevant attributes
4742 if (valan.template.graphHeight >= 0)
4745 jalan.graphHeight = valan.template.graphHeight;
4747 jalan.visible = valan.template.visible;
4749 reorder.add(new JvAnnotRow(valan.order, jalan));
4754 // Add any (possibly stale) autocalculated rows that were not appended to
4755 // the view during construction
4756 for (String other : remains)
4758 JvAnnotRow othera = visan.get(other);
4759 if (othera != nullAnnot && othera.template.getCalcId() != null
4760 && othera.template.getCalcId().length() > 0)
4762 reorder.add(othera);
4765 // now put the automatic annotation in its correct place
4766 int s = 0, srt[] = new int[reorder.size()];
4767 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4768 for (JvAnnotRow jvar : reorder)
4771 srt[s++] = jvar.order;
4774 jalview.util.QuickSort.sort(srt, rws);
4775 // and re-insert the annotation at its correct position
4776 for (JvAnnotRow jvar : rws)
4778 al.addAnnotation(jvar.template, jvar.order);
4780 af.alignPanel.adjustAnnotationHeight();
4784 Hashtable skipList = null;
4787 * TODO remove this method
4790 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4791 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4792 * throw new Error("Implementation Error. No skipList defined for this
4793 * Jalview2XML instance."); } return (AlignFrame)
4794 * skipList.get(view.getSequenceSetId()); }
4798 * Check if the Jalview view contained in object should be skipped or not.
4801 * @return true if view's sequenceSetId is a key in skipList
4803 private boolean skipViewport(JalviewModel object)
4805 if (skipList == null)
4810 if (skipList.containsKey(id = object.getJalviewModelSequence()
4811 .getViewport()[0].getSequenceSetId()))
4813 if (Cache.log != null && Cache.log.isDebugEnabled())
4815 Cache.log.debug("Skipping seuqence set id " + id);
4822 public void addToSkipList(AlignFrame af)
4824 if (skipList == null)
4826 skipList = new Hashtable();
4828 skipList.put(af.getViewport().getSequenceSetId(), af);
4831 public void clearSkipList()
4833 if (skipList != null)
4840 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4841 boolean ignoreUnrefed)
4843 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4845 Vector dseqs = null;
4848 // create a list of new dataset sequences
4849 dseqs = new Vector();
4851 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4853 Sequence vamsasSeq = vamsasSet.getSequence(i);
4854 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4856 // create a new dataset
4859 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4860 dseqs.copyInto(dsseqs);
4861 ds = new jalview.datamodel.Alignment(dsseqs);
4862 debug("Created new dataset " + vamsasSet.getDatasetId()
4863 + " for alignment " + System.identityHashCode(al));
4864 addDatasetRef(vamsasSet.getDatasetId(), ds);
4866 // set the dataset for the newly imported alignment.
4867 if (al.getDataset() == null && !ignoreUnrefed)
4876 * sequence definition to create/merge dataset sequence for
4880 * vector to add new dataset sequence to
4882 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4883 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4885 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4887 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4888 SequenceI dsq = null;
4889 if (sq != null && sq.getDatasetSequence() != null)
4891 dsq = sq.getDatasetSequence();
4893 if (sq == null && ignoreUnrefed)
4897 String sqid = vamsasSeq.getDsseqid();
4900 // need to create or add a new dataset sequence reference to this sequence
4903 dsq = seqRefIds.get(sqid);
4908 // make a new dataset sequence
4909 dsq = sq.createDatasetSequence();
4912 // make up a new dataset reference for this sequence
4913 sqid = seqHash(dsq);
4915 dsq.setVamsasId(uniqueSetSuffix + sqid);
4916 seqRefIds.put(sqid, dsq);
4921 dseqs.addElement(dsq);
4926 ds.addSequence(dsq);
4932 { // make this dataset sequence sq's dataset sequence
4933 sq.setDatasetSequence(dsq);
4934 // and update the current dataset alignment
4939 if (!dseqs.contains(dsq))
4946 if (ds.findIndex(dsq) < 0)
4948 ds.addSequence(dsq);
4955 // TODO: refactor this as a merge dataset sequence function
4956 // now check that sq (the dataset sequence) sequence really is the union of
4957 // all references to it
4958 // boolean pre = sq.getStart() < dsq.getStart();
4959 // boolean post = sq.getEnd() > dsq.getEnd();
4963 // StringBuffer sb = new StringBuffer();
4964 String newres = jalview.analysis.AlignSeq.extractGaps(
4965 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4966 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4967 && newres.length() > dsq.getLength())
4969 // Update with the longer sequence.
4973 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4974 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4975 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4976 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4978 dsq.setSequence(newres);
4980 // TODO: merges will never happen if we 'know' we have the real dataset
4981 // sequence - this should be detected when id==dssid
4983 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4984 // + (pre ? "prepended" : "") + " "
4985 // + (post ? "appended" : ""));
4991 * TODO use AlignmentI here and in related methods - needs
4992 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4994 Hashtable<String, AlignmentI> datasetIds = null;
4996 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
4998 private AlignmentI getDatasetFor(String datasetId)
5000 if (datasetIds == null)
5002 datasetIds = new Hashtable<String, AlignmentI>();
5005 if (datasetIds.containsKey(datasetId))
5007 return datasetIds.get(datasetId);
5012 private void addDatasetRef(String datasetId, AlignmentI dataset)
5014 if (datasetIds == null)
5016 datasetIds = new Hashtable<String, AlignmentI>();
5018 datasetIds.put(datasetId, dataset);
5022 * make a new dataset ID for this jalview dataset alignment
5027 private String getDatasetIdRef(AlignmentI dataset)
5029 if (dataset.getDataset() != null)
5031 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5033 String datasetId = makeHashCode(dataset, null);
5034 if (datasetId == null)
5036 // make a new datasetId and record it
5037 if (dataset2Ids == null)
5039 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5043 datasetId = dataset2Ids.get(dataset);
5045 if (datasetId == null)
5047 datasetId = "ds" + dataset2Ids.size() + 1;
5048 dataset2Ids.put(dataset, datasetId);
5054 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5056 for (int d = 0; d < sequence.getDBRefCount(); d++)
5058 DBRef dr = sequence.getDBRef(d);
5059 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5060 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5061 .getVersion(), sequence.getDBRef(d).getAccessionId());
5062 if (dr.getMapping() != null)
5064 entry.setMap(addMapping(dr.getMapping()));
5066 datasetSequence.addDBRef(entry);
5070 private jalview.datamodel.Mapping addMapping(Mapping m)
5072 SequenceI dsto = null;
5073 // Mapping m = dr.getMapping();
5074 int fr[] = new int[m.getMapListFromCount() * 2];
5075 Enumeration f = m.enumerateMapListFrom();
5076 for (int _i = 0; f.hasMoreElements(); _i += 2)
5078 MapListFrom mf = (MapListFrom) f.nextElement();
5079 fr[_i] = mf.getStart();
5080 fr[_i + 1] = mf.getEnd();
5082 int fto[] = new int[m.getMapListToCount() * 2];
5083 f = m.enumerateMapListTo();
5084 for (int _i = 0; f.hasMoreElements(); _i += 2)
5086 MapListTo mf = (MapListTo) f.nextElement();
5087 fto[_i] = mf.getStart();
5088 fto[_i + 1] = mf.getEnd();
5090 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5091 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5092 if (m.getMappingChoice() != null)
5094 MappingChoice mc = m.getMappingChoice();
5095 if (mc.getDseqFor() != null)
5097 String dsfor = "" + mc.getDseqFor();
5098 if (seqRefIds.containsKey(dsfor))
5103 jmap.setTo(seqRefIds.get(dsfor));
5107 frefedSequence.add(newMappingRef(dsfor, jmap));
5113 * local sequence definition
5115 Sequence ms = mc.getSequence();
5116 SequenceI djs = null;
5117 String sqid = ms.getDsseqid();
5118 if (sqid != null && sqid.length() > 0)
5121 * recover dataset sequence
5123 djs = seqRefIds.get(sqid);
5128 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5129 sqid = ((Object) ms).toString(); // make up a new hascode for
5130 // undefined dataset sequence hash
5131 // (unlikely to happen)
5137 * make a new dataset sequence and add it to refIds hash
5139 djs = new jalview.datamodel.Sequence(ms.getName(),
5141 djs.setStart(jmap.getMap().getToLowest());
5142 djs.setEnd(jmap.getMap().getToHighest());
5143 djs.setVamsasId(uniqueSetSuffix + sqid);
5145 incompleteSeqs.put(sqid, djs);
5146 seqRefIds.put(sqid, djs);
5149 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5158 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5159 boolean keepSeqRefs)
5162 JalviewModel jm = saveState(ap, null, null, null);
5167 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5171 uniqueSetSuffix = "";
5172 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5177 if (this.frefedSequence == null)
5179 frefedSequence = new Vector();
5182 viewportsAdded.clear();
5184 AlignFrame af = loadFromObject(jm, null, false, null);
5185 af.alignPanels.clear();
5186 af.closeMenuItem_actionPerformed(true);
5189 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5190 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5191 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5192 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5193 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5196 return af.alignPanel;
5200 * flag indicating if hashtables should be cleared on finalization TODO this
5201 * flag may not be necessary
5203 private final boolean _cleartables = true;
5205 private Hashtable jvids2vobj;
5210 * @see java.lang.Object#finalize()
5213 protected void finalize() throws Throwable
5215 // really make sure we have no buried refs left.
5220 this.seqRefIds = null;
5221 this.seqsToIds = null;
5225 private void warn(String msg)
5230 private void warn(String msg, Exception e)
5232 if (Cache.log != null)
5236 Cache.log.warn(msg, e);
5240 Cache.log.warn(msg);
5245 System.err.println("Warning: " + msg);
5248 e.printStackTrace();
5253 private void debug(String string)
5255 debug(string, null);
5258 private void debug(String msg, Exception e)
5260 if (Cache.log != null)
5264 Cache.log.debug(msg, e);
5268 Cache.log.debug(msg);
5273 System.err.println("Warning: " + msg);
5276 e.printStackTrace();
5282 * set the object to ID mapping tables used to write/recover objects and XML
5283 * ID strings for the jalview project. If external tables are provided then
5284 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5285 * object goes out of scope. - also populates the datasetIds hashtable with
5286 * alignment objects containing dataset sequences
5289 * Map from ID strings to jalview datamodel
5291 * Map from jalview datamodel to ID strings
5295 public void setObjectMappingTables(Hashtable vobj2jv,
5296 IdentityHashMap jv2vobj)
5298 this.jv2vobj = jv2vobj;
5299 this.vobj2jv = vobj2jv;
5300 Iterator ds = jv2vobj.keySet().iterator();
5302 while (ds.hasNext())
5304 Object jvobj = ds.next();
5305 id = jv2vobj.get(jvobj).toString();
5306 if (jvobj instanceof jalview.datamodel.Alignment)
5308 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5310 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5313 else if (jvobj instanceof jalview.datamodel.Sequence)
5315 // register sequence object so the XML parser can recover it.
5316 if (seqRefIds == null)
5318 seqRefIds = new HashMap<String, SequenceI>();
5320 if (seqsToIds == null)
5322 seqsToIds = new IdentityHashMap<SequenceI, String>();
5324 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5325 seqsToIds.put((SequenceI) jvobj, id);
5327 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5330 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5331 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5332 if (jvann.annotationId == null)
5334 jvann.annotationId = anid;
5336 if (!jvann.annotationId.equals(anid))
5338 // TODO verify that this is the correct behaviour
5339 this.warn("Overriding Annotation ID for " + anid
5340 + " from different id : " + jvann.annotationId);
5341 jvann.annotationId = anid;
5344 else if (jvobj instanceof String)
5346 if (jvids2vobj == null)
5348 jvids2vobj = new Hashtable();
5349 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5354 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5360 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5361 * objects created from the project archive. If string is null (default for
5362 * construction) then suffix will be set automatically.
5366 public void setUniqueSetSuffix(String string)
5368 uniqueSetSuffix = string;
5373 * uses skipList2 as the skipList for skipping views on sequence sets
5374 * associated with keys in the skipList
5378 public void setSkipList(Hashtable skipList2)
5380 skipList = skipList2;
5384 * Reads the jar entry of given name and returns its contents, or null if the
5385 * entry is not found.
5388 * @param jarEntryName
5391 protected String readJarEntry(jarInputStreamProvider jprovider,
5392 String jarEntryName)
5394 String result = null;
5395 BufferedReader in = null;
5400 * Reopen the jar input stream and traverse its entries to find a matching
5403 JarInputStream jin = jprovider.getJarInputStream();
5404 JarEntry entry = null;
5407 entry = jin.getNextJarEntry();
5408 } while (entry != null && !entry.getName().equals(jarEntryName));
5412 StringBuilder out = new StringBuilder(256);
5413 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5416 while ((data = in.readLine()) != null)
5420 result = out.toString();
5424 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5426 } catch (Exception ex)
5428 ex.printStackTrace();
5436 } catch (IOException e)
5447 * Returns an incrementing counter (0, 1, 2...)
5451 private synchronized int nextCounter()