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>();
638 // resolve splitframes
639 if (af.getViewport().getCodingComplement() != null)
641 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
647 saveAllFrames(frames, jout);
651 } catch (Exception foo)
657 } catch (Exception ex)
659 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
660 ex.printStackTrace();
665 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
666 String fileName, JarOutputStream jout)
669 for (String dssids : dsses.keySet())
671 AlignFrame _af = dsses.get(dssids);
672 String jfileName = fileName + " Dataset for " + _af.getTitle();
673 if (!jfileName.endsWith(".xml"))
675 jfileName = jfileName + ".xml";
677 saveState(_af.alignPanel, jfileName, true, jout, null);
682 * create a JalviewModel from an alignment view and marshall it to a
686 * panel to create jalview model for
688 * name of alignment panel written to output stream
695 public JalviewModel saveState(AlignmentPanel ap, String fileName,
696 JarOutputStream jout, List<String> viewIds)
698 return saveState(ap, fileName, false, jout, viewIds);
702 * create a JalviewModel from an alignment view and marshall it to a
706 * panel to create jalview model for
708 * name of alignment panel written to output stream
710 * when true, only write the dataset for the alignment, not the data
711 * associated with the view.
717 public JalviewModel saveState(AlignmentPanel ap, String fileName,
718 boolean storeDS, JarOutputStream jout, List<String> viewIds)
722 viewIds = new ArrayList<String>();
727 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
729 AlignViewport av = ap.av;
731 JalviewModel object = new JalviewModel();
732 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
734 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
735 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
736 "Development Build"));
739 * rjal is full height alignment, jal is actual alignment with full metadata
740 * but excludes hidden sequences.
742 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
744 if (av.hasHiddenRows())
746 rjal = jal.getHiddenSequences().getFullAlignment();
749 SequenceSet vamsasSet = new SequenceSet();
751 JalviewModelSequence jms = new JalviewModelSequence();
753 vamsasSet.setGapChar(jal.getGapCharacter() + "");
755 if (jal.getDataset() != null)
757 // dataset id is the dataset's hashcode
758 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
761 // switch jal and the dataset
762 jal = jal.getDataset();
766 if (jal.getProperties() != null)
768 Enumeration en = jal.getProperties().keys();
769 while (en.hasMoreElements())
771 String key = en.nextElement().toString();
772 SequenceSetProperties ssp = new SequenceSetProperties();
774 ssp.setValue(jal.getProperties().get(key).toString());
775 vamsasSet.addSequenceSetProperties(ssp);
780 Set<String> calcIdSet = new HashSet<String>();
783 for (final SequenceI jds : rjal.getSequences())
785 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
786 : jds.getDatasetSequence();
787 String id = seqHash(jds);
789 if (seqRefIds.get(id) != null)
791 // This happens for two reasons: 1. multiple views are being serialised.
792 // 2. the hashCode has collided with another sequence's code. This DOES
793 // HAPPEN! (PF00072.15.stk does this)
794 // JBPNote: Uncomment to debug writing out of files that do not read
795 // back in due to ArrayOutOfBoundExceptions.
796 // System.err.println("vamsasSeq backref: "+id+"");
797 // System.err.println(jds.getName()+"
798 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
799 // System.err.println("Hashcode: "+seqHash(jds));
800 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
801 // System.err.println(rsq.getName()+"
802 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
803 // System.err.println("Hashcode: "+seqHash(rsq));
807 vamsasSeq = createVamsasSequence(id, jds);
808 vamsasSet.addSequence(vamsasSeq);
809 seqRefIds.put(id, jds);
813 jseq.setStart(jds.getStart());
814 jseq.setEnd(jds.getEnd());
815 jseq.setColour(av.getSequenceColour(jds).getRGB());
817 jseq.setId(id); // jseq id should be a string not a number
820 // Store any sequences this sequence represents
821 if (av.hasHiddenRows())
823 // use rjal, contains the full height alignment
824 jseq.setHidden(av.getAlignment().getHiddenSequences()
827 if (av.isHiddenRepSequence(jds))
829 jalview.datamodel.SequenceI[] reps = av
830 .getRepresentedSequences(jds)
831 .getSequencesInOrder(rjal);
833 for (int h = 0; h < reps.length; h++)
837 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
842 // mark sequence as reference - if it is the reference for this view
845 jseq.setViewreference(jds == jal.getSeqrep());
849 // TODO: omit sequence features from each alignment view's XML dump if we
850 // are storing dataset
851 if (jds.getSequenceFeatures() != null)
853 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
855 while (index < sf.length)
857 Features features = new Features();
859 features.setBegin(sf[index].getBegin());
860 features.setEnd(sf[index].getEnd());
861 features.setDescription(sf[index].getDescription());
862 features.setType(sf[index].getType());
863 features.setFeatureGroup(sf[index].getFeatureGroup());
864 features.setScore(sf[index].getScore());
865 if (sf[index].links != null)
867 for (int l = 0; l < sf[index].links.size(); l++)
869 OtherData keyValue = new OtherData();
870 keyValue.setKey("LINK_" + l);
871 keyValue.setValue(sf[index].links.elementAt(l).toString());
872 features.addOtherData(keyValue);
875 if (sf[index].otherDetails != null)
878 Iterator<String> keys = sf[index].otherDetails.keySet()
880 while (keys.hasNext())
883 OtherData keyValue = new OtherData();
884 keyValue.setKey(key);
885 keyValue.setValue(sf[index].otherDetails.get(key).toString());
886 features.addOtherData(keyValue);
890 jseq.addFeatures(features);
895 if (jdatasq.getAllPDBEntries() != null)
897 Enumeration en = jdatasq.getAllPDBEntries().elements();
898 while (en.hasMoreElements())
900 Pdbids pdb = new Pdbids();
901 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
904 String pdbId = entry.getId();
906 pdb.setType(entry.getType());
909 * Store any structure views associated with this sequence. This
910 * section copes with duplicate entries in the project, so a dataset
911 * only view *should* be coped with sensibly.
913 // This must have been loaded, is it still visible?
914 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
915 String matchedFile = null;
916 for (int f = frames.length - 1; f > -1; f--)
918 if (frames[f] instanceof StructureViewerBase)
920 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
921 matchedFile = saveStructureState(ap, jds, pdb, entry,
922 viewIds, matchedFile, viewFrame);
924 * Only store each structure viewer's state once in the project
925 * jar. First time through only (storeDS==false)
927 String viewId = viewFrame.getViewId();
928 if (!storeDS && !viewIds.contains(viewId))
933 String viewerState = viewFrame.getStateInfo();
934 writeJarEntry(jout, getViewerJarEntryName(viewId),
935 viewerState.getBytes());
936 } catch (IOException e)
938 System.err.println("Error saving viewer state: "
945 if (matchedFile != null || entry.getFile() != null)
947 if (entry.getFile() != null)
950 matchedFile = entry.getFile();
952 pdb.setFile(matchedFile); // entry.getFile());
953 if (pdbfiles == null)
955 pdbfiles = new ArrayList<String>();
958 if (!pdbfiles.contains(pdbId))
961 copyFileToJar(jout, matchedFile, pdbId);
965 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
967 PdbentryItem item = new PdbentryItem();
968 Hashtable properties = entry.getProperty();
969 Enumeration en2 = properties.keys();
970 while (en2.hasMoreElements())
972 Property prop = new Property();
973 String key = en2.nextElement().toString();
975 prop.setValue(properties.get(key).toString());
976 item.addProperty(prop);
978 pdb.addPdbentryItem(item);
985 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
990 if (!storeDS && av.hasHiddenRows())
992 jal = av.getAlignment();
995 if (jal.getCodonFrames() != null)
997 List<AlignedCodonFrame> jac = jal.getCodonFrames();
998 for (AlignedCodonFrame acf : jac)
1000 AlcodonFrame alc = new AlcodonFrame();
1001 if (acf.getProtMappings() != null
1002 && acf.getProtMappings().length > 0)
1004 boolean hasMap = false;
1005 SequenceI[] dnas = acf.getdnaSeqs();
1006 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1007 for (int m = 0; m < pmaps.length; m++)
1009 AlcodMap alcmap = new AlcodMap();
1010 alcmap.setDnasq(seqHash(dnas[m]));
1011 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1013 alc.addAlcodMap(alcmap);
1018 vamsasSet.addAlcodonFrame(alc);
1021 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1023 // AlcodonFrame alc = new AlcodonFrame();
1024 // vamsasSet.addAlcodonFrame(alc);
1025 // for (int p = 0; p < acf.aaWidth; p++)
1027 // Alcodon cmap = new Alcodon();
1028 // if (acf.codons[p] != null)
1030 // // Null codons indicate a gapped column in the translated peptide
1032 // cmap.setPos1(acf.codons[p][0]);
1033 // cmap.setPos2(acf.codons[p][1]);
1034 // cmap.setPos3(acf.codons[p][2]);
1036 // alc.addAlcodon(cmap);
1038 // if (acf.getProtMappings() != null
1039 // && acf.getProtMappings().length > 0)
1041 // SequenceI[] dnas = acf.getdnaSeqs();
1042 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1043 // for (int m = 0; m < pmaps.length; m++)
1045 // AlcodMap alcmap = new AlcodMap();
1046 // alcmap.setDnasq(seqHash(dnas[m]));
1047 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1049 // alc.addAlcodMap(alcmap);
1056 // /////////////////////////////////
1057 if (!storeDS && av.currentTree != null)
1059 // FIND ANY ASSOCIATED TREES
1060 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1061 if (Desktop.desktop != null)
1063 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1065 for (int t = 0; t < frames.length; t++)
1067 if (frames[t] instanceof TreePanel)
1069 TreePanel tp = (TreePanel) frames[t];
1071 if (tp.treeCanvas.av.getAlignment() == jal)
1073 Tree tree = new Tree();
1074 tree.setTitle(tp.getTitle());
1075 tree.setCurrentTree((av.currentTree == tp.getTree()));
1076 tree.setNewick(tp.getTree().toString());
1077 tree.setThreshold(tp.treeCanvas.threshold);
1079 tree.setFitToWindow(tp.fitToWindow.getState());
1080 tree.setFontName(tp.getTreeFont().getName());
1081 tree.setFontSize(tp.getTreeFont().getSize());
1082 tree.setFontStyle(tp.getTreeFont().getStyle());
1083 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1085 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1086 tree.setShowDistances(tp.distanceMenu.getState());
1088 tree.setHeight(tp.getHeight());
1089 tree.setWidth(tp.getWidth());
1090 tree.setXpos(tp.getX());
1091 tree.setYpos(tp.getY());
1092 tree.setId(makeHashCode(tp, null));
1102 * store forward refs from an annotationRow to any groups
1104 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1107 for (SequenceI sq : jal.getSequences())
1109 // Store annotation on dataset sequences only
1110 AlignmentAnnotation[] aa = sq.getAnnotation();
1111 if (aa != null && aa.length > 0)
1113 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1120 if (jal.getAlignmentAnnotation() != null)
1122 // Store the annotation shown on the alignment.
1123 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1124 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1129 if (jal.getGroups() != null)
1131 JGroup[] groups = new JGroup[jal.getGroups().size()];
1133 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1135 JGroup jGroup = new JGroup();
1136 groups[++i] = jGroup;
1138 jGroup.setStart(sg.getStartRes());
1139 jGroup.setEnd(sg.getEndRes());
1140 jGroup.setName(sg.getName());
1141 if (groupRefs.containsKey(sg))
1143 // group has references so set its ID field
1144 jGroup.setId(groupRefs.get(sg));
1148 if (sg.cs.conservationApplied())
1150 jGroup.setConsThreshold(sg.cs.getConservationInc());
1152 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1154 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1158 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1161 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1163 jGroup.setColour("AnnotationColourGradient");
1164 jGroup.setAnnotationColours(constructAnnotationColours(
1165 (jalview.schemes.AnnotationColourGradient) sg.cs,
1168 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1170 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1174 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1177 jGroup.setPidThreshold(sg.cs.getThreshold());
1180 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1181 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1182 jGroup.setDisplayText(sg.getDisplayText());
1183 jGroup.setColourText(sg.getColourText());
1184 jGroup.setTextCol1(sg.textColour.getRGB());
1185 jGroup.setTextCol2(sg.textColour2.getRGB());
1186 jGroup.setTextColThreshold(sg.thresholdTextColour);
1187 jGroup.setShowUnconserved(sg.getShowNonconserved());
1188 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1189 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1190 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1191 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1192 for (SequenceI seq : sg.getSequences())
1194 jGroup.addSeq(seqHash(seq));
1198 jms.setJGroup(groups);
1202 // /////////SAVE VIEWPORT
1203 Viewport view = new Viewport();
1204 view.setTitle(ap.alignFrame.getTitle());
1205 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1206 av.getSequenceSetId()));
1207 view.setId(av.getViewId());
1208 if (av.getCodingComplement() != null)
1210 view.setComplementId(av.getCodingComplement().getViewId());
1212 view.setViewName(av.viewName);
1213 view.setGatheredViews(av.isGatherViewsHere());
1215 Rectangle size = ap.av.getExplodedGeometry();
1216 Rectangle position = size;
1219 size = ap.alignFrame.getBounds();
1220 if (av.getCodingComplement() != null)
1222 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1230 view.setXpos(position.x);
1231 view.setYpos(position.y);
1233 view.setWidth(size.width);
1234 view.setHeight(size.height);
1236 view.setStartRes(av.startRes);
1237 view.setStartSeq(av.startSeq);
1239 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1241 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1244 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1246 AnnotationColours ac = constructAnnotationColours(
1247 (jalview.schemes.AnnotationColourGradient) av
1248 .getGlobalColourScheme(),
1251 view.setAnnotationColours(ac);
1252 view.setBgColour("AnnotationColourGradient");
1256 view.setBgColour(ColourSchemeProperty.getColourName(av
1257 .getGlobalColourScheme()));
1260 ColourSchemeI cs = av.getGlobalColourScheme();
1264 if (cs.conservationApplied())
1266 view.setConsThreshold(cs.getConservationInc());
1267 if (cs instanceof jalview.schemes.UserColourScheme)
1269 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1273 if (cs instanceof ResidueColourScheme)
1275 view.setPidThreshold(cs.getThreshold());
1279 view.setConservationSelected(av.getConservationSelected());
1280 view.setPidSelected(av.getAbovePIDThreshold());
1281 view.setFontName(av.font.getName());
1282 view.setFontSize(av.font.getSize());
1283 view.setFontStyle(av.font.getStyle());
1284 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1285 view.setRenderGaps(av.isRenderGaps());
1286 view.setShowAnnotation(av.isShowAnnotation());
1287 view.setShowBoxes(av.getShowBoxes());
1288 view.setShowColourText(av.getColourText());
1289 view.setShowFullId(av.getShowJVSuffix());
1290 view.setRightAlignIds(av.isRightAlignIds());
1291 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1292 view.setShowText(av.getShowText());
1293 view.setShowUnconserved(av.getShowUnconserved());
1294 view.setWrapAlignment(av.getWrapAlignment());
1295 view.setTextCol1(av.getTextColour().getRGB());
1296 view.setTextCol2(av.getTextColour2().getRGB());
1297 view.setTextColThreshold(av.getThresholdTextColour());
1298 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1299 view.setShowSequenceLogo(av.isShowSequenceLogo());
1300 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1301 view.setShowGroupConsensus(av.isShowGroupConsensus());
1302 view.setShowGroupConservation(av.isShowGroupConservation());
1303 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1304 view.setShowDbRefTooltip(av.isShowDBRefs());
1305 view.setFollowHighlight(av.isFollowHighlight());
1306 view.setFollowSelection(av.followSelection);
1307 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1308 if (av.getFeaturesDisplayed() != null)
1310 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1312 String[] renderOrder = ap.getSeqPanel().seqCanvas
1313 .getFeatureRenderer().getRenderOrder()
1314 .toArray(new String[0]);
1316 Vector<String> settingsAdded = new Vector<String>();
1317 if (renderOrder != null)
1319 for (String featureType : renderOrder)
1321 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1322 .getFeatureRenderer()
1323 .getFeatureStyle(featureType);
1324 Setting setting = new Setting();
1325 setting.setType(featureType);
1326 if (!fcol.isSimpleColour())
1328 setting.setColour(fcol.getMaxColour().getRGB());
1329 setting.setMincolour(fcol.getMinColour().getRGB());
1330 setting.setMin(fcol.getMin());
1331 setting.setMax(fcol.getMax());
1332 setting.setColourByLabel(fcol.isColourByLabel());
1333 setting.setAutoScale(fcol.isAutoScaled());
1334 setting.setThreshold(fcol.getThreshold());
1335 // -1 = No threshold, 0 = Below, 1 = Above
1336 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1337 : (fcol.isBelowThreshold() ? 0 : -1));
1341 setting.setColour(fcol.getColour().getRGB());
1344 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1346 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1347 .getOrder(featureType);
1350 setting.setOrder(rorder);
1352 fs.addSetting(setting);
1353 settingsAdded.addElement(featureType);
1357 // is groups actually supposed to be a map here ?
1358 Iterator<String> en = ap.getSeqPanel().seqCanvas
1359 .getFeatureRenderer()
1360 .getFeatureGroups().iterator();
1361 Vector<String> groupsAdded = new Vector<String>();
1362 while (en.hasNext())
1364 String grp = en.next();
1365 if (groupsAdded.contains(grp))
1369 Group g = new Group();
1371 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1372 .getFeatureRenderer().checkGroupVisibility(grp, false))
1375 groupsAdded.addElement(grp);
1377 jms.setFeatureSettings(fs);
1380 if (av.hasHiddenColumns())
1382 if (av.getColumnSelection() == null
1383 || av.getColumnSelection().getHiddenColumns() == null)
1385 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1389 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1392 int[] region = av.getColumnSelection().getHiddenColumns()
1394 HiddenColumns hc = new HiddenColumns();
1395 hc.setStart(region[0]);
1396 hc.setEnd(region[1]);
1397 view.addHiddenColumns(hc);
1401 if (calcIdSet.size() > 0)
1403 for (String calcId : calcIdSet)
1405 if (calcId.trim().length() > 0)
1407 CalcIdParam cidp = createCalcIdParam(calcId, av);
1408 // Some calcIds have no parameters.
1411 view.addCalcIdParam(cidp);
1417 jms.addViewport(view);
1419 object.setJalviewModelSequence(jms);
1420 object.getVamsasModel().addSequenceSet(vamsasSet);
1422 if (jout != null && fileName != null)
1424 // We may not want to write the object to disk,
1425 // eg we can copy the alignViewport to a new view object
1426 // using save and then load
1429 System.out.println("Writing jar entry " + fileName);
1430 JarEntry entry = new JarEntry(fileName);
1431 jout.putNextEntry(entry);
1432 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1434 Marshaller marshaller = new Marshaller(pout);
1435 marshaller.marshal(object);
1438 } catch (Exception ex)
1440 // TODO: raise error in GUI if marshalling failed.
1441 ex.printStackTrace();
1448 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1449 * for each viewer, with
1451 * <li>viewer geometry (position, size, split pane divider location)</li>
1452 * <li>index of the selected structure in the viewer (currently shows gapped
1454 * <li>the id of the annotation holding RNA secondary structure</li>
1455 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1457 * Varna viewer state is also written out (in native Varna XML) to separate
1458 * project jar entries. A separate entry is written for each RNA structure
1459 * displayed, with the naming convention
1461 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1469 * @param storeDataset
1471 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1472 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1473 boolean storeDataset)
1475 if (Desktop.desktop == null)
1479 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1480 for (int f = frames.length - 1; f > -1; f--)
1482 if (frames[f] instanceof AppVarna)
1484 AppVarna varna = (AppVarna) frames[f];
1486 * link the sequence to every viewer that is showing it and is linked to
1487 * its alignment panel
1489 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1491 String viewId = varna.getViewId();
1492 RnaViewer rna = new RnaViewer();
1493 rna.setViewId(viewId);
1494 rna.setTitle(varna.getTitle());
1495 rna.setXpos(varna.getX());
1496 rna.setYpos(varna.getY());
1497 rna.setWidth(varna.getWidth());
1498 rna.setHeight(varna.getHeight());
1499 rna.setDividerLocation(varna.getDividerLocation());
1500 rna.setSelectedRna(varna.getSelectedIndex());
1501 jseq.addRnaViewer(rna);
1504 * Store each Varna panel's state once in the project per sequence.
1505 * First time through only (storeDataset==false)
1507 // boolean storeSessions = false;
1508 // String sequenceViewId = viewId + seqsToIds.get(jds);
1509 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1511 // viewIds.add(sequenceViewId);
1512 // storeSessions = true;
1514 for (RnaModel model : varna.getModels())
1516 if (model.seq == jds)
1519 * VARNA saves each view (sequence or alignment secondary
1520 * structure, gapped or trimmed) as a separate XML file
1522 String jarEntryName = rnaSessions.get(model);
1523 if (jarEntryName == null)
1526 String varnaStateFile = varna.getStateInfo(model.rna);
1527 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1528 copyFileToJar(jout, varnaStateFile, jarEntryName);
1529 rnaSessions.put(model, jarEntryName);
1531 SecondaryStructure ss = new SecondaryStructure();
1532 String annotationId = varna.getAnnotation(jds).annotationId;
1533 ss.setAnnotationId(annotationId);
1534 ss.setViewerState(jarEntryName);
1535 ss.setGapped(model.gapped);
1536 ss.setTitle(model.title);
1537 rna.addSecondaryStructure(ss);
1546 * Copy the contents of a file to a new entry added to the output jar
1550 * @param jarEntryName
1552 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1553 String jarEntryName)
1555 DataInputStream dis = null;
1558 File file = new File(infilePath);
1559 if (file.exists() && jout != null)
1561 dis = new DataInputStream(new FileInputStream(file));
1562 byte[] data = new byte[(int) file.length()];
1563 dis.readFully(data);
1564 writeJarEntry(jout, jarEntryName, data);
1566 } catch (Exception ex)
1568 ex.printStackTrace();
1576 } catch (IOException e)
1585 * Write the data to a new entry of given name in the output jar file
1588 * @param jarEntryName
1590 * @throws IOException
1592 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1593 byte[] data) throws IOException
1597 System.out.println("Writing jar entry " + jarEntryName);
1598 jout.putNextEntry(new JarEntry(jarEntryName));
1599 DataOutputStream dout = new DataOutputStream(jout);
1600 dout.write(data, 0, data.length);
1607 * Save the state of a structure viewer
1612 * the archive XML element under which to save the state
1615 * @param matchedFile
1619 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1620 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1621 String matchedFile, StructureViewerBase viewFrame)
1623 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1626 * Look for any bindings for this viewer to the PDB file of interest
1627 * (including part matches excluding chain id)
1629 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1631 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1632 final String pdbId = pdbentry.getId();
1633 if (!pdbId.equals(entry.getId())
1634 && !(entry.getId().length() > 4 && entry.getId()
1635 .toLowerCase().startsWith(pdbId.toLowerCase())))
1638 * not interested in a binding to a different PDB entry here
1642 if (matchedFile == null)
1644 matchedFile = pdbentry.getFile();
1646 else if (!matchedFile.equals(pdbentry.getFile()))
1649 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1650 + pdbentry.getFile());
1654 // can get at it if the ID
1655 // match is ambiguous (e.g.
1658 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1660 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1661 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1663 StructureState state = new StructureState();
1664 state.setVisible(true);
1665 state.setXpos(viewFrame.getX());
1666 state.setYpos(viewFrame.getY());
1667 state.setWidth(viewFrame.getWidth());
1668 state.setHeight(viewFrame.getHeight());
1669 final String viewId = viewFrame.getViewId();
1670 state.setViewId(viewId);
1671 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1672 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1673 state.setColourByJmol(viewFrame.isColouredByViewer());
1674 state.setType(viewFrame.getViewerType().toString());
1675 pdb.addStructureState(state);
1682 private AnnotationColours constructAnnotationColours(
1683 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1684 JalviewModelSequence jms)
1686 AnnotationColours ac = new AnnotationColours();
1687 ac.setAboveThreshold(acg.getAboveThreshold());
1688 ac.setThreshold(acg.getAnnotationThreshold());
1689 ac.setAnnotation(acg.getAnnotation());
1690 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1692 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1697 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1701 ac.setMaxColour(acg.getMaxColour().getRGB());
1702 ac.setMinColour(acg.getMinColour().getRGB());
1703 ac.setPerSequence(acg.isSeqAssociated());
1704 ac.setPredefinedColours(acg.isPredefinedColours());
1708 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1709 IdentityHashMap<SequenceGroup, String> groupRefs,
1710 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1711 SequenceSet vamsasSet)
1714 for (int i = 0; i < aa.length; i++)
1716 Annotation an = new Annotation();
1718 AlignmentAnnotation annotation = aa[i];
1719 if (annotation.annotationId != null)
1721 annotationIds.put(annotation.annotationId, annotation);
1724 an.setId(annotation.annotationId);
1726 an.setVisible(annotation.visible);
1728 an.setDescription(annotation.description);
1730 if (annotation.sequenceRef != null)
1732 // 2.9 JAL-1781 xref on sequence id rather than name
1733 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1735 if (annotation.groupRef != null)
1737 String groupIdr = groupRefs.get(annotation.groupRef);
1738 if (groupIdr == null)
1740 // make a locally unique String
1742 annotation.groupRef,
1743 groupIdr = ("" + System.currentTimeMillis()
1744 + annotation.groupRef.getName() + groupRefs
1747 an.setGroupRef(groupIdr.toString());
1750 // store all visualization attributes for annotation
1751 an.setGraphHeight(annotation.graphHeight);
1752 an.setCentreColLabels(annotation.centreColLabels);
1753 an.setScaleColLabels(annotation.scaleColLabel);
1754 an.setShowAllColLabels(annotation.showAllColLabels);
1755 an.setBelowAlignment(annotation.belowAlignment);
1757 if (annotation.graph > 0)
1760 an.setGraphType(annotation.graph);
1761 an.setGraphGroup(annotation.graphGroup);
1762 if (annotation.getThreshold() != null)
1764 ThresholdLine line = new ThresholdLine();
1765 line.setLabel(annotation.getThreshold().label);
1766 line.setValue(annotation.getThreshold().value);
1767 line.setColour(annotation.getThreshold().colour.getRGB());
1768 an.setThresholdLine(line);
1776 an.setLabel(annotation.label);
1778 if (annotation == av.getAlignmentQualityAnnot()
1779 || annotation == av.getAlignmentConservationAnnotation()
1780 || annotation == av.getAlignmentConsensusAnnotation()
1781 || annotation.autoCalculated)
1783 // new way of indicating autocalculated annotation -
1784 an.setAutoCalculated(annotation.autoCalculated);
1786 if (annotation.hasScore())
1788 an.setScore(annotation.getScore());
1791 if (annotation.getCalcId() != null)
1793 calcIdSet.add(annotation.getCalcId());
1794 an.setCalcId(annotation.getCalcId());
1796 if (annotation.hasProperties())
1798 for (String pr : annotation.getProperties())
1800 Property prop = new Property();
1802 prop.setValue(annotation.getProperty(pr));
1803 an.addProperty(prop);
1807 AnnotationElement ae;
1808 if (annotation.annotations != null)
1810 an.setScoreOnly(false);
1811 for (int a = 0; a < annotation.annotations.length; a++)
1813 if ((annotation == null) || (annotation.annotations[a] == null))
1818 ae = new AnnotationElement();
1819 if (annotation.annotations[a].description != null)
1821 ae.setDescription(annotation.annotations[a].description);
1823 if (annotation.annotations[a].displayCharacter != null)
1825 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1828 if (!Float.isNaN(annotation.annotations[a].value))
1830 ae.setValue(annotation.annotations[a].value);
1834 if (annotation.annotations[a].secondaryStructure > ' ')
1836 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1840 if (annotation.annotations[a].colour != null
1841 && annotation.annotations[a].colour != java.awt.Color.black)
1843 ae.setColour(annotation.annotations[a].colour.getRGB());
1846 an.addAnnotationElement(ae);
1847 if (annotation.autoCalculated)
1849 // only write one non-null entry into the annotation row -
1850 // sufficient to get the visualization attributes necessary to
1858 an.setScoreOnly(true);
1860 if (!storeDS || (storeDS && !annotation.autoCalculated))
1862 // skip autocalculated annotation - these are only provided for
1864 vamsasSet.addAnnotation(an);
1870 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1872 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1873 if (settings != null)
1875 CalcIdParam vCalcIdParam = new CalcIdParam();
1876 vCalcIdParam.setCalcId(calcId);
1877 vCalcIdParam.addServiceURL(settings.getServiceURI());
1878 // generic URI allowing a third party to resolve another instance of the
1879 // service used for this calculation
1880 for (String urls : settings.getServiceURLs())
1882 vCalcIdParam.addServiceURL(urls);
1884 vCalcIdParam.setVersion("1.0");
1885 if (settings.getPreset() != null)
1887 WsParamSetI setting = settings.getPreset();
1888 vCalcIdParam.setName(setting.getName());
1889 vCalcIdParam.setDescription(setting.getDescription());
1893 vCalcIdParam.setName("");
1894 vCalcIdParam.setDescription("Last used parameters");
1896 // need to be able to recover 1) settings 2) user-defined presets or
1897 // recreate settings from preset 3) predefined settings provided by
1898 // service - or settings that can be transferred (or discarded)
1899 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1901 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1902 // todo - decide if updateImmediately is needed for any projects.
1904 return vCalcIdParam;
1909 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1912 if (calcIdParam.getVersion().equals("1.0"))
1914 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1915 .getPreferredServiceFor(calcIdParam.getServiceURL());
1916 if (service != null)
1918 WsParamSetI parmSet = null;
1921 parmSet = service.getParamStore().parseServiceParameterFile(
1922 calcIdParam.getName(), calcIdParam.getDescription(),
1923 calcIdParam.getServiceURL(),
1924 calcIdParam.getParameters().replace("|\\n|", "\n"));
1925 } catch (IOException x)
1927 warn("Couldn't parse parameter data for "
1928 + calcIdParam.getCalcId(), x);
1931 List<ArgumentI> argList = null;
1932 if (calcIdParam.getName().length() > 0)
1934 parmSet = service.getParamStore()
1935 .getPreset(calcIdParam.getName());
1936 if (parmSet != null)
1938 // TODO : check we have a good match with settings in AACon -
1939 // otherwise we'll need to create a new preset
1944 argList = parmSet.getArguments();
1947 AAConSettings settings = new AAConSettings(
1948 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1949 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1950 calcIdParam.isNeedsUpdate());
1955 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1959 throw new Error(MessageManager.formatMessage(
1960 "error.unsupported_version_calcIdparam",
1961 new Object[] { calcIdParam.toString() }));
1965 * External mapping between jalview objects and objects yielding a valid and
1966 * unique object ID string. This is null for normal Jalview project IO, but
1967 * non-null when a jalview project is being read or written as part of a
1970 IdentityHashMap jv2vobj = null;
1973 * Construct a unique ID for jvobj using either existing bindings or if none
1974 * exist, the result of the hashcode call for the object.
1977 * jalview data object
1978 * @return unique ID for referring to jvobj
1980 private String makeHashCode(Object jvobj, String altCode)
1982 if (jv2vobj != null)
1984 Object id = jv2vobj.get(jvobj);
1987 return id.toString();
1989 // check string ID mappings
1990 if (jvids2vobj != null && jvobj instanceof String)
1992 id = jvids2vobj.get(jvobj);
1996 return id.toString();
1998 // give up and warn that something has gone wrong
1999 warn("Cannot find ID for object in external mapping : " + jvobj);
2005 * return local jalview object mapped to ID, if it exists
2009 * @return null or object bound to idcode
2011 private Object retrieveExistingObj(String idcode)
2013 if (idcode != null && vobj2jv != null)
2015 return vobj2jv.get(idcode);
2021 * binding from ID strings from external mapping table to jalview data model
2024 private Hashtable vobj2jv;
2026 private Sequence createVamsasSequence(String id, SequenceI jds)
2028 return createVamsasSequence(true, id, jds, null);
2031 private Sequence createVamsasSequence(boolean recurse, String id,
2032 SequenceI jds, SequenceI parentseq)
2034 Sequence vamsasSeq = new Sequence();
2035 vamsasSeq.setId(id);
2036 vamsasSeq.setName(jds.getName());
2037 vamsasSeq.setSequence(jds.getSequenceAsString());
2038 vamsasSeq.setDescription(jds.getDescription());
2039 jalview.datamodel.DBRefEntry[] dbrefs = null;
2040 if (jds.getDatasetSequence() != null)
2042 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2043 if (jds.getDatasetSequence().getDBRefs() != null)
2045 dbrefs = jds.getDatasetSequence().getDBRefs();
2050 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
2051 // dataset sequences only
2052 dbrefs = jds.getDBRefs();
2056 for (int d = 0; d < dbrefs.length; d++)
2058 DBRef dbref = new DBRef();
2059 dbref.setSource(dbrefs[d].getSource());
2060 dbref.setVersion(dbrefs[d].getVersion());
2061 dbref.setAccessionId(dbrefs[d].getAccessionId());
2062 if (dbrefs[d].hasMap())
2064 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2066 dbref.setMapping(mp);
2068 vamsasSeq.addDBRef(dbref);
2074 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2075 SequenceI parentseq, SequenceI jds, boolean recurse)
2078 if (jmp.getMap() != null)
2082 jalview.util.MapList mlst = jmp.getMap();
2083 List<int[]> r = mlst.getFromRanges();
2084 for (int[] range : r)
2086 MapListFrom mfrom = new MapListFrom();
2087 mfrom.setStart(range[0]);
2088 mfrom.setEnd(range[1]);
2089 mp.addMapListFrom(mfrom);
2091 r = mlst.getToRanges();
2092 for (int[] range : r)
2094 MapListTo mto = new MapListTo();
2095 mto.setStart(range[0]);
2096 mto.setEnd(range[1]);
2097 mp.addMapListTo(mto);
2099 mp.setMapFromUnit(mlst.getFromRatio());
2100 mp.setMapToUnit(mlst.getToRatio());
2101 if (jmp.getTo() != null)
2103 MappingChoice mpc = new MappingChoice();
2105 && (parentseq != jmp.getTo() || parentseq
2106 .getDatasetSequence() != jmp.getTo()))
2108 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2114 SequenceI ps = null;
2115 if (parentseq != jmp.getTo()
2116 && parentseq.getDatasetSequence() != jmp.getTo())
2118 // chaining dbref rather than a handshaking one
2119 jmpid = seqHash(ps = jmp.getTo());
2123 jmpid = seqHash(ps = parentseq);
2125 mpc.setDseqFor(jmpid);
2126 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2128 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2129 seqRefIds.put(mpc.getDseqFor(), ps);
2133 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2136 mp.setMappingChoice(mpc);
2142 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2143 List<UserColourScheme> userColours, JalviewModelSequence jms)
2146 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2147 boolean newucs = false;
2148 if (!userColours.contains(ucs))
2150 userColours.add(ucs);
2153 id = "ucs" + userColours.indexOf(ucs);
2156 // actually create the scheme's entry in the XML model
2157 java.awt.Color[] colours = ucs.getColours();
2158 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2159 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2161 for (int i = 0; i < colours.length; i++)
2163 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2164 col.setName(ResidueProperties.aa[i]);
2165 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2166 jbucs.addColour(col);
2168 if (ucs.getLowerCaseColours() != null)
2170 colours = ucs.getLowerCaseColours();
2171 for (int i = 0; i < colours.length; i++)
2173 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2174 col.setName(ResidueProperties.aa[i].toLowerCase());
2175 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2176 jbucs.addColour(col);
2181 uc.setUserColourScheme(jbucs);
2182 jms.addUserColours(uc);
2188 jalview.schemes.UserColourScheme getUserColourScheme(
2189 JalviewModelSequence jms, String id)
2191 UserColours[] uc = jms.getUserColours();
2192 UserColours colours = null;
2194 for (int i = 0; i < uc.length; i++)
2196 if (uc[i].getId().equals(id))
2204 java.awt.Color[] newColours = new java.awt.Color[24];
2206 for (int i = 0; i < 24; i++)
2208 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2209 .getUserColourScheme().getColour(i).getRGB(), 16));
2212 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2215 if (colours.getUserColourScheme().getColourCount() > 24)
2217 newColours = new java.awt.Color[23];
2218 for (int i = 0; i < 23; i++)
2220 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2221 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2223 ucs.setLowerCaseColours(newColours);
2230 * contains last error message (if any) encountered by XML loader.
2232 String errorMessage = null;
2235 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2236 * exceptions are raised during project XML parsing
2238 public boolean attemptversion1parse = true;
2241 * Load a jalview project archive from a jar file
2244 * - HTTP URL or filename
2246 public AlignFrame loadJalviewAlign(final String file)
2249 jalview.gui.AlignFrame af = null;
2253 // create list to store references for any new Jmol viewers created
2254 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2255 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2256 // Workaround is to make sure caller implements the JarInputStreamProvider
2258 // so we can re-open the jar input stream for each entry.
2260 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2261 af = loadJalviewAlign(jprovider);
2263 } catch (MalformedURLException e)
2265 errorMessage = "Invalid URL format for '" + file + "'";
2271 SwingUtilities.invokeAndWait(new Runnable()
2276 setLoadingFinishedForNewStructureViewers();
2279 } catch (Exception x)
2281 System.err.println("Error loading alignment: " + x.getMessage());
2287 private jarInputStreamProvider createjarInputStreamProvider(
2288 final String file) throws MalformedURLException
2291 errorMessage = null;
2292 uniqueSetSuffix = null;
2294 viewportsAdded.clear();
2295 frefedSequence = null;
2297 if (file.startsWith("http://"))
2299 url = new URL(file);
2301 final URL _url = url;
2302 return new jarInputStreamProvider()
2306 public JarInputStream getJarInputStream() throws IOException
2310 return new JarInputStream(_url.openStream());
2314 return new JarInputStream(new FileInputStream(file));
2319 public String getFilename()
2327 * Recover jalview session from a jalview project archive. Caller may
2328 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2329 * themselves. Any null fields will be initialised with default values,
2330 * non-null fields are left alone.
2335 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2337 errorMessage = null;
2338 if (uniqueSetSuffix == null)
2340 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2342 if (seqRefIds == null)
2346 AlignFrame af = null, _af = null;
2347 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2348 final String file = jprovider.getFilename();
2351 JarInputStream jin = null;
2352 JarEntry jarentry = null;
2357 jin = jprovider.getJarInputStream();
2358 for (int i = 0; i < entryCount; i++)
2360 jarentry = jin.getNextJarEntry();
2363 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2365 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2366 JalviewModel object = new JalviewModel();
2368 Unmarshaller unmar = new Unmarshaller(object);
2369 unmar.setValidation(false);
2370 object = (JalviewModel) unmar.unmarshal(in);
2371 if (true) // !skipViewport(object))
2373 _af = loadFromObject(object, file, true, jprovider);
2374 if (object.getJalviewModelSequence().getViewportCount() > 0)
2377 if (af.viewport.isGatherViewsHere())
2379 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2385 else if (jarentry != null)
2387 // Some other file here.
2390 } while (jarentry != null);
2391 resolveFrefedSequences();
2392 } catch (IOException ex)
2394 ex.printStackTrace();
2395 errorMessage = "Couldn't locate Jalview XML file : " + file;
2396 System.err.println("Exception whilst loading jalview XML file : "
2398 } catch (Exception ex)
2400 System.err.println("Parsing as Jalview Version 2 file failed.");
2401 ex.printStackTrace(System.err);
2402 if (attemptversion1parse)
2404 // Is Version 1 Jar file?
2407 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2408 } catch (Exception ex2)
2410 System.err.println("Exception whilst loading as jalviewXMLV1:");
2411 ex2.printStackTrace();
2415 if (Desktop.instance != null)
2417 Desktop.instance.stopLoading();
2421 System.out.println("Successfully loaded archive file");
2424 ex.printStackTrace();
2426 System.err.println("Exception whilst loading jalview XML file : "
2428 } catch (OutOfMemoryError e)
2430 // Don't use the OOM Window here
2431 errorMessage = "Out of memory loading jalview XML file";
2432 System.err.println("Out of memory whilst loading jalview XML file");
2433 e.printStackTrace();
2436 if (Desktop.instance != null)
2438 Desktop.instance.stopLoading();
2442 * Regather multiple views (with the same sequence set id) to the frame (if
2443 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2444 * views instead of separate frames. Note this doesn't restore a state where
2445 * some expanded views in turn have tabbed views - the last "first tab" read
2446 * in will play the role of gatherer for all.
2448 for (AlignFrame fr : gatherToThisFrame.values())
2450 Desktop.instance.gatherViews(fr);
2453 restoreSplitFrames();
2455 if (errorMessage != null)
2463 * Try to reconstruct and display SplitFrame windows, where each contains
2464 * complementary dna and protein alignments. Done by pairing up AlignFrame
2465 * objects (created earlier) which have complementary viewport ids associated.
2467 protected void restoreSplitFrames()
2469 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2470 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2471 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2474 * Identify the DNA alignments
2476 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2479 AlignFrame af = candidate.getValue();
2480 if (af.getViewport().getAlignment().isNucleotide())
2482 dna.put(candidate.getKey().getId(), af);
2487 * Try to match up the protein complements
2489 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2492 AlignFrame af = candidate.getValue();
2493 if (!af.getViewport().getAlignment().isNucleotide())
2495 String complementId = candidate.getKey().getComplementId();
2496 // only non-null complements should be in the Map
2497 if (complementId != null && dna.containsKey(complementId))
2499 final AlignFrame dnaFrame = dna.get(complementId);
2500 SplitFrame sf = createSplitFrame(dnaFrame, af);
2501 addedToSplitFrames.add(dnaFrame);
2502 addedToSplitFrames.add(af);
2503 if (af.viewport.isGatherViewsHere())
2512 * Open any that we failed to pair up (which shouldn't happen!) as
2513 * standalone AlignFrame's.
2515 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2518 AlignFrame af = candidate.getValue();
2519 if (!addedToSplitFrames.contains(af))
2521 Viewport view = candidate.getKey();
2522 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2524 System.err.println("Failed to restore view " + view.getTitle()
2525 + " to split frame");
2530 * Gather back into tabbed views as flagged.
2532 for (SplitFrame sf : gatherTo)
2534 Desktop.instance.gatherViews(sf);
2537 splitFrameCandidates.clear();
2541 * Construct and display one SplitFrame holding DNA and protein alignments.
2544 * @param proteinFrame
2547 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2548 AlignFrame proteinFrame)
2550 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2551 String title = MessageManager.getString("label.linked_view_title");
2552 int width = (int) dnaFrame.getBounds().getWidth();
2553 int height = (int) (dnaFrame.getBounds().getHeight()
2554 + proteinFrame.getBounds().getHeight() + 50);
2557 * SplitFrame location is saved to both enclosed frames
2559 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2560 Desktop.addInternalFrame(splitFrame, title, width, height);
2563 * And compute cDNA consensus (couldn't do earlier with consensus as
2564 * mappings were not yet present)
2566 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2572 * check errorMessage for a valid error message and raise an error box in the
2573 * GUI or write the current errorMessage to stderr and then clear the error
2576 protected void reportErrors()
2578 reportErrors(false);
2581 protected void reportErrors(final boolean saving)
2583 if (errorMessage != null)
2585 final String finalErrorMessage = errorMessage;
2588 javax.swing.SwingUtilities.invokeLater(new Runnable()
2593 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2594 finalErrorMessage, "Error "
2595 + (saving ? "saving" : "loading")
2596 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2602 System.err.println("Problem loading Jalview file: " + errorMessage);
2605 errorMessage = null;
2608 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2611 * when set, local views will be updated from view stored in JalviewXML
2612 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2613 * sync if this is set to true.
2615 private final boolean updateLocalViews = false;
2618 * Returns the path to a temporary file holding the PDB file for the given PDB
2619 * id. The first time of asking, searches for a file of that name in the
2620 * Jalview project jar, and copies it to a new temporary file. Any repeat
2621 * requests just return the path to the file previously created.
2627 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2629 if (alreadyLoadedPDB.containsKey(pdbId))
2631 return alreadyLoadedPDB.get(pdbId).toString();
2634 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2635 if (tempFile != null)
2637 alreadyLoadedPDB.put(pdbId, tempFile);
2643 * Copies the jar entry of given name to a new temporary file and returns the
2644 * path to the file, or null if the entry is not found.
2647 * @param jarEntryName
2649 * a prefix for the temporary file name, must be at least three
2653 protected String copyJarEntry(jarInputStreamProvider jprovider,
2654 String jarEntryName, String prefix)
2656 BufferedReader in = null;
2657 PrintWriter out = null;
2661 JarInputStream jin = jprovider.getJarInputStream();
2663 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2664 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2665 * FileInputStream(jprovider)); }
2668 JarEntry entry = null;
2671 entry = jin.getNextJarEntry();
2672 } while (entry != null && !entry.getName().equals(jarEntryName));
2675 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2676 File outFile = File.createTempFile(prefix, ".tmp");
2677 outFile.deleteOnExit();
2678 out = new PrintWriter(new FileOutputStream(outFile));
2681 while ((data = in.readLine()) != null)
2686 String t = outFile.getAbsolutePath();
2691 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2693 } catch (Exception ex)
2695 ex.printStackTrace();
2703 } catch (IOException e)
2717 private class JvAnnotRow
2719 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2726 * persisted version of annotation row from which to take vis properties
2728 public jalview.datamodel.AlignmentAnnotation template;
2731 * original position of the annotation row in the alignment
2737 * Load alignment frame from jalview XML DOM object
2742 * filename source string
2743 * @param loadTreesAndStructures
2744 * when false only create Viewport
2746 * data source provider
2747 * @return alignment frame created from view stored in DOM
2749 AlignFrame loadFromObject(JalviewModel object, String file,
2750 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2752 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2753 Sequence[] vamsasSeq = vamsasSet.getSequence();
2755 JalviewModelSequence jms = object.getJalviewModelSequence();
2757 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2760 // ////////////////////////////////
2763 List<SequenceI> hiddenSeqs = null;
2766 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2768 boolean multipleView = false;
2769 SequenceI referenceseqForView = null;
2770 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2771 int vi = 0; // counter in vamsasSeq array
2772 for (int i = 0; i < jseqs.length; i++)
2774 String seqId = jseqs[i].getId();
2776 SequenceI tmpSeq = seqRefIds.get(seqId);
2779 if (!incompleteSeqs.containsKey(seqId))
2781 // may not need this check, but keep it for at least 2.9,1 release
2782 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2785 .println("Warning JAL-2154 regression: updating start/end for sequence "
2786 + tmpSeq.toString());
2789 incompleteSeqs.remove(seqId);
2791 tmpSeq.setStart(jseqs[i].getStart());
2792 tmpSeq.setEnd(jseqs[i].getEnd());
2793 tmpseqs.add(tmpSeq);
2794 multipleView = true;
2798 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2799 vamsasSeq[vi].getSequence());
2800 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2801 tmpSeq.setStart(jseqs[i].getStart());
2802 tmpSeq.setEnd(jseqs[i].getEnd());
2803 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2804 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2805 tmpseqs.add(tmpSeq);
2809 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2811 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2814 if (jseqs[i].getHidden())
2816 if (hiddenSeqs == null)
2818 hiddenSeqs = new ArrayList<SequenceI>();
2821 hiddenSeqs.add(tmpSeq);
2826 // Create the alignment object from the sequence set
2827 // ///////////////////////////////
2828 SequenceI[] orderedSeqs = tmpseqs
2829 .toArray(new SequenceI[tmpseqs.size()]);
2831 AlignmentI al = new Alignment(orderedSeqs);
2833 if (referenceseqForView != null)
2835 al.setSeqrep(referenceseqForView);
2837 // / Add the alignment properties
2838 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2840 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2841 al.setProperty(ssp.getKey(), ssp.getValue());
2845 // SequenceFeatures are added to the DatasetSequence,
2846 // so we must create or recover the dataset before loading features
2847 // ///////////////////////////////
2848 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2850 // older jalview projects do not have a dataset id.
2851 al.setDataset(null);
2855 // recover dataset - passing on flag indicating if this a 'viewless'
2856 // sequence set (a.k.a. a stored dataset for the project)
2857 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2858 .getViewportCount() == 0);
2860 // ///////////////////////////////
2862 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2865 // load sequence features, database references and any associated PDB
2866 // structures for the alignment
2867 for (int i = 0; i < vamsasSeq.length; i++)
2869 if (jseqs[i].getFeaturesCount() > 0)
2871 Features[] features = jseqs[i].getFeatures();
2872 for (int f = 0; f < features.length; f++)
2874 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2875 features[f].getType(), features[f].getDescription(),
2876 features[f].getStatus(), features[f].getBegin(),
2877 features[f].getEnd(), features[f].getFeatureGroup());
2879 sf.setScore(features[f].getScore());
2880 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2882 OtherData keyValue = features[f].getOtherData(od);
2883 if (keyValue.getKey().startsWith("LINK"))
2885 sf.addLink(keyValue.getValue());
2889 sf.setValue(keyValue.getKey(), keyValue.getValue());
2894 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2897 if (vamsasSeq[i].getDBRefCount() > 0)
2899 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2901 if (jseqs[i].getPdbidsCount() > 0)
2903 Pdbids[] ids = jseqs[i].getPdbids();
2904 for (int p = 0; p < ids.length; p++)
2906 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2907 entry.setId(ids[p].getId());
2908 if (ids[p].getType() != null)
2910 if (ids[p].getType().equalsIgnoreCase("PDB"))
2912 entry.setType(PDBEntry.Type.PDB);
2916 entry.setType(PDBEntry.Type.FILE);
2919 if (ids[p].getFile() != null)
2921 if (!pdbloaded.containsKey(ids[p].getFile()))
2923 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2927 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2930 StructureSelectionManager.getStructureSelectionManager(
2931 Desktop.instance).registerPDBEntry(entry);
2932 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2936 } // end !multipleview
2938 // ///////////////////////////////
2939 // LOAD SEQUENCE MAPPINGS
2941 if (vamsasSet.getAlcodonFrameCount() > 0)
2943 // TODO Potentially this should only be done once for all views of an
2945 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2946 for (int i = 0; i < alc.length; i++)
2948 AlignedCodonFrame cf = new AlignedCodonFrame();
2949 if (alc[i].getAlcodMapCount() > 0)
2951 AlcodMap[] maps = alc[i].getAlcodMap();
2952 for (int m = 0; m < maps.length; m++)
2954 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2956 jalview.datamodel.Mapping mapping = null;
2957 // attach to dna sequence reference.
2958 if (maps[m].getMapping() != null)
2960 mapping = addMapping(maps[m].getMapping());
2962 if (dnaseq != null && mapping.getTo() != null)
2964 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2969 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
2973 al.addCodonFrame(cf);
2978 // ////////////////////////////////
2980 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2983 * store any annotations which forward reference a group's ID
2985 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2987 if (vamsasSet.getAnnotationCount() > 0)
2989 Annotation[] an = vamsasSet.getAnnotation();
2991 for (int i = 0; i < an.length; i++)
2993 Annotation annotation = an[i];
2996 * test if annotation is automatically calculated for this view only
2998 boolean autoForView = false;
2999 if (annotation.getLabel().equals("Quality")
3000 || annotation.getLabel().equals("Conservation")
3001 || annotation.getLabel().equals("Consensus"))
3003 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3005 if (!annotation.hasAutoCalculated())
3007 annotation.setAutoCalculated(true);
3011 || (annotation.hasAutoCalculated() && annotation
3012 .isAutoCalculated()))
3014 // remove ID - we don't recover annotation from other views for
3015 // view-specific annotation
3016 annotation.setId(null);
3019 // set visiblity for other annotation in this view
3020 String annotationId = annotation.getId();
3021 if (annotationId != null && annotationIds.containsKey(annotationId))
3023 AlignmentAnnotation jda = annotationIds.get(annotationId);
3024 // in principle Visible should always be true for annotation displayed
3025 // in multiple views
3026 if (annotation.hasVisible())
3028 jda.visible = annotation.getVisible();
3031 al.addAnnotation(jda);
3035 // Construct new annotation from model.
3036 AnnotationElement[] ae = annotation.getAnnotationElement();
3037 jalview.datamodel.Annotation[] anot = null;
3038 java.awt.Color firstColour = null;
3040 if (!annotation.getScoreOnly())
3042 anot = new jalview.datamodel.Annotation[al.getWidth()];
3043 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3045 anpos = ae[aa].getPosition();
3047 if (anpos >= anot.length)
3052 anot[anpos] = new jalview.datamodel.Annotation(
3054 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3055 (ae[aa].getSecondaryStructure() == null || ae[aa]
3056 .getSecondaryStructure().length() == 0) ? ' '
3057 : ae[aa].getSecondaryStructure().charAt(0),
3061 // JBPNote: Consider verifying dataflow for IO of secondary
3062 // structure annotation read from Stockholm files
3063 // this was added to try to ensure that
3064 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3066 // anot[ae[aa].getPosition()].displayCharacter = "";
3068 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3069 if (firstColour == null)
3071 firstColour = anot[anpos].colour;
3075 jalview.datamodel.AlignmentAnnotation jaa = null;
3077 if (annotation.getGraph())
3079 float llim = 0, hlim = 0;
3080 // if (autoForView || an[i].isAutoCalculated()) {
3083 jaa = new jalview.datamodel.AlignmentAnnotation(
3084 annotation.getLabel(), annotation.getDescription(), anot,
3085 llim, hlim, annotation.getGraphType());
3087 jaa.graphGroup = annotation.getGraphGroup();
3088 jaa._linecolour = firstColour;
3089 if (annotation.getThresholdLine() != null)
3091 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3092 .getThresholdLine().getValue(), annotation
3093 .getThresholdLine().getLabel(), new java.awt.Color(
3094 annotation.getThresholdLine().getColour())));
3097 if (autoForView || annotation.isAutoCalculated())
3099 // Hardwire the symbol display line to ensure that labels for
3100 // histograms are displayed
3106 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3107 an[i].getDescription(), anot);
3108 jaa._linecolour = firstColour;
3110 // register new annotation
3111 if (an[i].getId() != null)
3113 annotationIds.put(an[i].getId(), jaa);
3114 jaa.annotationId = an[i].getId();
3116 // recover sequence association
3117 String sequenceRef = an[i].getSequenceRef();
3118 if (sequenceRef != null)
3120 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3121 SequenceI sequence = seqRefIds.get(sequenceRef);
3122 if (sequence == null)
3124 // in pre-2.9 projects sequence ref is to sequence name
3125 sequence = al.findName(sequenceRef);
3127 if (sequence != null)
3129 jaa.createSequenceMapping(sequence, 1, true);
3130 sequence.addAlignmentAnnotation(jaa);
3133 // and make a note of any group association
3134 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3136 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3137 .get(an[i].getGroupRef());
3140 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3141 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3146 if (an[i].hasScore())
3148 jaa.setScore(an[i].getScore());
3150 if (an[i].hasVisible())
3152 jaa.visible = an[i].getVisible();
3155 if (an[i].hasCentreColLabels())
3157 jaa.centreColLabels = an[i].getCentreColLabels();
3160 if (an[i].hasScaleColLabels())
3162 jaa.scaleColLabel = an[i].getScaleColLabels();
3164 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3166 // newer files have an 'autoCalculated' flag and store calculation
3167 // state in viewport properties
3168 jaa.autoCalculated = true; // means annotation will be marked for
3169 // update at end of load.
3171 if (an[i].hasGraphHeight())
3173 jaa.graphHeight = an[i].getGraphHeight();
3175 if (an[i].hasBelowAlignment())
3177 jaa.belowAlignment = an[i].isBelowAlignment();
3179 jaa.setCalcId(an[i].getCalcId());
3180 if (an[i].getPropertyCount() > 0)
3182 for (jalview.schemabinding.version2.Property prop : an[i]
3185 jaa.setProperty(prop.getName(), prop.getValue());
3188 if (jaa.autoCalculated)
3190 autoAlan.add(new JvAnnotRow(i, jaa));
3193 // if (!autoForView)
3195 // add autocalculated group annotation and any user created annotation
3197 al.addAnnotation(jaa);
3201 // ///////////////////////
3203 // Create alignment markup and styles for this view
3204 if (jms.getJGroupCount() > 0)
3206 JGroup[] groups = jms.getJGroup();
3207 boolean addAnnotSchemeGroup = false;
3208 for (int i = 0; i < groups.length; i++)
3210 JGroup jGroup = groups[i];
3211 ColourSchemeI cs = null;
3212 if (jGroup.getColour() != null)
3214 if (jGroup.getColour().startsWith("ucs"))
3216 cs = getUserColourScheme(jms, jGroup.getColour());
3218 else if (jGroup.getColour().equals("AnnotationColourGradient")
3219 && jGroup.getAnnotationColours() != null)
3221 addAnnotSchemeGroup = true;
3226 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3231 cs.setThreshold(jGroup.getPidThreshold(), true);
3235 Vector<SequenceI> seqs = new Vector<SequenceI>();
3237 for (int s = 0; s < jGroup.getSeqCount(); s++)
3239 String seqId = jGroup.getSeq(s) + "";
3240 SequenceI ts = seqRefIds.get(seqId);
3244 seqs.addElement(ts);
3248 if (seqs.size() < 1)
3253 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3254 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3255 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3257 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3259 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3260 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3261 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3262 .isShowUnconserved() : false);
3263 sg.thresholdTextColour = jGroup.getTextColThreshold();
3264 if (jGroup.hasShowConsensusHistogram())
3266 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3269 if (jGroup.hasShowSequenceLogo())
3271 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3273 if (jGroup.hasNormaliseSequenceLogo())
3275 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3277 if (jGroup.hasIgnoreGapsinConsensus())
3279 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3281 if (jGroup.getConsThreshold() != 0)
3283 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3284 "All", ResidueProperties.propHash, 3,
3285 sg.getSequences(null), 0, sg.getWidth() - 1);
3287 c.verdict(false, 25);
3288 sg.cs.setConservation(c);
3291 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3293 // re-instate unique group/annotation row reference
3294 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3298 for (AlignmentAnnotation jaa : jaal)
3301 if (jaa.autoCalculated)
3303 // match up and try to set group autocalc alignment row for this
3305 if (jaa.label.startsWith("Consensus for "))
3307 sg.setConsensus(jaa);
3309 // match up and try to set group autocalc alignment row for this
3311 if (jaa.label.startsWith("Conservation for "))
3313 sg.setConservationRow(jaa);
3320 if (addAnnotSchemeGroup)
3322 // reconstruct the annotation colourscheme
3323 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3324 null, al, jms, false);
3330 // only dataset in this model, so just return.
3333 // ///////////////////////////////
3336 // If we just load in the same jar file again, the sequenceSetId
3337 // will be the same, and we end up with multiple references
3338 // to the same sequenceSet. We must modify this id on load
3339 // so that each load of the file gives a unique id
3340 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3341 String viewId = (view.getId() == null ? null : view.getId()
3343 AlignFrame af = null;
3344 AlignViewport av = null;
3345 // now check to see if we really need to create a new viewport.
3346 if (multipleView && viewportsAdded.size() == 0)
3348 // We recovered an alignment for which a viewport already exists.
3349 // TODO: fix up any settings necessary for overlaying stored state onto
3350 // state recovered from another document. (may not be necessary).
3351 // we may need a binding from a viewport in memory to one recovered from
3353 // and then recover its containing af to allow the settings to be applied.
3354 // TODO: fix for vamsas demo
3356 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3358 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3359 if (seqsetobj != null)
3361 if (seqsetobj instanceof String)
3363 uniqueSeqSetId = (String) seqsetobj;
3365 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3371 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3377 * indicate that annotation colours are applied across all groups (pre
3378 * Jalview 2.8.1 behaviour)
3380 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3381 "2.8.1", object.getVersion());
3383 AlignmentPanel ap = null;
3384 boolean isnewview = true;
3387 // Check to see if this alignment already has a view id == viewId
3388 jalview.gui.AlignmentPanel views[] = Desktop
3389 .getAlignmentPanels(uniqueSeqSetId);
3390 if (views != null && views.length > 0)
3392 for (int v = 0; v < views.length; v++)
3394 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3396 // recover the existing alignpanel, alignframe, viewport
3397 af = views[v].alignFrame;
3400 // TODO: could even skip resetting view settings if we don't want to
3401 // change the local settings from other jalview processes
3410 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3411 uniqueSeqSetId, viewId, autoAlan);
3417 * Load any trees, PDB structures and viewers
3419 * Not done if flag is false (when this method is used for New View)
3421 if (loadTreesAndStructures)
3423 loadTrees(jms, view, af, av, ap);
3424 loadPDBStructures(jprovider, jseqs, af, ap);
3425 loadRnaViewers(jprovider, jseqs, ap);
3427 // and finally return.
3432 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3433 * panel is restored from separate jar entries, two (gapped and trimmed) per
3434 * sequence and secondary structure.
3436 * Currently each viewer shows just one sequence and structure (gapped and
3437 * trimmed), however this method is designed to support multiple sequences or
3438 * structures in viewers if wanted in future.
3444 private void loadRnaViewers(jarInputStreamProvider jprovider,
3445 JSeq[] jseqs, AlignmentPanel ap)
3448 * scan the sequences for references to viewers; create each one the first
3449 * time it is referenced, add Rna models to existing viewers
3451 for (JSeq jseq : jseqs)
3453 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3455 RnaViewer viewer = jseq.getRnaViewer(i);
3456 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3457 uniqueSetSuffix, ap);
3459 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3461 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3462 SequenceI seq = seqRefIds.get(jseq.getId());
3463 AlignmentAnnotation ann = this.annotationIds.get(ss
3464 .getAnnotationId());
3467 * add the structure to the Varna display (with session state copied
3468 * from the jar to a temporary file)
3470 boolean gapped = ss.isGapped();
3471 String rnaTitle = ss.getTitle();
3472 String sessionState = ss.getViewerState();
3473 String tempStateFile = copyJarEntry(jprovider, sessionState,
3475 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3476 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3478 appVarna.setInitialSelection(viewer.getSelectedRna());
3484 * Locate and return an already instantiated matching AppVarna, or create one
3488 * @param viewIdSuffix
3492 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3493 String viewIdSuffix, AlignmentPanel ap)
3496 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3497 * if load is repeated
3499 String postLoadId = viewer.getViewId() + viewIdSuffix;
3500 for (JInternalFrame frame : getAllFrames())
3502 if (frame instanceof AppVarna)
3504 AppVarna varna = (AppVarna) frame;
3505 if (postLoadId.equals(varna.getViewId()))
3507 // this viewer is already instantiated
3508 // could in future here add ap as another 'parent' of the
3509 // AppVarna window; currently just 1-to-many
3516 * viewer not found - make it
3518 RnaViewerModel model = new RnaViewerModel(postLoadId,
3519 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3520 viewer.getWidth(), viewer.getHeight(),
3521 viewer.getDividerLocation());
3522 AppVarna varna = new AppVarna(model, ap);
3528 * Load any saved trees
3536 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3537 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3539 // TODO result of automated refactoring - are all these parameters needed?
3542 for (int t = 0; t < jms.getTreeCount(); t++)
3545 Tree tree = jms.getTree(t);
3547 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3550 tp = af.ShowNewickTree(
3551 new jalview.io.NewickFile(tree.getNewick()),
3552 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3553 tree.getXpos(), tree.getYpos());
3554 if (tree.getId() != null)
3556 // perhaps bind the tree id to something ?
3561 // update local tree attributes ?
3562 // TODO: should check if tp has been manipulated by user - if so its
3563 // settings shouldn't be modified
3564 tp.setTitle(tree.getTitle());
3565 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3566 .getWidth(), tree.getHeight()));
3567 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3570 tp.treeCanvas.av = av; // af.viewport;
3571 tp.treeCanvas.ap = ap; // af.alignPanel;
3576 warn("There was a problem recovering stored Newick tree: \n"
3577 + tree.getNewick());
3581 tp.fitToWindow.setState(tree.getFitToWindow());
3582 tp.fitToWindow_actionPerformed(null);
3584 if (tree.getFontName() != null)
3586 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3587 .getFontStyle(), tree.getFontSize()));
3591 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3592 .getFontStyle(), tree.getFontSize()));
3595 tp.showPlaceholders(tree.getMarkUnlinked());
3596 tp.showBootstrap(tree.getShowBootstrap());
3597 tp.showDistances(tree.getShowDistances());
3599 tp.treeCanvas.threshold = tree.getThreshold();
3601 if (tree.getCurrentTree())
3603 af.viewport.setCurrentTree(tp.getTree());
3607 } catch (Exception ex)
3609 ex.printStackTrace();
3614 * Load and link any saved structure viewers.
3621 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3622 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3625 * Run through all PDB ids on the alignment, and collect mappings between
3626 * distinct view ids and all sequences referring to that view.
3628 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3630 for (int i = 0; i < jseqs.length; i++)
3632 if (jseqs[i].getPdbidsCount() > 0)
3634 Pdbids[] ids = jseqs[i].getPdbids();
3635 for (int p = 0; p < ids.length; p++)
3637 final int structureStateCount = ids[p].getStructureStateCount();
3638 for (int s = 0; s < structureStateCount; s++)
3640 // check to see if we haven't already created this structure view
3641 final StructureState structureState = ids[p]
3642 .getStructureState(s);
3643 String sviewid = (structureState.getViewId() == null) ? null
3644 : structureState.getViewId() + uniqueSetSuffix;
3645 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3646 // Originally : ids[p].getFile()
3647 // : TODO: verify external PDB file recovery still works in normal
3648 // jalview project load
3649 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3650 jpdb.setId(ids[p].getId());
3652 int x = structureState.getXpos();
3653 int y = structureState.getYpos();
3654 int width = structureState.getWidth();
3655 int height = structureState.getHeight();
3657 // Probably don't need to do this anymore...
3658 // Desktop.desktop.getComponentAt(x, y);
3659 // TODO: NOW: check that this recovers the PDB file correctly.
3660 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3661 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3663 if (sviewid == null)
3665 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3668 if (!structureViewers.containsKey(sviewid))
3670 structureViewers.put(sviewid,
3671 new StructureViewerModel(x, y, width, height, false,
3672 false, true, structureState.getViewId(),
3673 structureState.getType()));
3674 // Legacy pre-2.7 conversion JAL-823 :
3675 // do not assume any view has to be linked for colour by
3679 // assemble String[] { pdb files }, String[] { id for each
3680 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3681 // seqs_file 2}, boolean[] {
3682 // linkAlignPanel,superposeWithAlignpanel}} from hash
3683 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3684 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3685 | (structureState.hasAlignwithAlignPanel() ? structureState
3686 .getAlignwithAlignPanel() : false));
3689 * Default colour by linked panel to false if not specified (e.g.
3690 * for pre-2.7 projects)
3692 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3693 colourWithAlignPanel |= (structureState
3694 .hasColourwithAlignPanel() ? structureState
3695 .getColourwithAlignPanel() : false);
3696 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3699 * Default colour by viewer to true if not specified (e.g. for
3702 boolean colourByViewer = jmoldat.isColourByViewer();
3703 colourByViewer &= structureState.hasColourByJmol() ? structureState
3704 .getColourByJmol() : true;
3705 jmoldat.setColourByViewer(colourByViewer);
3707 if (jmoldat.getStateData().length() < structureState
3708 .getContent().length())
3711 jmoldat.setStateData(structureState.getContent());
3714 if (ids[p].getFile() != null)
3716 File mapkey = new File(ids[p].getFile());
3717 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3718 if (seqstrmaps == null)
3720 jmoldat.getFileData().put(
3722 seqstrmaps = jmoldat.new StructureData(pdbFile,
3725 if (!seqstrmaps.getSeqList().contains(seq))
3727 seqstrmaps.getSeqList().add(seq);
3733 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");
3740 // Instantiate the associated structure views
3741 for (Entry<String, StructureViewerModel> entry : structureViewers
3746 createOrLinkStructureViewer(entry, af, ap, jprovider);
3747 } catch (Exception e)
3749 System.err.println("Error loading structure viewer: "
3751 // failed - try the next one
3763 protected void createOrLinkStructureViewer(
3764 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3765 AlignmentPanel ap, jarInputStreamProvider jprovider)
3767 final StructureViewerModel stateData = viewerData.getValue();
3770 * Search for any viewer windows already open from other alignment views
3771 * that exactly match the stored structure state
3773 StructureViewerBase comp = findMatchingViewer(viewerData);
3777 linkStructureViewer(ap, comp, stateData);
3782 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3783 * "viewer_"+stateData.viewId
3785 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3787 createChimeraViewer(viewerData, af, jprovider);
3792 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3794 createJmolViewer(viewerData, af, jprovider);
3799 * Create a new Chimera viewer.
3805 protected void createChimeraViewer(
3806 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3807 jarInputStreamProvider jprovider)
3809 StructureViewerModel data = viewerData.getValue();
3810 String chimeraSessionFile = data.getStateData();
3813 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3815 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3816 * 'uniquified' sviewid used to reconstruct the viewer here
3818 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3819 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3822 Set<Entry<File, StructureData>> fileData = data.getFileData()
3824 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3825 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3826 for (Entry<File, StructureData> pdb : fileData)
3828 String filePath = pdb.getValue().getFilePath();
3829 String pdbId = pdb.getValue().getPdbId();
3830 // pdbs.add(new PDBEntry(filePath, pdbId));
3831 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3832 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3833 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3837 boolean colourByChimera = data.isColourByViewer();
3838 boolean colourBySequence = data.isColourWithAlignPanel();
3840 // TODO use StructureViewer as a factory here, see JAL-1761
3841 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3842 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3844 String newViewId = viewerData.getKey();
3846 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3847 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3848 colourBySequence, newViewId);
3849 cvf.setSize(data.getWidth(), data.getHeight());
3850 cvf.setLocation(data.getX(), data.getY());
3854 * Create a new Jmol window. First parse the Jmol state to translate filenames
3855 * loaded into the view, and record the order in which files are shown in the
3856 * Jmol view, so we can add the sequence mappings in same order.
3862 protected void createJmolViewer(
3863 final Entry<String, StructureViewerModel> viewerData,
3864 AlignFrame af, jarInputStreamProvider jprovider)
3866 final StructureViewerModel svattrib = viewerData.getValue();
3867 String state = svattrib.getStateData();
3870 * Pre-2.9: state element value is the Jmol state string
3872 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3875 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3877 state = readJarEntry(jprovider,
3878 getViewerJarEntryName(svattrib.getViewId()));
3881 List<String> pdbfilenames = new ArrayList<String>();
3882 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3883 List<String> pdbids = new ArrayList<String>();
3884 StringBuilder newFileLoc = new StringBuilder(64);
3885 int cp = 0, ncp, ecp;
3886 Map<File, StructureData> oldFiles = svattrib.getFileData();
3887 while ((ncp = state.indexOf("load ", cp)) > -1)
3891 // look for next filename in load statement
3892 newFileLoc.append(state.substring(cp,
3893 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3894 String oldfilenam = state.substring(ncp,
3895 ecp = state.indexOf("\"", ncp));
3896 // recover the new mapping data for this old filename
3897 // have to normalize filename - since Jmol and jalview do
3899 // translation differently.
3900 StructureData filedat = oldFiles.get(new File(oldfilenam));
3901 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3902 pdbfilenames.add(filedat.getFilePath());
3903 pdbids.add(filedat.getPdbId());
3904 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3905 newFileLoc.append("\"");
3906 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3907 // look for next file statement.
3908 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3912 // just append rest of state
3913 newFileLoc.append(state.substring(cp));
3917 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3918 newFileLoc = new StringBuilder(state);
3919 newFileLoc.append("; load append ");
3920 for (File id : oldFiles.keySet())
3922 // add this and any other pdb files that should be present in
3924 StructureData filedat = oldFiles.get(id);
3925 newFileLoc.append(filedat.getFilePath());
3926 pdbfilenames.add(filedat.getFilePath());
3927 pdbids.add(filedat.getPdbId());
3928 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3929 newFileLoc.append(" \"");
3930 newFileLoc.append(filedat.getFilePath());
3931 newFileLoc.append("\"");
3934 newFileLoc.append(";");
3937 if (newFileLoc.length() == 0)
3941 int histbug = newFileLoc.indexOf("history = ");
3945 * change "history = [true|false];" to "history = [1|0];"
3948 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3949 String val = (diff == -1) ? null : newFileLoc
3950 .substring(histbug, diff);
3951 if (val != null && val.length() >= 4)
3953 if (val.contains("e")) // eh? what can it be?
3955 if (val.trim().equals("true"))
3963 newFileLoc.replace(histbug, diff, val);
3968 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3970 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3971 final SequenceI[][] sq = seqmaps
3972 .toArray(new SequenceI[seqmaps.size()][]);
3973 final String fileloc = newFileLoc.toString();
3974 final String sviewid = viewerData.getKey();
3975 final AlignFrame alf = af;
3976 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3977 svattrib.getWidth(), svattrib.getHeight());
3980 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3985 JalviewStructureDisplayI sview = null;
3988 sview = new StructureViewer(alf.alignPanel
3989 .getStructureSelectionManager()).createView(
3990 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3991 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3992 addNewStructureViewer(sview);
3993 } catch (OutOfMemoryError ex)
3995 new OOMWarning("restoring structure view for PDB id " + id,
3996 (OutOfMemoryError) ex.getCause());
3997 if (sview != null && sview.isVisible())
3999 sview.closeViewer(false);
4000 sview.setVisible(false);
4006 } catch (InvocationTargetException ex)
4008 warn("Unexpected error when opening Jmol view.", ex);
4010 } catch (InterruptedException e)
4012 // e.printStackTrace();
4018 * Generates a name for the entry in the project jar file to hold state
4019 * information for a structure viewer
4024 protected String getViewerJarEntryName(String viewId)
4026 return VIEWER_PREFIX + viewId;
4030 * Returns any open frame that matches given structure viewer data. The match
4031 * is based on the unique viewId, or (for older project versions) the frame's
4037 protected StructureViewerBase findMatchingViewer(
4038 Entry<String, StructureViewerModel> viewerData)
4040 final String sviewid = viewerData.getKey();
4041 final StructureViewerModel svattrib = viewerData.getValue();
4042 StructureViewerBase comp = null;
4043 JInternalFrame[] frames = getAllFrames();
4044 for (JInternalFrame frame : frames)
4046 if (frame instanceof StructureViewerBase)
4049 * Post jalview 2.4 schema includes structure view id
4052 && ((StructureViewerBase) frame).getViewId()
4055 comp = (StructureViewerBase) frame;
4056 break; // break added in 2.9
4059 * Otherwise test for matching position and size of viewer frame
4061 else if (frame.getX() == svattrib.getX()
4062 && frame.getY() == svattrib.getY()
4063 && frame.getHeight() == svattrib.getHeight()
4064 && frame.getWidth() == svattrib.getWidth())
4066 comp = (StructureViewerBase) frame;
4067 // no break in faint hope of an exact match on viewId
4075 * Link an AlignmentPanel to an existing structure viewer.
4080 * @param useinViewerSuperpos
4081 * @param usetoColourbyseq
4082 * @param viewerColouring
4084 protected void linkStructureViewer(AlignmentPanel ap,
4085 StructureViewerBase viewer, StructureViewerModel stateData)
4087 // NOTE: if the jalview project is part of a shared session then
4088 // view synchronization should/could be done here.
4090 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4091 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4092 final boolean viewerColouring = stateData.isColourByViewer();
4093 Map<File, StructureData> oldFiles = stateData.getFileData();
4096 * Add mapping for sequences in this view to an already open viewer
4098 final AAStructureBindingModel binding = viewer.getBinding();
4099 for (File id : oldFiles.keySet())
4101 // add this and any other pdb files that should be present in the
4103 StructureData filedat = oldFiles.get(id);
4104 String pdbFile = filedat.getFilePath();
4105 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4106 binding.getSsm().setMapping(seq, null, pdbFile,
4107 jalview.io.AppletFormatAdapter.FILE);
4108 binding.addSequenceForStructFile(pdbFile, seq);
4110 // and add the AlignmentPanel's reference to the view panel
4111 viewer.addAlignmentPanel(ap);
4112 if (useinViewerSuperpos)
4114 viewer.useAlignmentPanelForSuperposition(ap);
4118 viewer.excludeAlignmentPanelForSuperposition(ap);
4120 if (usetoColourbyseq)
4122 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4126 viewer.excludeAlignmentPanelForColourbyseq(ap);
4131 * Get all frames within the Desktop.
4135 protected JInternalFrame[] getAllFrames()
4137 JInternalFrame[] frames = null;
4138 // TODO is this necessary - is it safe - risk of hanging?
4143 frames = Desktop.desktop.getAllFrames();
4144 } catch (ArrayIndexOutOfBoundsException e)
4146 // occasional No such child exceptions are thrown here...
4150 } catch (InterruptedException f)
4154 } while (frames == null);
4159 * Answers true if 'version' is equal to or later than 'supported', where each
4160 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4161 * changes. Development and test values for 'version' are leniently treated
4165 * - minimum version we are comparing against
4167 * - version of data being processsed
4170 public static boolean isVersionStringLaterThan(String supported,
4173 if (supported == null || version == null
4174 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4175 || version.equalsIgnoreCase("Test")
4176 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4178 System.err.println("Assuming project file with "
4179 + (version == null ? "null" : version)
4180 + " is compatible with Jalview version " + supported);
4185 return StringUtils.compareVersions(version, supported, "b") >= 0;
4189 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4191 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4193 if (newStructureViewers != null)
4195 sview.getBinding().setFinishedLoadingFromArchive(false);
4196 newStructureViewers.add(sview);
4200 protected void setLoadingFinishedForNewStructureViewers()
4202 if (newStructureViewers != null)
4204 for (JalviewStructureDisplayI sview : newStructureViewers)
4206 sview.getBinding().setFinishedLoadingFromArchive(true);
4208 newStructureViewers.clear();
4209 newStructureViewers = null;
4213 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4214 List<SequenceI> hiddenSeqs, AlignmentI al,
4215 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4216 String viewId, List<JvAnnotRow> autoAlan)
4218 AlignFrame af = null;
4219 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4220 uniqueSeqSetId, viewId);
4222 af.setFileName(file, "Jalview");
4224 for (int i = 0; i < JSEQ.length; i++)
4226 af.viewport.setSequenceColour(af.viewport.getAlignment()
4227 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4232 af.getViewport().setColourByReferenceSeq(true);
4233 af.getViewport().setDisplayReferenceSeq(true);
4236 af.viewport.setGatherViewsHere(view.getGatheredViews());
4238 if (view.getSequenceSetId() != null)
4240 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4242 af.viewport.setSequenceSetId(uniqueSeqSetId);
4245 // propagate shared settings to this new view
4246 af.viewport.setHistoryList(av.getHistoryList());
4247 af.viewport.setRedoList(av.getRedoList());
4251 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4253 // TODO: check if this method can be called repeatedly without
4254 // side-effects if alignpanel already registered.
4255 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4257 // apply Hidden regions to view.
4258 if (hiddenSeqs != null)
4260 for (int s = 0; s < JSEQ.length; s++)
4262 SequenceGroup hidden = new SequenceGroup();
4263 boolean isRepresentative = false;
4264 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4266 isRepresentative = true;
4267 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4268 .getHiddenSequences(r));
4269 hidden.addSequence(sequenceToHide, false);
4270 // remove from hiddenSeqs list so we don't try to hide it twice
4271 hiddenSeqs.remove(sequenceToHide);
4273 if (isRepresentative)
4275 SequenceI representativeSequence = al.getSequenceAt(s);
4276 hidden.addSequence(representativeSequence, false);
4277 af.viewport.hideRepSequences(representativeSequence, hidden);
4281 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4283 af.viewport.hideSequence(hseqs);
4286 // recover view properties and display parameters
4287 if (view.getViewName() != null)
4289 af.viewport.viewName = view.getViewName();
4290 af.setInitialTabVisible();
4292 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4295 af.viewport.setShowAnnotation(view.getShowAnnotation());
4296 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4298 af.viewport.setColourText(view.getShowColourText());
4300 af.viewport.setConservationSelected(view.getConservationSelected());
4301 af.viewport.setShowJVSuffix(view.getShowFullId());
4302 af.viewport.setRightAlignIds(view.getRightAlignIds());
4303 af.viewport.setFont(
4304 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4305 .getFontSize()), true);
4306 ViewStyleI vs = af.viewport.getViewStyle();
4307 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4308 af.viewport.setViewStyle(vs);
4309 // TODO: allow custom charWidth/Heights to be restored by updating them
4310 // after setting font - which means set above to false
4311 af.viewport.setRenderGaps(view.getRenderGaps());
4312 af.viewport.setWrapAlignment(view.getWrapAlignment());
4313 af.viewport.setShowAnnotation(view.getShowAnnotation());
4315 af.viewport.setShowBoxes(view.getShowBoxes());
4317 af.viewport.setShowText(view.getShowText());
4319 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4320 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4321 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4322 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4323 .isShowUnconserved() : false);
4324 af.viewport.setStartRes(view.getStartRes());
4325 af.viewport.setStartSeq(view.getStartSeq());
4326 af.alignPanel.updateLayout();
4327 ColourSchemeI cs = null;
4328 // apply colourschemes
4329 if (view.getBgColour() != null)
4331 if (view.getBgColour().startsWith("ucs"))
4333 cs = getUserColourScheme(jms, view.getBgColour());
4335 else if (view.getBgColour().startsWith("Annotation"))
4337 AnnotationColours viewAnnColour = view.getAnnotationColours();
4338 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4345 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4350 cs.setThreshold(view.getPidThreshold(), true);
4351 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4355 af.viewport.setGlobalColourScheme(cs);
4356 af.viewport.setColourAppliesToAllGroups(false);
4358 if (view.getConservationSelected() && cs != null)
4360 cs.setConservationInc(view.getConsThreshold());
4363 af.changeColour(cs);
4365 af.viewport.setColourAppliesToAllGroups(true);
4367 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4369 if (view.hasCentreColumnLabels())
4371 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4373 if (view.hasIgnoreGapsinConsensus())
4375 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4378 if (view.hasFollowHighlight())
4380 af.viewport.setFollowHighlight(view.getFollowHighlight());
4382 if (view.hasFollowSelection())
4384 af.viewport.followSelection = view.getFollowSelection();
4386 if (view.hasShowConsensusHistogram())
4388 af.viewport.setShowConsensusHistogram(view
4389 .getShowConsensusHistogram());
4393 af.viewport.setShowConsensusHistogram(true);
4395 if (view.hasShowSequenceLogo())
4397 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4401 af.viewport.setShowSequenceLogo(false);
4403 if (view.hasNormaliseSequenceLogo())
4405 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4407 if (view.hasShowDbRefTooltip())
4409 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4411 if (view.hasShowNPfeatureTooltip())
4413 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4415 if (view.hasShowGroupConsensus())
4417 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4421 af.viewport.setShowGroupConsensus(false);
4423 if (view.hasShowGroupConservation())
4425 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4429 af.viewport.setShowGroupConservation(false);
4432 // recover featre settings
4433 if (jms.getFeatureSettings() != null)
4435 FeaturesDisplayed fdi;
4436 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4437 String[] renderOrder = new String[jms.getFeatureSettings()
4438 .getSettingCount()];
4439 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4440 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4442 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4444 Setting setting = jms.getFeatureSettings().getSetting(fs);
4445 if (setting.hasMincolour())
4447 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4448 new Color(setting.getMincolour()), new Color(
4449 setting.getColour()), setting.getMin(),
4450 setting.getMax()) : new FeatureColour(new Color(
4451 setting.getMincolour()), new Color(setting.getColour()),
4453 if (setting.hasThreshold())
4455 gc.setThreshold(setting.getThreshold());
4456 int threshstate = setting.getThreshstate();
4457 // -1 = None, 0 = Below, 1 = Above threshold
4458 if (threshstate == 0)
4460 gc.setBelowThreshold(true);
4462 else if (threshstate == 1)
4464 gc.setAboveThreshold(true);
4467 gc.setAutoScaled(true); // default
4468 if (setting.hasAutoScale())
4470 gc.setAutoScaled(setting.getAutoScale());
4472 if (setting.hasColourByLabel())
4474 gc.setColourByLabel(setting.getColourByLabel());
4476 // and put in the feature colour table.
4477 featureColours.put(setting.getType(), gc);
4481 featureColours.put(setting.getType(), new FeatureColour(
4482 new Color(setting.getColour())));
4484 renderOrder[fs] = setting.getType();
4485 if (setting.hasOrder())
4487 featureOrder.put(setting.getType(), setting.getOrder());
4491 featureOrder.put(setting.getType(), new Float(fs
4492 / jms.getFeatureSettings().getSettingCount()));
4494 if (setting.getDisplay())
4496 fdi.setVisible(setting.getType());
4499 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4500 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4502 Group grp = jms.getFeatureSettings().getGroup(gs);
4503 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4505 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4506 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4507 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4508 FeatureRendererSettings frs = new FeatureRendererSettings(
4509 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4510 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4511 .transferSettings(frs);
4515 if (view.getHiddenColumnsCount() > 0)
4517 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4519 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4520 .getHiddenColumns(c).getEnd() // +1
4524 if (view.getCalcIdParam() != null)
4526 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4528 if (calcIdParam != null)
4530 if (recoverCalcIdParam(calcIdParam, af.viewport))
4535 warn("Couldn't recover parameters for "
4536 + calcIdParam.getCalcId());
4541 af.setMenusFromViewport(af.viewport);
4542 af.setTitle(view.getTitle());
4543 // TODO: we don't need to do this if the viewport is aready visible.
4545 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4546 * has a 'cdna/protein complement' view, in which case save it in order to
4547 * populate a SplitFrame once all views have been read in.
4549 String complementaryViewId = view.getComplementId();
4550 if (complementaryViewId == null)
4552 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4554 // recompute any autoannotation
4555 af.alignPanel.updateAnnotation(false, true);
4556 reorderAutoannotation(af, al, autoAlan);
4557 af.alignPanel.alignmentChanged();
4561 splitFrameCandidates.put(view, af);
4566 private ColourSchemeI constructAnnotationColour(
4567 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4568 JalviewModelSequence jms, boolean checkGroupAnnColour)
4570 boolean propagateAnnColour = false;
4571 ColourSchemeI cs = null;
4572 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4573 if (checkGroupAnnColour && al.getGroups() != null
4574 && al.getGroups().size() > 0)
4576 // pre 2.8.1 behaviour
4577 // check to see if we should transfer annotation colours
4578 propagateAnnColour = true;
4579 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4581 if (sg.cs instanceof AnnotationColourGradient)
4583 propagateAnnColour = false;
4587 // int find annotation
4588 if (annAlignment.getAlignmentAnnotation() != null)
4590 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4592 if (annAlignment.getAlignmentAnnotation()[i].label
4593 .equals(viewAnnColour.getAnnotation()))
4595 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4597 annAlignment.getAlignmentAnnotation()[i]
4598 .setThreshold(new jalview.datamodel.GraphLine(
4599 viewAnnColour.getThreshold(), "Threshold",
4600 java.awt.Color.black)
4605 if (viewAnnColour.getColourScheme().equals("None"))
4607 cs = new AnnotationColourGradient(
4608 annAlignment.getAlignmentAnnotation()[i],
4609 new java.awt.Color(viewAnnColour.getMinColour()),
4610 new java.awt.Color(viewAnnColour.getMaxColour()),
4611 viewAnnColour.getAboveThreshold());
4613 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4615 cs = new AnnotationColourGradient(
4616 annAlignment.getAlignmentAnnotation()[i],
4617 getUserColourScheme(jms,
4618 viewAnnColour.getColourScheme()),
4619 viewAnnColour.getAboveThreshold());
4623 cs = new AnnotationColourGradient(
4624 annAlignment.getAlignmentAnnotation()[i],
4625 ColourSchemeProperty.getColour(al,
4626 viewAnnColour.getColourScheme()),
4627 viewAnnColour.getAboveThreshold());
4629 if (viewAnnColour.hasPerSequence())
4631 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4634 if (viewAnnColour.hasPredefinedColours())
4636 ((AnnotationColourGradient) cs)
4637 .setPredefinedColours(viewAnnColour
4638 .isPredefinedColours());
4640 if (propagateAnnColour && al.getGroups() != null)
4642 // Also use these settings for all the groups
4643 for (int g = 0; g < al.getGroups().size(); g++)
4645 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4653 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4654 * new AnnotationColourGradient(
4655 * annAlignment.getAlignmentAnnotation()[i], new
4656 * java.awt.Color(viewAnnColour. getMinColour()), new
4657 * java.awt.Color(viewAnnColour. getMaxColour()),
4658 * viewAnnColour.getAboveThreshold()); } else
4661 sg.cs = new AnnotationColourGradient(
4662 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4663 viewAnnColour.getAboveThreshold());
4664 if (cs instanceof AnnotationColourGradient)
4666 if (viewAnnColour.hasPerSequence())
4668 ((AnnotationColourGradient) cs)
4669 .setSeqAssociated(viewAnnColour.isPerSequence());
4671 if (viewAnnColour.hasPredefinedColours())
4673 ((AnnotationColourGradient) cs)
4674 .setPredefinedColours(viewAnnColour
4675 .isPredefinedColours());
4691 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4692 List<JvAnnotRow> autoAlan)
4694 // copy over visualization settings for autocalculated annotation in the
4696 if (al.getAlignmentAnnotation() != null)
4699 * Kludge for magic autoannotation names (see JAL-811)
4701 String[] magicNames = new String[] { "Consensus", "Quality",
4703 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4704 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4705 for (String nm : magicNames)
4707 visan.put(nm, nullAnnot);
4709 for (JvAnnotRow auan : autoAlan)
4711 visan.put(auan.template.label
4712 + (auan.template.getCalcId() == null ? "" : "\t"
4713 + auan.template.getCalcId()), auan);
4715 int hSize = al.getAlignmentAnnotation().length;
4716 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4717 // work through any autoCalculated annotation already on the view
4718 // removing it if it should be placed in a different location on the
4719 // annotation panel.
4720 List<String> remains = new ArrayList<String>(visan.keySet());
4721 for (int h = 0; h < hSize; h++)
4723 jalview.datamodel.AlignmentAnnotation jalan = al
4724 .getAlignmentAnnotation()[h];
4725 if (jalan.autoCalculated)
4728 JvAnnotRow valan = visan.get(k = jalan.label);
4729 if (jalan.getCalcId() != null)
4731 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4736 // delete the auto calculated row from the alignment
4737 al.deleteAnnotation(jalan, false);
4741 if (valan != nullAnnot)
4743 if (jalan != valan.template)
4745 // newly created autoannotation row instance
4746 // so keep a reference to the visible annotation row
4747 // and copy over all relevant attributes
4748 if (valan.template.graphHeight >= 0)
4751 jalan.graphHeight = valan.template.graphHeight;
4753 jalan.visible = valan.template.visible;
4755 reorder.add(new JvAnnotRow(valan.order, jalan));
4760 // Add any (possibly stale) autocalculated rows that were not appended to
4761 // the view during construction
4762 for (String other : remains)
4764 JvAnnotRow othera = visan.get(other);
4765 if (othera != nullAnnot && othera.template.getCalcId() != null
4766 && othera.template.getCalcId().length() > 0)
4768 reorder.add(othera);
4771 // now put the automatic annotation in its correct place
4772 int s = 0, srt[] = new int[reorder.size()];
4773 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4774 for (JvAnnotRow jvar : reorder)
4777 srt[s++] = jvar.order;
4780 jalview.util.QuickSort.sort(srt, rws);
4781 // and re-insert the annotation at its correct position
4782 for (JvAnnotRow jvar : rws)
4784 al.addAnnotation(jvar.template, jvar.order);
4786 af.alignPanel.adjustAnnotationHeight();
4790 Hashtable skipList = null;
4793 * TODO remove this method
4796 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4797 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4798 * throw new Error("Implementation Error. No skipList defined for this
4799 * Jalview2XML instance."); } return (AlignFrame)
4800 * skipList.get(view.getSequenceSetId()); }
4804 * Check if the Jalview view contained in object should be skipped or not.
4807 * @return true if view's sequenceSetId is a key in skipList
4809 private boolean skipViewport(JalviewModel object)
4811 if (skipList == null)
4816 if (skipList.containsKey(id = object.getJalviewModelSequence()
4817 .getViewport()[0].getSequenceSetId()))
4819 if (Cache.log != null && Cache.log.isDebugEnabled())
4821 Cache.log.debug("Skipping seuqence set id " + id);
4828 public void addToSkipList(AlignFrame af)
4830 if (skipList == null)
4832 skipList = new Hashtable();
4834 skipList.put(af.getViewport().getSequenceSetId(), af);
4837 public void clearSkipList()
4839 if (skipList != null)
4846 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4847 boolean ignoreUnrefed)
4849 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4851 Vector dseqs = null;
4854 // create a list of new dataset sequences
4855 dseqs = new Vector();
4857 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4859 Sequence vamsasSeq = vamsasSet.getSequence(i);
4860 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4862 // create a new dataset
4865 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4866 dseqs.copyInto(dsseqs);
4867 ds = new jalview.datamodel.Alignment(dsseqs);
4868 debug("Created new dataset " + vamsasSet.getDatasetId()
4869 + " for alignment " + System.identityHashCode(al));
4870 addDatasetRef(vamsasSet.getDatasetId(), ds);
4872 // set the dataset for the newly imported alignment.
4873 if (al.getDataset() == null && !ignoreUnrefed)
4882 * sequence definition to create/merge dataset sequence for
4886 * vector to add new dataset sequence to
4888 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4889 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4891 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4893 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4894 SequenceI dsq = null;
4895 if (sq != null && sq.getDatasetSequence() != null)
4897 dsq = sq.getDatasetSequence();
4899 if (sq == null && ignoreUnrefed)
4903 String sqid = vamsasSeq.getDsseqid();
4906 // need to create or add a new dataset sequence reference to this sequence
4909 dsq = seqRefIds.get(sqid);
4914 // make a new dataset sequence
4915 dsq = sq.createDatasetSequence();
4918 // make up a new dataset reference for this sequence
4919 sqid = seqHash(dsq);
4921 dsq.setVamsasId(uniqueSetSuffix + sqid);
4922 seqRefIds.put(sqid, dsq);
4927 dseqs.addElement(dsq);
4932 ds.addSequence(dsq);
4938 { // make this dataset sequence sq's dataset sequence
4939 sq.setDatasetSequence(dsq);
4940 // and update the current dataset alignment
4945 if (!dseqs.contains(dsq))
4952 if (ds.findIndex(dsq) < 0)
4954 ds.addSequence(dsq);
4961 // TODO: refactor this as a merge dataset sequence function
4962 // now check that sq (the dataset sequence) sequence really is the union of
4963 // all references to it
4964 // boolean pre = sq.getStart() < dsq.getStart();
4965 // boolean post = sq.getEnd() > dsq.getEnd();
4969 // StringBuffer sb = new StringBuffer();
4970 String newres = jalview.analysis.AlignSeq.extractGaps(
4971 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4972 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4973 && newres.length() > dsq.getLength())
4975 // Update with the longer sequence.
4979 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4980 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4981 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4982 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4984 dsq.setSequence(newres);
4986 // TODO: merges will never happen if we 'know' we have the real dataset
4987 // sequence - this should be detected when id==dssid
4989 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4990 // + (pre ? "prepended" : "") + " "
4991 // + (post ? "appended" : ""));
4997 * TODO use AlignmentI here and in related methods - needs
4998 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5000 Hashtable<String, AlignmentI> datasetIds = null;
5002 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5004 private AlignmentI getDatasetFor(String datasetId)
5006 if (datasetIds == null)
5008 datasetIds = new Hashtable<String, AlignmentI>();
5011 if (datasetIds.containsKey(datasetId))
5013 return datasetIds.get(datasetId);
5018 private void addDatasetRef(String datasetId, AlignmentI dataset)
5020 if (datasetIds == null)
5022 datasetIds = new Hashtable<String, AlignmentI>();
5024 datasetIds.put(datasetId, dataset);
5028 * make a new dataset ID for this jalview dataset alignment
5033 private String getDatasetIdRef(AlignmentI dataset)
5035 if (dataset.getDataset() != null)
5037 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5039 String datasetId = makeHashCode(dataset, null);
5040 if (datasetId == null)
5042 // make a new datasetId and record it
5043 if (dataset2Ids == null)
5045 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5049 datasetId = dataset2Ids.get(dataset);
5051 if (datasetId == null)
5053 datasetId = "ds" + dataset2Ids.size() + 1;
5054 dataset2Ids.put(dataset, datasetId);
5060 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5062 for (int d = 0; d < sequence.getDBRefCount(); d++)
5064 DBRef dr = sequence.getDBRef(d);
5065 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5066 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5067 .getVersion(), sequence.getDBRef(d).getAccessionId());
5068 if (dr.getMapping() != null)
5070 entry.setMap(addMapping(dr.getMapping()));
5072 datasetSequence.addDBRef(entry);
5076 private jalview.datamodel.Mapping addMapping(Mapping m)
5078 SequenceI dsto = null;
5079 // Mapping m = dr.getMapping();
5080 int fr[] = new int[m.getMapListFromCount() * 2];
5081 Enumeration f = m.enumerateMapListFrom();
5082 for (int _i = 0; f.hasMoreElements(); _i += 2)
5084 MapListFrom mf = (MapListFrom) f.nextElement();
5085 fr[_i] = mf.getStart();
5086 fr[_i + 1] = mf.getEnd();
5088 int fto[] = new int[m.getMapListToCount() * 2];
5089 f = m.enumerateMapListTo();
5090 for (int _i = 0; f.hasMoreElements(); _i += 2)
5092 MapListTo mf = (MapListTo) f.nextElement();
5093 fto[_i] = mf.getStart();
5094 fto[_i + 1] = mf.getEnd();
5096 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5097 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5098 if (m.getMappingChoice() != null)
5100 MappingChoice mc = m.getMappingChoice();
5101 if (mc.getDseqFor() != null)
5103 String dsfor = "" + mc.getDseqFor();
5104 if (seqRefIds.containsKey(dsfor))
5109 jmap.setTo(seqRefIds.get(dsfor));
5113 frefedSequence.add(newMappingRef(dsfor, jmap));
5119 * local sequence definition
5121 Sequence ms = mc.getSequence();
5122 SequenceI djs = null;
5123 String sqid = ms.getDsseqid();
5124 if (sqid != null && sqid.length() > 0)
5127 * recover dataset sequence
5129 djs = seqRefIds.get(sqid);
5134 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5135 sqid = ((Object) ms).toString(); // make up a new hascode for
5136 // undefined dataset sequence hash
5137 // (unlikely to happen)
5143 * make a new dataset sequence and add it to refIds hash
5145 djs = new jalview.datamodel.Sequence(ms.getName(),
5147 djs.setStart(jmap.getMap().getToLowest());
5148 djs.setEnd(jmap.getMap().getToHighest());
5149 djs.setVamsasId(uniqueSetSuffix + sqid);
5151 incompleteSeqs.put(sqid, djs);
5152 seqRefIds.put(sqid, djs);
5155 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5164 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5165 boolean keepSeqRefs)
5168 JalviewModel jm = saveState(ap, null, null, null);
5173 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5177 uniqueSetSuffix = "";
5178 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5183 if (this.frefedSequence == null)
5185 frefedSequence = new Vector();
5188 viewportsAdded.clear();
5190 AlignFrame af = loadFromObject(jm, null, false, null);
5191 af.alignPanels.clear();
5192 af.closeMenuItem_actionPerformed(true);
5195 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5196 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5197 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5198 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5199 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5202 return af.alignPanel;
5206 * flag indicating if hashtables should be cleared on finalization TODO this
5207 * flag may not be necessary
5209 private final boolean _cleartables = true;
5211 private Hashtable jvids2vobj;
5216 * @see java.lang.Object#finalize()
5219 protected void finalize() throws Throwable
5221 // really make sure we have no buried refs left.
5226 this.seqRefIds = null;
5227 this.seqsToIds = null;
5231 private void warn(String msg)
5236 private void warn(String msg, Exception e)
5238 if (Cache.log != null)
5242 Cache.log.warn(msg, e);
5246 Cache.log.warn(msg);
5251 System.err.println("Warning: " + msg);
5254 e.printStackTrace();
5259 private void debug(String string)
5261 debug(string, null);
5264 private void debug(String msg, Exception e)
5266 if (Cache.log != null)
5270 Cache.log.debug(msg, e);
5274 Cache.log.debug(msg);
5279 System.err.println("Warning: " + msg);
5282 e.printStackTrace();
5288 * set the object to ID mapping tables used to write/recover objects and XML
5289 * ID strings for the jalview project. If external tables are provided then
5290 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5291 * object goes out of scope. - also populates the datasetIds hashtable with
5292 * alignment objects containing dataset sequences
5295 * Map from ID strings to jalview datamodel
5297 * Map from jalview datamodel to ID strings
5301 public void setObjectMappingTables(Hashtable vobj2jv,
5302 IdentityHashMap jv2vobj)
5304 this.jv2vobj = jv2vobj;
5305 this.vobj2jv = vobj2jv;
5306 Iterator ds = jv2vobj.keySet().iterator();
5308 while (ds.hasNext())
5310 Object jvobj = ds.next();
5311 id = jv2vobj.get(jvobj).toString();
5312 if (jvobj instanceof jalview.datamodel.Alignment)
5314 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5316 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5319 else if (jvobj instanceof jalview.datamodel.Sequence)
5321 // register sequence object so the XML parser can recover it.
5322 if (seqRefIds == null)
5324 seqRefIds = new HashMap<String, SequenceI>();
5326 if (seqsToIds == null)
5328 seqsToIds = new IdentityHashMap<SequenceI, String>();
5330 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5331 seqsToIds.put((SequenceI) jvobj, id);
5333 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5336 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5337 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5338 if (jvann.annotationId == null)
5340 jvann.annotationId = anid;
5342 if (!jvann.annotationId.equals(anid))
5344 // TODO verify that this is the correct behaviour
5345 this.warn("Overriding Annotation ID for " + anid
5346 + " from different id : " + jvann.annotationId);
5347 jvann.annotationId = anid;
5350 else if (jvobj instanceof String)
5352 if (jvids2vobj == null)
5354 jvids2vobj = new Hashtable();
5355 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5360 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5366 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5367 * objects created from the project archive. If string is null (default for
5368 * construction) then suffix will be set automatically.
5372 public void setUniqueSetSuffix(String string)
5374 uniqueSetSuffix = string;
5379 * uses skipList2 as the skipList for skipping views on sequence sets
5380 * associated with keys in the skipList
5384 public void setSkipList(Hashtable skipList2)
5386 skipList = skipList2;
5390 * Reads the jar entry of given name and returns its contents, or null if the
5391 * entry is not found.
5394 * @param jarEntryName
5397 protected String readJarEntry(jarInputStreamProvider jprovider,
5398 String jarEntryName)
5400 String result = null;
5401 BufferedReader in = null;
5406 * Reopen the jar input stream and traverse its entries to find a matching
5409 JarInputStream jin = jprovider.getJarInputStream();
5410 JarEntry entry = null;
5413 entry = jin.getNextJarEntry();
5414 } while (entry != null && !entry.getName().equals(jarEntryName));
5418 StringBuilder out = new StringBuilder(256);
5419 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5422 while ((data = in.readLine()) != null)
5426 result = out.toString();
5430 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5432 } catch (Exception ex)
5434 ex.printStackTrace();
5442 } catch (IOException e)
5453 * Returns an incrementing counter (0, 1, 2...)
5457 private synchronized int nextCounter()