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.Enumeration;
112 import java.util.HashMap;
113 import java.util.HashSet;
114 import java.util.Hashtable;
115 import java.util.IdentityHashMap;
116 import java.util.Iterator;
117 import java.util.LinkedHashMap;
118 import java.util.List;
119 import java.util.Map;
120 import java.util.Map.Entry;
121 import java.util.Set;
122 import java.util.Vector;
123 import java.util.jar.JarEntry;
124 import java.util.jar.JarInputStream;
125 import java.util.jar.JarOutputStream;
127 import javax.swing.JInternalFrame;
128 import javax.swing.JOptionPane;
129 import javax.swing.SwingUtilities;
131 import org.exolab.castor.xml.Marshaller;
132 import org.exolab.castor.xml.Unmarshaller;
135 * Write out the current jalview desktop state as a Jalview XML stream.
137 * Note: the vamsas objects referred to here are primitive versions of the
138 * VAMSAS project schema elements - they are not the same and most likely never
142 * @version $Revision: 1.134 $
144 public class Jalview2XML
146 private static final String VIEWER_PREFIX = "viewer_";
148 private static final String RNA_PREFIX = "rna_";
150 private static final String UTF_8 = "UTF-8";
152 // use this with nextCounter() to make unique names for entities
153 private int counter = 0;
156 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
157 * of sequence objects are created.
159 IdentityHashMap<SequenceI, String> seqsToIds = null;
162 * jalview XML Sequence ID to jalview sequence object reference (both dataset
163 * and alignment sequences. Populated as XML reps of sequence objects are
166 Map<String, SequenceI> seqRefIds = null;
168 Map<String, SequenceI> incompleteSeqs = null;
170 List<SeqFref> frefedSequence = null;
172 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
175 * Map of reconstructed AlignFrame objects that appear to have come from
176 * SplitFrame objects (have a dna/protein complement view).
178 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
181 * Map from displayed rna structure models to their saved session state jar
184 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
187 * create/return unique hash string for sq
190 * @return new or existing unique string for sq
192 String seqHash(SequenceI sq)
194 if (seqsToIds == null)
198 if (seqsToIds.containsKey(sq))
200 return seqsToIds.get(sq);
204 // create sequential key
205 String key = "sq" + (seqsToIds.size() + 1);
206 key = makeHashCode(sq, key); // check we don't have an external reference
208 seqsToIds.put(sq, key);
217 if (seqRefIds != null)
221 if (seqsToIds != null)
225 if (incompleteSeqs != null)
227 incompleteSeqs.clear();
235 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
236 // seqRefIds = new Hashtable();
237 // seqsToIds = new IdentityHashMap();
243 if (seqsToIds == null)
245 seqsToIds = new IdentityHashMap<SequenceI, String>();
247 if (seqRefIds == null)
249 seqRefIds = new HashMap<String, SequenceI>();
251 if (incompleteSeqs == null)
253 incompleteSeqs = new HashMap<String, SequenceI>();
255 if (frefedSequence == null)
257 frefedSequence = new ArrayList<SeqFref>();
265 public Jalview2XML(boolean raiseGUI)
267 this.raiseGUI = raiseGUI;
271 * base class for resolving forward references to sequences by their ID
276 abstract class SeqFref
280 public SeqFref(String _sref)
285 public String getSref()
290 public SequenceI getSrefSeq()
292 return seqRefIds.get(sref);
295 public boolean isResolvable()
297 return seqRefIds.get(sref) != null;
300 public SequenceI getSrefDatasetSeq()
302 SequenceI sq = seqRefIds.get(sref);
305 while (sq.getDatasetSequence() != null)
307 sq = sq.getDatasetSequence();
313 * @return true if the forward reference was fully resolved
315 abstract boolean resolve();
319 * create forward reference for a mapping
325 public SeqFref newMappingRef(final String sref,
326 final jalview.datamodel.Mapping _jmap)
328 SeqFref fref = new SeqFref(sref)
330 public jalview.datamodel.Mapping jmap = _jmap;
335 SequenceI seq = getSrefDatasetSeq();
347 public SeqFref newAlcodMapRef(final String sref,
348 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
351 SeqFref fref = new SeqFref(sref)
353 AlignedCodonFrame cf = _cf;
355 public jalview.datamodel.Mapping mp = _jmap;
360 SequenceI seq = getSrefDatasetSeq();
365 cf.addMap(seq, mp.getTo(), mp.getMap());
372 public void resolveFrefedSequences()
374 Iterator<SeqFref> nextFref=frefedSequence.iterator();
375 int toresolve=frefedSequence.size();
376 int unresolved=0,failedtoresolve=0;
377 while (nextFref.hasNext()) {
378 SeqFref ref = nextFref.next();
379 if (ref.isResolvable())
388 } catch (Exception x) {
389 System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
399 System.err.println("Jalview Project Import: There were " + unresolved
400 + " forward references left unresolved on the stack.");
402 if (failedtoresolve>0)
404 System.err.println("SERIOUS! " + failedtoresolve
405 + " resolvable forward references failed to resolve.");
407 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
409 System.err.println("Jalview Project Import: There are "
410 + incompleteSeqs.size()
411 + " sequences which may have incomplete metadata.");
412 if (incompleteSeqs.size() < 10)
414 for (SequenceI s : incompleteSeqs.values())
416 System.err.println(s.toString());
422 .println("Too many to report. Skipping output of incomplete sequences.");
428 * This maintains a map of viewports, the key being the seqSetId. Important to
429 * set historyItem and redoList for multiple views
431 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
433 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
435 String uniqueSetSuffix = "";
438 * List of pdbfiles added to Jar
440 List<String> pdbfiles = null;
442 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
443 public void saveState(File statefile)
445 FileOutputStream fos = null;
448 fos = new FileOutputStream(statefile);
449 JarOutputStream jout = new JarOutputStream(fos);
452 } catch (Exception e)
454 // TODO: inform user of the problem - they need to know if their data was
456 if (errorMessage == null)
458 errorMessage = "Couldn't write Jalview Archive to output file '"
459 + statefile + "' - See console error log for details";
463 errorMessage += "(output file was '" + statefile + "')";
473 } catch (IOException e)
483 * Writes a jalview project archive to the given Jar output stream.
487 public void saveState(JarOutputStream jout)
489 AlignFrame[] frames = Desktop.getAlignFrames();
496 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
499 * ensure cached data is clear before starting
501 // todo tidy up seqRefIds, seqsToIds initialisation / reset
503 splitFrameCandidates.clear();
508 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
509 // //////////////////////////////////////////////////
511 List<String> shortNames = new ArrayList<String>();
512 List<String> viewIds = new ArrayList<String>();
515 for (int i = frames.length - 1; i > -1; i--)
517 AlignFrame af = frames[i];
521 .containsKey(af.getViewport().getSequenceSetId()))
526 String shortName = makeFilename(af, shortNames);
528 int ap, apSize = af.alignPanels.size();
530 for (ap = 0; ap < apSize; ap++)
532 AlignmentPanel apanel = af.alignPanels.get(ap);
533 String fileName = apSize == 1 ? shortName : ap + shortName;
534 if (!fileName.endsWith(".xml"))
536 fileName = fileName + ".xml";
539 saveState(apanel, fileName, jout, viewIds);
541 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
543 if (!dsses.containsKey(dssid))
545 dsses.put(dssid, af);
550 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
556 } catch (Exception foo)
561 } catch (Exception ex)
563 // TODO: inform user of the problem - they need to know if their data was
565 if (errorMessage == null)
567 errorMessage = "Couldn't write Jalview Archive - see error output for details";
569 ex.printStackTrace();
574 * Generates a distinct file name, based on the title of the AlignFrame, by
575 * appending _n for increasing n until an unused name is generated. The new
576 * name (without its extension) is added to the list.
580 * @return the generated name, with .xml extension
582 protected String makeFilename(AlignFrame af, List<String> namesUsed)
584 String shortName = af.getTitle();
586 if (shortName.indexOf(File.separatorChar) > -1)
588 shortName = shortName.substring(shortName
589 .lastIndexOf(File.separatorChar) + 1);
594 while (namesUsed.contains(shortName))
596 if (shortName.endsWith("_" + (count - 1)))
598 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
601 shortName = shortName.concat("_" + count);
605 namesUsed.add(shortName);
607 if (!shortName.endsWith(".xml"))
609 shortName = shortName + ".xml";
614 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
615 public boolean saveAlignment(AlignFrame af, String jarFile,
621 int apSize = af.alignPanels.size();
622 FileOutputStream fos = new FileOutputStream(jarFile);
623 JarOutputStream jout = new JarOutputStream(fos);
624 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
625 List<String> viewIds = new ArrayList<String>();
627 for (AlignmentPanel apanel : af.alignPanels)
629 String jfileName = apSize == 1 ? fileName : fileName + ap;
631 if (!jfileName.endsWith(".xml"))
633 jfileName = jfileName + ".xml";
635 saveState(apanel, jfileName, jout, viewIds);
636 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
638 if (!dsses.containsKey(dssid))
640 dsses.put(dssid, af);
643 writeDatasetFor(dsses, fileName, jout);
647 } catch (Exception foo)
653 } catch (Exception ex)
655 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
656 ex.printStackTrace();
661 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
662 String fileName, JarOutputStream jout)
665 for (String dssids : dsses.keySet())
667 AlignFrame _af = dsses.get(dssids);
668 String jfileName = fileName + " Dataset for " + _af.getTitle();
669 if (!jfileName.endsWith(".xml"))
671 jfileName = jfileName + ".xml";
673 saveState(_af.alignPanel, jfileName, true, jout, null);
678 * create a JalviewModel from an alignment view and marshall it to a
682 * panel to create jalview model for
684 * name of alignment panel written to output stream
691 public JalviewModel saveState(AlignmentPanel ap, String fileName,
692 JarOutputStream jout, List<String> viewIds)
694 return saveState(ap, fileName, false, jout, viewIds);
698 * create a JalviewModel from an alignment view and marshall it to a
702 * panel to create jalview model for
704 * name of alignment panel written to output stream
706 * when true, only write the dataset for the alignment, not the data
707 * associated with the view.
713 public JalviewModel saveState(AlignmentPanel ap, String fileName,
714 boolean storeDS, JarOutputStream jout, List<String> viewIds)
718 viewIds = new ArrayList<String>();
723 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
725 AlignViewport av = ap.av;
727 JalviewModel object = new JalviewModel();
728 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
730 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
731 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
732 "Development Build"));
735 * rjal is full height alignment, jal is actual alignment with full metadata
736 * but excludes hidden sequences.
738 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
740 if (av.hasHiddenRows())
742 rjal = jal.getHiddenSequences().getFullAlignment();
745 SequenceSet vamsasSet = new SequenceSet();
747 JalviewModelSequence jms = new JalviewModelSequence();
749 vamsasSet.setGapChar(jal.getGapCharacter() + "");
751 if (jal.getDataset() != null)
753 // dataset id is the dataset's hashcode
754 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
757 // switch jal and the dataset
758 jal = jal.getDataset();
762 if (jal.getProperties() != null)
764 Enumeration en = jal.getProperties().keys();
765 while (en.hasMoreElements())
767 String key = en.nextElement().toString();
768 SequenceSetProperties ssp = new SequenceSetProperties();
770 ssp.setValue(jal.getProperties().get(key).toString());
771 vamsasSet.addSequenceSetProperties(ssp);
776 Set<String> calcIdSet = new HashSet<String>();
779 for (final SequenceI jds : rjal.getSequences())
781 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
782 : jds.getDatasetSequence();
783 String id = seqHash(jds);
785 if (seqRefIds.get(id) != null)
787 // This happens for two reasons: 1. multiple views are being serialised.
788 // 2. the hashCode has collided with another sequence's code. This DOES
789 // HAPPEN! (PF00072.15.stk does this)
790 // JBPNote: Uncomment to debug writing out of files that do not read
791 // back in due to ArrayOutOfBoundExceptions.
792 // System.err.println("vamsasSeq backref: "+id+"");
793 // System.err.println(jds.getName()+"
794 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
795 // System.err.println("Hashcode: "+seqHash(jds));
796 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
797 // System.err.println(rsq.getName()+"
798 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
799 // System.err.println("Hashcode: "+seqHash(rsq));
803 vamsasSeq = createVamsasSequence(id, jds);
804 vamsasSet.addSequence(vamsasSeq);
805 seqRefIds.put(id, jds);
809 jseq.setStart(jds.getStart());
810 jseq.setEnd(jds.getEnd());
811 jseq.setColour(av.getSequenceColour(jds).getRGB());
813 jseq.setId(id); // jseq id should be a string not a number
816 // Store any sequences this sequence represents
817 if (av.hasHiddenRows())
819 // use rjal, contains the full height alignment
820 jseq.setHidden(av.getAlignment().getHiddenSequences()
823 if (av.isHiddenRepSequence(jds))
825 jalview.datamodel.SequenceI[] reps = av
826 .getRepresentedSequences(jds)
827 .getSequencesInOrder(rjal);
829 for (int h = 0; h < reps.length; h++)
833 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
838 // mark sequence as reference - if it is the reference for this view
841 jseq.setViewreference(jds == jal.getSeqrep());
845 // TODO: omit sequence features from each alignment view's XML dump if we
846 // are storing dataset
847 if (jds.getSequenceFeatures() != null)
849 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
851 while (index < sf.length)
853 Features features = new Features();
855 features.setBegin(sf[index].getBegin());
856 features.setEnd(sf[index].getEnd());
857 features.setDescription(sf[index].getDescription());
858 features.setType(sf[index].getType());
859 features.setFeatureGroup(sf[index].getFeatureGroup());
860 features.setScore(sf[index].getScore());
861 if (sf[index].links != null)
863 for (int l = 0; l < sf[index].links.size(); l++)
865 OtherData keyValue = new OtherData();
866 keyValue.setKey("LINK_" + l);
867 keyValue.setValue(sf[index].links.elementAt(l).toString());
868 features.addOtherData(keyValue);
871 if (sf[index].otherDetails != null)
874 Iterator<String> keys = sf[index].otherDetails.keySet()
876 while (keys.hasNext())
879 OtherData keyValue = new OtherData();
880 keyValue.setKey(key);
881 keyValue.setValue(sf[index].otherDetails.get(key).toString());
882 features.addOtherData(keyValue);
886 jseq.addFeatures(features);
891 if (jdatasq.getAllPDBEntries() != null)
893 Enumeration en = jdatasq.getAllPDBEntries().elements();
894 while (en.hasMoreElements())
896 Pdbids pdb = new Pdbids();
897 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
900 String pdbId = entry.getId();
902 pdb.setType(entry.getType());
905 * Store any structure views associated with this sequence. This
906 * section copes with duplicate entries in the project, so a dataset
907 * only view *should* be coped with sensibly.
909 // This must have been loaded, is it still visible?
910 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
911 String matchedFile = null;
912 for (int f = frames.length - 1; f > -1; f--)
914 if (frames[f] instanceof StructureViewerBase)
916 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
917 matchedFile = saveStructureState(ap, jds, pdb, entry,
918 viewIds, matchedFile, viewFrame);
920 * Only store each structure viewer's state once in the project
921 * jar. First time through only (storeDS==false)
923 String viewId = viewFrame.getViewId();
924 if (!storeDS && !viewIds.contains(viewId))
929 String viewerState = viewFrame.getStateInfo();
930 writeJarEntry(jout, getViewerJarEntryName(viewId),
931 viewerState.getBytes());
932 } catch (IOException e)
934 System.err.println("Error saving viewer state: "
941 if (matchedFile != null || entry.getFile() != null)
943 if (entry.getFile() != null)
946 matchedFile = entry.getFile();
948 pdb.setFile(matchedFile); // entry.getFile());
949 if (pdbfiles == null)
951 pdbfiles = new ArrayList<String>();
954 if (!pdbfiles.contains(pdbId))
957 copyFileToJar(jout, matchedFile, pdbId);
961 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
963 PdbentryItem item = new PdbentryItem();
964 Hashtable properties = entry.getProperty();
965 Enumeration en2 = properties.keys();
966 while (en2.hasMoreElements())
968 Property prop = new Property();
969 String key = en2.nextElement().toString();
971 prop.setValue(properties.get(key).toString());
972 item.addProperty(prop);
974 pdb.addPdbentryItem(item);
981 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
986 if (!storeDS && av.hasHiddenRows())
988 jal = av.getAlignment();
991 if (jal.getCodonFrames() != null)
993 List<AlignedCodonFrame> jac = jal.getCodonFrames();
994 for (AlignedCodonFrame acf : jac)
996 AlcodonFrame alc = new AlcodonFrame();
997 if (acf.getProtMappings() != null
998 && acf.getProtMappings().length > 0)
1000 boolean hasMap = false;
1001 SequenceI[] dnas = acf.getdnaSeqs();
1002 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1003 for (int m = 0; m < pmaps.length; m++)
1005 AlcodMap alcmap = new AlcodMap();
1006 alcmap.setDnasq(seqHash(dnas[m]));
1007 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1009 alc.addAlcodMap(alcmap);
1014 vamsasSet.addAlcodonFrame(alc);
1017 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1019 // AlcodonFrame alc = new AlcodonFrame();
1020 // vamsasSet.addAlcodonFrame(alc);
1021 // for (int p = 0; p < acf.aaWidth; p++)
1023 // Alcodon cmap = new Alcodon();
1024 // if (acf.codons[p] != null)
1026 // // Null codons indicate a gapped column in the translated peptide
1028 // cmap.setPos1(acf.codons[p][0]);
1029 // cmap.setPos2(acf.codons[p][1]);
1030 // cmap.setPos3(acf.codons[p][2]);
1032 // alc.addAlcodon(cmap);
1034 // if (acf.getProtMappings() != null
1035 // && acf.getProtMappings().length > 0)
1037 // SequenceI[] dnas = acf.getdnaSeqs();
1038 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1039 // for (int m = 0; m < pmaps.length; m++)
1041 // AlcodMap alcmap = new AlcodMap();
1042 // alcmap.setDnasq(seqHash(dnas[m]));
1043 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1045 // alc.addAlcodMap(alcmap);
1052 // /////////////////////////////////
1053 if (!storeDS && av.currentTree != null)
1055 // FIND ANY ASSOCIATED TREES
1056 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1057 if (Desktop.desktop != null)
1059 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1061 for (int t = 0; t < frames.length; t++)
1063 if (frames[t] instanceof TreePanel)
1065 TreePanel tp = (TreePanel) frames[t];
1067 if (tp.treeCanvas.av.getAlignment() == jal)
1069 Tree tree = new Tree();
1070 tree.setTitle(tp.getTitle());
1071 tree.setCurrentTree((av.currentTree == tp.getTree()));
1072 tree.setNewick(tp.getTree().toString());
1073 tree.setThreshold(tp.treeCanvas.threshold);
1075 tree.setFitToWindow(tp.fitToWindow.getState());
1076 tree.setFontName(tp.getTreeFont().getName());
1077 tree.setFontSize(tp.getTreeFont().getSize());
1078 tree.setFontStyle(tp.getTreeFont().getStyle());
1079 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1081 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1082 tree.setShowDistances(tp.distanceMenu.getState());
1084 tree.setHeight(tp.getHeight());
1085 tree.setWidth(tp.getWidth());
1086 tree.setXpos(tp.getX());
1087 tree.setYpos(tp.getY());
1088 tree.setId(makeHashCode(tp, null));
1098 * store forward refs from an annotationRow to any groups
1100 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1103 for (SequenceI sq : jal.getSequences())
1105 // Store annotation on dataset sequences only
1106 AlignmentAnnotation[] aa = sq.getAnnotation();
1107 if (aa != null && aa.length > 0)
1109 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1116 if (jal.getAlignmentAnnotation() != null)
1118 // Store the annotation shown on the alignment.
1119 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1120 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1125 if (jal.getGroups() != null)
1127 JGroup[] groups = new JGroup[jal.getGroups().size()];
1129 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1131 JGroup jGroup = new JGroup();
1132 groups[++i] = jGroup;
1134 jGroup.setStart(sg.getStartRes());
1135 jGroup.setEnd(sg.getEndRes());
1136 jGroup.setName(sg.getName());
1137 if (groupRefs.containsKey(sg))
1139 // group has references so set its ID field
1140 jGroup.setId(groupRefs.get(sg));
1144 if (sg.cs.conservationApplied())
1146 jGroup.setConsThreshold(sg.cs.getConservationInc());
1148 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1150 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1154 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1157 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1159 jGroup.setColour("AnnotationColourGradient");
1160 jGroup.setAnnotationColours(constructAnnotationColours(
1161 (jalview.schemes.AnnotationColourGradient) sg.cs,
1164 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1166 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1170 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1173 jGroup.setPidThreshold(sg.cs.getThreshold());
1176 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1177 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1178 jGroup.setDisplayText(sg.getDisplayText());
1179 jGroup.setColourText(sg.getColourText());
1180 jGroup.setTextCol1(sg.textColour.getRGB());
1181 jGroup.setTextCol2(sg.textColour2.getRGB());
1182 jGroup.setTextColThreshold(sg.thresholdTextColour);
1183 jGroup.setShowUnconserved(sg.getShowNonconserved());
1184 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1185 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1186 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1187 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1188 for (SequenceI seq : sg.getSequences())
1190 jGroup.addSeq(seqHash(seq));
1194 jms.setJGroup(groups);
1198 // /////////SAVE VIEWPORT
1199 Viewport view = new Viewport();
1200 view.setTitle(ap.alignFrame.getTitle());
1201 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1202 av.getSequenceSetId()));
1203 view.setId(av.getViewId());
1204 if (av.getCodingComplement() != null)
1206 view.setComplementId(av.getCodingComplement().getViewId());
1208 view.setViewName(av.viewName);
1209 view.setGatheredViews(av.isGatherViewsHere());
1211 Rectangle size = ap.av.getExplodedGeometry();
1212 Rectangle position = size;
1215 size = ap.alignFrame.getBounds();
1216 if (av.getCodingComplement() != null)
1218 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1226 view.setXpos(position.x);
1227 view.setYpos(position.y);
1229 view.setWidth(size.width);
1230 view.setHeight(size.height);
1232 view.setStartRes(av.startRes);
1233 view.setStartSeq(av.startSeq);
1235 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1237 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1240 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1242 AnnotationColours ac = constructAnnotationColours(
1243 (jalview.schemes.AnnotationColourGradient) av
1244 .getGlobalColourScheme(),
1247 view.setAnnotationColours(ac);
1248 view.setBgColour("AnnotationColourGradient");
1252 view.setBgColour(ColourSchemeProperty.getColourName(av
1253 .getGlobalColourScheme()));
1256 ColourSchemeI cs = av.getGlobalColourScheme();
1260 if (cs.conservationApplied())
1262 view.setConsThreshold(cs.getConservationInc());
1263 if (cs instanceof jalview.schemes.UserColourScheme)
1265 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1269 if (cs instanceof ResidueColourScheme)
1271 view.setPidThreshold(cs.getThreshold());
1275 view.setConservationSelected(av.getConservationSelected());
1276 view.setPidSelected(av.getAbovePIDThreshold());
1277 view.setFontName(av.font.getName());
1278 view.setFontSize(av.font.getSize());
1279 view.setFontStyle(av.font.getStyle());
1280 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1281 view.setRenderGaps(av.isRenderGaps());
1282 view.setShowAnnotation(av.isShowAnnotation());
1283 view.setShowBoxes(av.getShowBoxes());
1284 view.setShowColourText(av.getColourText());
1285 view.setShowFullId(av.getShowJVSuffix());
1286 view.setRightAlignIds(av.isRightAlignIds());
1287 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1288 view.setShowText(av.getShowText());
1289 view.setShowUnconserved(av.getShowUnconserved());
1290 view.setWrapAlignment(av.getWrapAlignment());
1291 view.setTextCol1(av.getTextColour().getRGB());
1292 view.setTextCol2(av.getTextColour2().getRGB());
1293 view.setTextColThreshold(av.getThresholdTextColour());
1294 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1295 view.setShowSequenceLogo(av.isShowSequenceLogo());
1296 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1297 view.setShowGroupConsensus(av.isShowGroupConsensus());
1298 view.setShowGroupConservation(av.isShowGroupConservation());
1299 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1300 view.setShowDbRefTooltip(av.isShowDBRefs());
1301 view.setFollowHighlight(av.isFollowHighlight());
1302 view.setFollowSelection(av.followSelection);
1303 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1304 if (av.getFeaturesDisplayed() != null)
1306 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1308 String[] renderOrder = ap.getSeqPanel().seqCanvas
1309 .getFeatureRenderer().getRenderOrder()
1310 .toArray(new String[0]);
1312 Vector<String> settingsAdded = new Vector<String>();
1313 if (renderOrder != null)
1315 for (String featureType : renderOrder)
1317 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1318 .getFeatureRenderer()
1319 .getFeatureStyle(featureType);
1320 Setting setting = new Setting();
1321 setting.setType(featureType);
1322 if (!fcol.isSimpleColour())
1324 setting.setColour(fcol.getMaxColour().getRGB());
1325 setting.setMincolour(fcol.getMinColour().getRGB());
1326 setting.setMin(fcol.getMin());
1327 setting.setMax(fcol.getMax());
1328 setting.setColourByLabel(fcol.isColourByLabel());
1329 setting.setAutoScale(fcol.isAutoScaled());
1330 setting.setThreshold(fcol.getThreshold());
1331 // -1 = No threshold, 0 = Below, 1 = Above
1332 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1333 : (fcol.isBelowThreshold() ? 0 : -1));
1337 setting.setColour(fcol.getColour().getRGB());
1340 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1342 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1343 .getOrder(featureType);
1346 setting.setOrder(rorder);
1348 fs.addSetting(setting);
1349 settingsAdded.addElement(featureType);
1353 // is groups actually supposed to be a map here ?
1354 Iterator<String> en = ap.getSeqPanel().seqCanvas
1355 .getFeatureRenderer()
1356 .getFeatureGroups().iterator();
1357 Vector<String> groupsAdded = new Vector<String>();
1358 while (en.hasNext())
1360 String grp = en.next();
1361 if (groupsAdded.contains(grp))
1365 Group g = new Group();
1367 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1368 .getFeatureRenderer().checkGroupVisibility(grp, false))
1371 groupsAdded.addElement(grp);
1373 jms.setFeatureSettings(fs);
1376 if (av.hasHiddenColumns())
1378 if (av.getColumnSelection() == null
1379 || av.getColumnSelection().getHiddenColumns() == null)
1381 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1385 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1388 int[] region = av.getColumnSelection().getHiddenColumns()
1390 HiddenColumns hc = new HiddenColumns();
1391 hc.setStart(region[0]);
1392 hc.setEnd(region[1]);
1393 view.addHiddenColumns(hc);
1397 if (calcIdSet.size() > 0)
1399 for (String calcId : calcIdSet)
1401 if (calcId.trim().length() > 0)
1403 CalcIdParam cidp = createCalcIdParam(calcId, av);
1404 // Some calcIds have no parameters.
1407 view.addCalcIdParam(cidp);
1413 jms.addViewport(view);
1415 object.setJalviewModelSequence(jms);
1416 object.getVamsasModel().addSequenceSet(vamsasSet);
1418 if (jout != null && fileName != null)
1420 // We may not want to write the object to disk,
1421 // eg we can copy the alignViewport to a new view object
1422 // using save and then load
1425 System.out.println("Writing jar entry " + fileName);
1426 JarEntry entry = new JarEntry(fileName);
1427 jout.putNextEntry(entry);
1428 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1430 Marshaller marshaller = new Marshaller(pout);
1431 marshaller.marshal(object);
1434 } catch (Exception ex)
1436 // TODO: raise error in GUI if marshalling failed.
1437 ex.printStackTrace();
1444 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1445 * for each viewer, with
1447 * <li>viewer geometry (position, size, split pane divider location)</li>
1448 * <li>index of the selected structure in the viewer (currently shows gapped
1450 * <li>the id of the annotation holding RNA secondary structure</li>
1451 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1453 * Varna viewer state is also written out (in native Varna XML) to separate
1454 * project jar entries. A separate entry is written for each RNA structure
1455 * displayed, with the naming convention
1457 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1465 * @param storeDataset
1467 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1468 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1469 boolean storeDataset)
1471 if (Desktop.desktop == null)
1475 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1476 for (int f = frames.length - 1; f > -1; f--)
1478 if (frames[f] instanceof AppVarna)
1480 AppVarna varna = (AppVarna) frames[f];
1482 * link the sequence to every viewer that is showing it and is linked to
1483 * its alignment panel
1485 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1487 String viewId = varna.getViewId();
1488 RnaViewer rna = new RnaViewer();
1489 rna.setViewId(viewId);
1490 rna.setTitle(varna.getTitle());
1491 rna.setXpos(varna.getX());
1492 rna.setYpos(varna.getY());
1493 rna.setWidth(varna.getWidth());
1494 rna.setHeight(varna.getHeight());
1495 rna.setDividerLocation(varna.getDividerLocation());
1496 rna.setSelectedRna(varna.getSelectedIndex());
1497 jseq.addRnaViewer(rna);
1500 * Store each Varna panel's state once in the project per sequence.
1501 * First time through only (storeDataset==false)
1503 // boolean storeSessions = false;
1504 // String sequenceViewId = viewId + seqsToIds.get(jds);
1505 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1507 // viewIds.add(sequenceViewId);
1508 // storeSessions = true;
1510 for (RnaModel model : varna.getModels())
1512 if (model.seq == jds)
1515 * VARNA saves each view (sequence or alignment secondary
1516 * structure, gapped or trimmed) as a separate XML file
1518 String jarEntryName = rnaSessions.get(model);
1519 if (jarEntryName == null)
1522 String varnaStateFile = varna.getStateInfo(model.rna);
1523 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1524 copyFileToJar(jout, varnaStateFile, jarEntryName);
1525 rnaSessions.put(model, jarEntryName);
1527 SecondaryStructure ss = new SecondaryStructure();
1528 String annotationId = varna.getAnnotation(jds).annotationId;
1529 ss.setAnnotationId(annotationId);
1530 ss.setViewerState(jarEntryName);
1531 ss.setGapped(model.gapped);
1532 ss.setTitle(model.title);
1533 rna.addSecondaryStructure(ss);
1542 * Copy the contents of a file to a new entry added to the output jar
1546 * @param jarEntryName
1548 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1549 String jarEntryName)
1551 DataInputStream dis = null;
1554 File file = new File(infilePath);
1555 if (file.exists() && jout != null)
1557 dis = new DataInputStream(new FileInputStream(file));
1558 byte[] data = new byte[(int) file.length()];
1559 dis.readFully(data);
1560 writeJarEntry(jout, jarEntryName, data);
1562 } catch (Exception ex)
1564 ex.printStackTrace();
1572 } catch (IOException e)
1581 * Write the data to a new entry of given name in the output jar file
1584 * @param jarEntryName
1586 * @throws IOException
1588 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1589 byte[] data) throws IOException
1593 System.out.println("Writing jar entry " + jarEntryName);
1594 jout.putNextEntry(new JarEntry(jarEntryName));
1595 DataOutputStream dout = new DataOutputStream(jout);
1596 dout.write(data, 0, data.length);
1603 * Save the state of a structure viewer
1608 * the archive XML element under which to save the state
1611 * @param matchedFile
1615 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1616 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1617 String matchedFile, StructureViewerBase viewFrame)
1619 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1622 * Look for any bindings for this viewer to the PDB file of interest
1623 * (including part matches excluding chain id)
1625 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1627 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1628 final String pdbId = pdbentry.getId();
1629 if (!pdbId.equals(entry.getId())
1630 && !(entry.getId().length() > 4 && entry.getId()
1631 .toLowerCase().startsWith(pdbId.toLowerCase())))
1634 * not interested in a binding to a different PDB entry here
1638 if (matchedFile == null)
1640 matchedFile = pdbentry.getFile();
1642 else if (!matchedFile.equals(pdbentry.getFile()))
1645 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1646 + pdbentry.getFile());
1650 // can get at it if the ID
1651 // match is ambiguous (e.g.
1654 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1656 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1657 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1659 StructureState state = new StructureState();
1660 state.setVisible(true);
1661 state.setXpos(viewFrame.getX());
1662 state.setYpos(viewFrame.getY());
1663 state.setWidth(viewFrame.getWidth());
1664 state.setHeight(viewFrame.getHeight());
1665 final String viewId = viewFrame.getViewId();
1666 state.setViewId(viewId);
1667 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1668 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1669 state.setColourByJmol(viewFrame.isColouredByViewer());
1670 state.setType(viewFrame.getViewerType().toString());
1671 pdb.addStructureState(state);
1678 private AnnotationColours constructAnnotationColours(
1679 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1680 JalviewModelSequence jms)
1682 AnnotationColours ac = new AnnotationColours();
1683 ac.setAboveThreshold(acg.getAboveThreshold());
1684 ac.setThreshold(acg.getAnnotationThreshold());
1685 ac.setAnnotation(acg.getAnnotation());
1686 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1688 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1693 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1697 ac.setMaxColour(acg.getMaxColour().getRGB());
1698 ac.setMinColour(acg.getMinColour().getRGB());
1699 ac.setPerSequence(acg.isSeqAssociated());
1700 ac.setPredefinedColours(acg.isPredefinedColours());
1704 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1705 IdentityHashMap<SequenceGroup, String> groupRefs,
1706 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1707 SequenceSet vamsasSet)
1710 for (int i = 0; i < aa.length; i++)
1712 Annotation an = new Annotation();
1714 AlignmentAnnotation annotation = aa[i];
1715 if (annotation.annotationId != null)
1717 annotationIds.put(annotation.annotationId, annotation);
1720 an.setId(annotation.annotationId);
1722 an.setVisible(annotation.visible);
1724 an.setDescription(annotation.description);
1726 if (annotation.sequenceRef != null)
1728 // 2.9 JAL-1781 xref on sequence id rather than name
1729 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1731 if (annotation.groupRef != null)
1733 String groupIdr = groupRefs.get(annotation.groupRef);
1734 if (groupIdr == null)
1736 // make a locally unique String
1738 annotation.groupRef,
1739 groupIdr = ("" + System.currentTimeMillis()
1740 + annotation.groupRef.getName() + groupRefs
1743 an.setGroupRef(groupIdr.toString());
1746 // store all visualization attributes for annotation
1747 an.setGraphHeight(annotation.graphHeight);
1748 an.setCentreColLabels(annotation.centreColLabels);
1749 an.setScaleColLabels(annotation.scaleColLabel);
1750 an.setShowAllColLabels(annotation.showAllColLabels);
1751 an.setBelowAlignment(annotation.belowAlignment);
1753 if (annotation.graph > 0)
1756 an.setGraphType(annotation.graph);
1757 an.setGraphGroup(annotation.graphGroup);
1758 if (annotation.getThreshold() != null)
1760 ThresholdLine line = new ThresholdLine();
1761 line.setLabel(annotation.getThreshold().label);
1762 line.setValue(annotation.getThreshold().value);
1763 line.setColour(annotation.getThreshold().colour.getRGB());
1764 an.setThresholdLine(line);
1772 an.setLabel(annotation.label);
1774 if (annotation == av.getAlignmentQualityAnnot()
1775 || annotation == av.getAlignmentConservationAnnotation()
1776 || annotation == av.getAlignmentConsensusAnnotation()
1777 || annotation.autoCalculated)
1779 // new way of indicating autocalculated annotation -
1780 an.setAutoCalculated(annotation.autoCalculated);
1782 if (annotation.hasScore())
1784 an.setScore(annotation.getScore());
1787 if (annotation.getCalcId() != null)
1789 calcIdSet.add(annotation.getCalcId());
1790 an.setCalcId(annotation.getCalcId());
1792 if (annotation.hasProperties())
1794 for (String pr : annotation.getProperties())
1796 Property prop = new Property();
1798 prop.setValue(annotation.getProperty(pr));
1799 an.addProperty(prop);
1803 AnnotationElement ae;
1804 if (annotation.annotations != null)
1806 an.setScoreOnly(false);
1807 for (int a = 0; a < annotation.annotations.length; a++)
1809 if ((annotation == null) || (annotation.annotations[a] == null))
1814 ae = new AnnotationElement();
1815 if (annotation.annotations[a].description != null)
1817 ae.setDescription(annotation.annotations[a].description);
1819 if (annotation.annotations[a].displayCharacter != null)
1821 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1824 if (!Float.isNaN(annotation.annotations[a].value))
1826 ae.setValue(annotation.annotations[a].value);
1830 if (annotation.annotations[a].secondaryStructure > ' ')
1832 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1836 if (annotation.annotations[a].colour != null
1837 && annotation.annotations[a].colour != java.awt.Color.black)
1839 ae.setColour(annotation.annotations[a].colour.getRGB());
1842 an.addAnnotationElement(ae);
1843 if (annotation.autoCalculated)
1845 // only write one non-null entry into the annotation row -
1846 // sufficient to get the visualization attributes necessary to
1854 an.setScoreOnly(true);
1856 if (!storeDS || (storeDS && !annotation.autoCalculated))
1858 // skip autocalculated annotation - these are only provided for
1860 vamsasSet.addAnnotation(an);
1866 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1868 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1869 if (settings != null)
1871 CalcIdParam vCalcIdParam = new CalcIdParam();
1872 vCalcIdParam.setCalcId(calcId);
1873 vCalcIdParam.addServiceURL(settings.getServiceURI());
1874 // generic URI allowing a third party to resolve another instance of the
1875 // service used for this calculation
1876 for (String urls : settings.getServiceURLs())
1878 vCalcIdParam.addServiceURL(urls);
1880 vCalcIdParam.setVersion("1.0");
1881 if (settings.getPreset() != null)
1883 WsParamSetI setting = settings.getPreset();
1884 vCalcIdParam.setName(setting.getName());
1885 vCalcIdParam.setDescription(setting.getDescription());
1889 vCalcIdParam.setName("");
1890 vCalcIdParam.setDescription("Last used parameters");
1892 // need to be able to recover 1) settings 2) user-defined presets or
1893 // recreate settings from preset 3) predefined settings provided by
1894 // service - or settings that can be transferred (or discarded)
1895 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1897 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1898 // todo - decide if updateImmediately is needed for any projects.
1900 return vCalcIdParam;
1905 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1908 if (calcIdParam.getVersion().equals("1.0"))
1910 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1911 .getPreferredServiceFor(calcIdParam.getServiceURL());
1912 if (service != null)
1914 WsParamSetI parmSet = null;
1917 parmSet = service.getParamStore().parseServiceParameterFile(
1918 calcIdParam.getName(), calcIdParam.getDescription(),
1919 calcIdParam.getServiceURL(),
1920 calcIdParam.getParameters().replace("|\\n|", "\n"));
1921 } catch (IOException x)
1923 warn("Couldn't parse parameter data for "
1924 + calcIdParam.getCalcId(), x);
1927 List<ArgumentI> argList = null;
1928 if (calcIdParam.getName().length() > 0)
1930 parmSet = service.getParamStore()
1931 .getPreset(calcIdParam.getName());
1932 if (parmSet != null)
1934 // TODO : check we have a good match with settings in AACon -
1935 // otherwise we'll need to create a new preset
1940 argList = parmSet.getArguments();
1943 AAConSettings settings = new AAConSettings(
1944 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1945 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1946 calcIdParam.isNeedsUpdate());
1951 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1955 throw new Error(MessageManager.formatMessage(
1956 "error.unsupported_version_calcIdparam",
1957 new Object[] { calcIdParam.toString() }));
1961 * External mapping between jalview objects and objects yielding a valid and
1962 * unique object ID string. This is null for normal Jalview project IO, but
1963 * non-null when a jalview project is being read or written as part of a
1966 IdentityHashMap jv2vobj = null;
1969 * Construct a unique ID for jvobj using either existing bindings or if none
1970 * exist, the result of the hashcode call for the object.
1973 * jalview data object
1974 * @return unique ID for referring to jvobj
1976 private String makeHashCode(Object jvobj, String altCode)
1978 if (jv2vobj != null)
1980 Object id = jv2vobj.get(jvobj);
1983 return id.toString();
1985 // check string ID mappings
1986 if (jvids2vobj != null && jvobj instanceof String)
1988 id = jvids2vobj.get(jvobj);
1992 return id.toString();
1994 // give up and warn that something has gone wrong
1995 warn("Cannot find ID for object in external mapping : " + jvobj);
2001 * return local jalview object mapped to ID, if it exists
2005 * @return null or object bound to idcode
2007 private Object retrieveExistingObj(String idcode)
2009 if (idcode != null && vobj2jv != null)
2011 return vobj2jv.get(idcode);
2017 * binding from ID strings from external mapping table to jalview data model
2020 private Hashtable vobj2jv;
2022 private Sequence createVamsasSequence(String id, SequenceI jds)
2024 return createVamsasSequence(true, id, jds, null);
2027 private Sequence createVamsasSequence(boolean recurse, String id,
2028 SequenceI jds, SequenceI parentseq)
2030 Sequence vamsasSeq = new Sequence();
2031 vamsasSeq.setId(id);
2032 vamsasSeq.setName(jds.getName());
2033 vamsasSeq.setSequence(jds.getSequenceAsString());
2034 vamsasSeq.setDescription(jds.getDescription());
2035 jalview.datamodel.DBRefEntry[] dbrefs = null;
2036 if (jds.getDatasetSequence() != null)
2038 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2039 if (jds.getDatasetSequence().getDBRefs() != null)
2041 dbrefs = jds.getDatasetSequence().getDBRefs();
2046 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
2047 // dataset sequences only
2048 dbrefs = jds.getDBRefs();
2052 for (int d = 0; d < dbrefs.length; d++)
2054 DBRef dbref = new DBRef();
2055 dbref.setSource(dbrefs[d].getSource());
2056 dbref.setVersion(dbrefs[d].getVersion());
2057 dbref.setAccessionId(dbrefs[d].getAccessionId());
2058 if (dbrefs[d].hasMap())
2060 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2062 dbref.setMapping(mp);
2064 vamsasSeq.addDBRef(dbref);
2070 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2071 SequenceI parentseq, SequenceI jds, boolean recurse)
2074 if (jmp.getMap() != null)
2078 jalview.util.MapList mlst = jmp.getMap();
2079 List<int[]> r = mlst.getFromRanges();
2080 for (int[] range : r)
2082 MapListFrom mfrom = new MapListFrom();
2083 mfrom.setStart(range[0]);
2084 mfrom.setEnd(range[1]);
2085 mp.addMapListFrom(mfrom);
2087 r = mlst.getToRanges();
2088 for (int[] range : r)
2090 MapListTo mto = new MapListTo();
2091 mto.setStart(range[0]);
2092 mto.setEnd(range[1]);
2093 mp.addMapListTo(mto);
2095 mp.setMapFromUnit(mlst.getFromRatio());
2096 mp.setMapToUnit(mlst.getToRatio());
2097 if (jmp.getTo() != null)
2099 MappingChoice mpc = new MappingChoice();
2101 && (parentseq != jmp.getTo() || parentseq
2102 .getDatasetSequence() != jmp.getTo()))
2104 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2110 SequenceI ps = null;
2111 if (parentseq != jmp.getTo()
2112 && parentseq.getDatasetSequence() != jmp.getTo())
2114 // chaining dbref rather than a handshaking one
2115 jmpid = seqHash(ps = jmp.getTo());
2119 jmpid = seqHash(ps = parentseq);
2121 mpc.setDseqFor(jmpid);
2122 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2124 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2125 seqRefIds.put(mpc.getDseqFor(), ps);
2129 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2132 mp.setMappingChoice(mpc);
2138 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2139 List<UserColourScheme> userColours, JalviewModelSequence jms)
2142 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2143 boolean newucs = false;
2144 if (!userColours.contains(ucs))
2146 userColours.add(ucs);
2149 id = "ucs" + userColours.indexOf(ucs);
2152 // actually create the scheme's entry in the XML model
2153 java.awt.Color[] colours = ucs.getColours();
2154 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2155 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2157 for (int i = 0; i < colours.length; i++)
2159 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2160 col.setName(ResidueProperties.aa[i]);
2161 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2162 jbucs.addColour(col);
2164 if (ucs.getLowerCaseColours() != null)
2166 colours = ucs.getLowerCaseColours();
2167 for (int i = 0; i < colours.length; i++)
2169 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2170 col.setName(ResidueProperties.aa[i].toLowerCase());
2171 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2172 jbucs.addColour(col);
2177 uc.setUserColourScheme(jbucs);
2178 jms.addUserColours(uc);
2184 jalview.schemes.UserColourScheme getUserColourScheme(
2185 JalviewModelSequence jms, String id)
2187 UserColours[] uc = jms.getUserColours();
2188 UserColours colours = null;
2190 for (int i = 0; i < uc.length; i++)
2192 if (uc[i].getId().equals(id))
2200 java.awt.Color[] newColours = new java.awt.Color[24];
2202 for (int i = 0; i < 24; i++)
2204 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2205 .getUserColourScheme().getColour(i).getRGB(), 16));
2208 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2211 if (colours.getUserColourScheme().getColourCount() > 24)
2213 newColours = new java.awt.Color[23];
2214 for (int i = 0; i < 23; i++)
2216 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2217 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2219 ucs.setLowerCaseColours(newColours);
2226 * contains last error message (if any) encountered by XML loader.
2228 String errorMessage = null;
2231 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2232 * exceptions are raised during project XML parsing
2234 public boolean attemptversion1parse = true;
2237 * Load a jalview project archive from a jar file
2240 * - HTTP URL or filename
2242 public AlignFrame loadJalviewAlign(final String file)
2245 jalview.gui.AlignFrame af = null;
2249 // create list to store references for any new Jmol viewers created
2250 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2251 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2252 // Workaround is to make sure caller implements the JarInputStreamProvider
2254 // so we can re-open the jar input stream for each entry.
2256 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2257 af = loadJalviewAlign(jprovider);
2259 } catch (MalformedURLException e)
2261 errorMessage = "Invalid URL format for '" + file + "'";
2267 SwingUtilities.invokeAndWait(new Runnable()
2272 setLoadingFinishedForNewStructureViewers();
2275 } catch (Exception x)
2277 System.err.println("Error loading alignment: " + x.getMessage());
2283 private jarInputStreamProvider createjarInputStreamProvider(
2284 final String file) throws MalformedURLException
2287 errorMessage = null;
2288 uniqueSetSuffix = null;
2290 viewportsAdded.clear();
2291 frefedSequence = null;
2293 if (file.startsWith("http://"))
2295 url = new URL(file);
2297 final URL _url = url;
2298 return new jarInputStreamProvider()
2302 public JarInputStream getJarInputStream() throws IOException
2306 return new JarInputStream(_url.openStream());
2310 return new JarInputStream(new FileInputStream(file));
2315 public String getFilename()
2323 * Recover jalview session from a jalview project archive. Caller may
2324 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2325 * themselves. Any null fields will be initialised with default values,
2326 * non-null fields are left alone.
2331 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2333 errorMessage = null;
2334 if (uniqueSetSuffix == null)
2336 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2338 if (seqRefIds == null)
2342 AlignFrame af = null, _af = null;
2343 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2344 final String file = jprovider.getFilename();
2347 JarInputStream jin = null;
2348 JarEntry jarentry = null;
2353 jin = jprovider.getJarInputStream();
2354 for (int i = 0; i < entryCount; i++)
2356 jarentry = jin.getNextJarEntry();
2359 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2361 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2362 JalviewModel object = new JalviewModel();
2364 Unmarshaller unmar = new Unmarshaller(object);
2365 unmar.setValidation(false);
2366 object = (JalviewModel) unmar.unmarshal(in);
2367 if (true) // !skipViewport(object))
2369 _af = loadFromObject(object, file, true, jprovider);
2370 if (object.getJalviewModelSequence().getViewportCount() > 0)
2373 if (af.viewport.isGatherViewsHere())
2375 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2381 else if (jarentry != null)
2383 // Some other file here.
2386 } while (jarentry != null);
2387 resolveFrefedSequences();
2388 } catch (IOException ex)
2390 ex.printStackTrace();
2391 errorMessage = "Couldn't locate Jalview XML file : " + file;
2392 System.err.println("Exception whilst loading jalview XML file : "
2394 } catch (Exception ex)
2396 System.err.println("Parsing as Jalview Version 2 file failed.");
2397 ex.printStackTrace(System.err);
2398 if (attemptversion1parse)
2400 // Is Version 1 Jar file?
2403 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2404 } catch (Exception ex2)
2406 System.err.println("Exception whilst loading as jalviewXMLV1:");
2407 ex2.printStackTrace();
2411 if (Desktop.instance != null)
2413 Desktop.instance.stopLoading();
2417 System.out.println("Successfully loaded archive file");
2420 ex.printStackTrace();
2422 System.err.println("Exception whilst loading jalview XML file : "
2424 } catch (OutOfMemoryError e)
2426 // Don't use the OOM Window here
2427 errorMessage = "Out of memory loading jalview XML file";
2428 System.err.println("Out of memory whilst loading jalview XML file");
2429 e.printStackTrace();
2432 if (Desktop.instance != null)
2434 Desktop.instance.stopLoading();
2438 * Regather multiple views (with the same sequence set id) to the frame (if
2439 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2440 * views instead of separate frames. Note this doesn't restore a state where
2441 * some expanded views in turn have tabbed views - the last "first tab" read
2442 * in will play the role of gatherer for all.
2444 for (AlignFrame fr : gatherToThisFrame.values())
2446 Desktop.instance.gatherViews(fr);
2449 restoreSplitFrames();
2451 if (errorMessage != null)
2459 * Try to reconstruct and display SplitFrame windows, where each contains
2460 * complementary dna and protein alignments. Done by pairing up AlignFrame
2461 * objects (created earlier) which have complementary viewport ids associated.
2463 protected void restoreSplitFrames()
2465 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2466 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2467 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2470 * Identify the DNA alignments
2472 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2475 AlignFrame af = candidate.getValue();
2476 if (af.getViewport().getAlignment().isNucleotide())
2478 dna.put(candidate.getKey().getId(), af);
2483 * Try to match up the protein complements
2485 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2488 AlignFrame af = candidate.getValue();
2489 if (!af.getViewport().getAlignment().isNucleotide())
2491 String complementId = candidate.getKey().getComplementId();
2492 // only non-null complements should be in the Map
2493 if (complementId != null && dna.containsKey(complementId))
2495 final AlignFrame dnaFrame = dna.get(complementId);
2496 SplitFrame sf = createSplitFrame(dnaFrame, af);
2497 addedToSplitFrames.add(dnaFrame);
2498 addedToSplitFrames.add(af);
2499 if (af.viewport.isGatherViewsHere())
2508 * Open any that we failed to pair up (which shouldn't happen!) as
2509 * standalone AlignFrame's.
2511 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2514 AlignFrame af = candidate.getValue();
2515 if (!addedToSplitFrames.contains(af))
2517 Viewport view = candidate.getKey();
2518 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2520 System.err.println("Failed to restore view " + view.getTitle()
2521 + " to split frame");
2526 * Gather back into tabbed views as flagged.
2528 for (SplitFrame sf : gatherTo)
2530 Desktop.instance.gatherViews(sf);
2533 splitFrameCandidates.clear();
2537 * Construct and display one SplitFrame holding DNA and protein alignments.
2540 * @param proteinFrame
2543 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2544 AlignFrame proteinFrame)
2546 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2547 String title = MessageManager.getString("label.linked_view_title");
2548 int width = (int) dnaFrame.getBounds().getWidth();
2549 int height = (int) (dnaFrame.getBounds().getHeight()
2550 + proteinFrame.getBounds().getHeight() + 50);
2553 * SplitFrame location is saved to both enclosed frames
2555 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2556 Desktop.addInternalFrame(splitFrame, title, width, height);
2559 * And compute cDNA consensus (couldn't do earlier with consensus as
2560 * mappings were not yet present)
2562 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2568 * check errorMessage for a valid error message and raise an error box in the
2569 * GUI or write the current errorMessage to stderr and then clear the error
2572 protected void reportErrors()
2574 reportErrors(false);
2577 protected void reportErrors(final boolean saving)
2579 if (errorMessage != null)
2581 final String finalErrorMessage = errorMessage;
2584 javax.swing.SwingUtilities.invokeLater(new Runnable()
2589 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2590 finalErrorMessage, "Error "
2591 + (saving ? "saving" : "loading")
2592 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2598 System.err.println("Problem loading Jalview file: " + errorMessage);
2601 errorMessage = null;
2604 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2607 * when set, local views will be updated from view stored in JalviewXML
2608 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2609 * sync if this is set to true.
2611 private final boolean updateLocalViews = false;
2614 * Returns the path to a temporary file holding the PDB file for the given PDB
2615 * id. The first time of asking, searches for a file of that name in the
2616 * Jalview project jar, and copies it to a new temporary file. Any repeat
2617 * requests just return the path to the file previously created.
2623 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2625 if (alreadyLoadedPDB.containsKey(pdbId))
2627 return alreadyLoadedPDB.get(pdbId).toString();
2630 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2631 if (tempFile != null)
2633 alreadyLoadedPDB.put(pdbId, tempFile);
2639 * Copies the jar entry of given name to a new temporary file and returns the
2640 * path to the file, or null if the entry is not found.
2643 * @param jarEntryName
2645 * a prefix for the temporary file name, must be at least three
2649 protected String copyJarEntry(jarInputStreamProvider jprovider,
2650 String jarEntryName, String prefix)
2652 BufferedReader in = null;
2653 PrintWriter out = null;
2657 JarInputStream jin = jprovider.getJarInputStream();
2659 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2660 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2661 * FileInputStream(jprovider)); }
2664 JarEntry entry = null;
2667 entry = jin.getNextJarEntry();
2668 } while (entry != null && !entry.getName().equals(jarEntryName));
2671 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2672 File outFile = File.createTempFile(prefix, ".tmp");
2673 outFile.deleteOnExit();
2674 out = new PrintWriter(new FileOutputStream(outFile));
2677 while ((data = in.readLine()) != null)
2682 String t = outFile.getAbsolutePath();
2687 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2689 } catch (Exception ex)
2691 ex.printStackTrace();
2699 } catch (IOException e)
2713 private class JvAnnotRow
2715 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2722 * persisted version of annotation row from which to take vis properties
2724 public jalview.datamodel.AlignmentAnnotation template;
2727 * original position of the annotation row in the alignment
2733 * Load alignment frame from jalview XML DOM object
2738 * filename source string
2739 * @param loadTreesAndStructures
2740 * when false only create Viewport
2742 * data source provider
2743 * @return alignment frame created from view stored in DOM
2745 AlignFrame loadFromObject(JalviewModel object, String file,
2746 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2748 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2749 Sequence[] vamsasSeq = vamsasSet.getSequence();
2751 JalviewModelSequence jms = object.getJalviewModelSequence();
2753 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2756 // ////////////////////////////////
2759 List<SequenceI> hiddenSeqs = null;
2762 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2764 boolean multipleView = false;
2765 SequenceI referenceseqForView = null;
2766 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2767 int vi = 0; // counter in vamsasSeq array
2768 for (int i = 0; i < jseqs.length; i++)
2770 String seqId = jseqs[i].getId();
2772 SequenceI tmpSeq = seqRefIds.get(seqId);
2775 if (!incompleteSeqs.containsKey(seqId))
2777 // may not need this check, but keep it for at least 2.9,1 release
2778 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2781 .println("Warning JAL-2154 regression: updating start/end for sequence "
2782 + tmpSeq.toString());
2785 incompleteSeqs.remove(seqId);
2787 tmpSeq.setStart(jseqs[i].getStart());
2788 tmpSeq.setEnd(jseqs[i].getEnd());
2789 tmpseqs.add(tmpSeq);
2790 multipleView = true;
2794 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2795 vamsasSeq[vi].getSequence());
2796 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2797 tmpSeq.setStart(jseqs[i].getStart());
2798 tmpSeq.setEnd(jseqs[i].getEnd());
2799 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2800 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2801 tmpseqs.add(tmpSeq);
2805 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2807 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2810 if (jseqs[i].getHidden())
2812 if (hiddenSeqs == null)
2814 hiddenSeqs = new ArrayList<SequenceI>();
2817 hiddenSeqs.add(tmpSeq);
2822 // Create the alignment object from the sequence set
2823 // ///////////////////////////////
2824 SequenceI[] orderedSeqs = tmpseqs
2825 .toArray(new SequenceI[tmpseqs.size()]);
2827 AlignmentI al = new Alignment(orderedSeqs);
2829 if (referenceseqForView != null)
2831 al.setSeqrep(referenceseqForView);
2833 // / Add the alignment properties
2834 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2836 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2837 al.setProperty(ssp.getKey(), ssp.getValue());
2841 // SequenceFeatures are added to the DatasetSequence,
2842 // so we must create or recover the dataset before loading features
2843 // ///////////////////////////////
2844 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2846 // older jalview projects do not have a dataset id.
2847 al.setDataset(null);
2851 // recover dataset - passing on flag indicating if this a 'viewless'
2852 // sequence set (a.k.a. a stored dataset for the project)
2853 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2854 .getViewportCount() == 0);
2856 // ///////////////////////////////
2858 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2861 // load sequence features, database references and any associated PDB
2862 // structures for the alignment
2863 for (int i = 0; i < vamsasSeq.length; i++)
2865 if (jseqs[i].getFeaturesCount() > 0)
2867 Features[] features = jseqs[i].getFeatures();
2868 for (int f = 0; f < features.length; f++)
2870 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2871 features[f].getType(), features[f].getDescription(),
2872 features[f].getStatus(), features[f].getBegin(),
2873 features[f].getEnd(), features[f].getFeatureGroup());
2875 sf.setScore(features[f].getScore());
2876 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2878 OtherData keyValue = features[f].getOtherData(od);
2879 if (keyValue.getKey().startsWith("LINK"))
2881 sf.addLink(keyValue.getValue());
2885 sf.setValue(keyValue.getKey(), keyValue.getValue());
2890 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2893 if (vamsasSeq[i].getDBRefCount() > 0)
2895 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2897 if (jseqs[i].getPdbidsCount() > 0)
2899 Pdbids[] ids = jseqs[i].getPdbids();
2900 for (int p = 0; p < ids.length; p++)
2902 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2903 entry.setId(ids[p].getId());
2904 if (ids[p].getType() != null)
2906 if (ids[p].getType().equalsIgnoreCase("PDB"))
2908 entry.setType(PDBEntry.Type.PDB);
2912 entry.setType(PDBEntry.Type.FILE);
2915 if (ids[p].getFile() != null)
2917 if (!pdbloaded.containsKey(ids[p].getFile()))
2919 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2923 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2926 StructureSelectionManager.getStructureSelectionManager(
2927 Desktop.instance).registerPDBEntry(entry);
2928 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2932 } // end !multipleview
2934 // ///////////////////////////////
2935 // LOAD SEQUENCE MAPPINGS
2937 if (vamsasSet.getAlcodonFrameCount() > 0)
2939 // TODO Potentially this should only be done once for all views of an
2941 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2942 for (int i = 0; i < alc.length; i++)
2944 AlignedCodonFrame cf = new AlignedCodonFrame();
2945 if (alc[i].getAlcodMapCount() > 0)
2947 AlcodMap[] maps = alc[i].getAlcodMap();
2948 for (int m = 0; m < maps.length; m++)
2950 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2952 jalview.datamodel.Mapping mapping = null;
2953 // attach to dna sequence reference.
2954 if (maps[m].getMapping() != null)
2956 mapping = addMapping(maps[m].getMapping());
2958 if (dnaseq != null && mapping.getTo() != null)
2960 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2965 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
2969 al.addCodonFrame(cf);
2974 // ////////////////////////////////
2976 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2979 * store any annotations which forward reference a group's ID
2981 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2983 if (vamsasSet.getAnnotationCount() > 0)
2985 Annotation[] an = vamsasSet.getAnnotation();
2987 for (int i = 0; i < an.length; i++)
2989 Annotation annotation = an[i];
2992 * test if annotation is automatically calculated for this view only
2994 boolean autoForView = false;
2995 if (annotation.getLabel().equals("Quality")
2996 || annotation.getLabel().equals("Conservation")
2997 || annotation.getLabel().equals("Consensus"))
2999 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3001 if (!annotation.hasAutoCalculated())
3003 annotation.setAutoCalculated(true);
3007 || (annotation.hasAutoCalculated() && annotation
3008 .isAutoCalculated()))
3010 // remove ID - we don't recover annotation from other views for
3011 // view-specific annotation
3012 annotation.setId(null);
3015 // set visiblity for other annotation in this view
3016 String annotationId = annotation.getId();
3017 if (annotationId != null && annotationIds.containsKey(annotationId))
3019 AlignmentAnnotation jda = annotationIds.get(annotationId);
3020 // in principle Visible should always be true for annotation displayed
3021 // in multiple views
3022 if (annotation.hasVisible())
3024 jda.visible = annotation.getVisible();
3027 al.addAnnotation(jda);
3031 // Construct new annotation from model.
3032 AnnotationElement[] ae = annotation.getAnnotationElement();
3033 jalview.datamodel.Annotation[] anot = null;
3034 java.awt.Color firstColour = null;
3036 if (!annotation.getScoreOnly())
3038 anot = new jalview.datamodel.Annotation[al.getWidth()];
3039 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3041 anpos = ae[aa].getPosition();
3043 if (anpos >= anot.length)
3048 anot[anpos] = new jalview.datamodel.Annotation(
3050 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3051 (ae[aa].getSecondaryStructure() == null || ae[aa]
3052 .getSecondaryStructure().length() == 0) ? ' '
3053 : ae[aa].getSecondaryStructure().charAt(0),
3057 // JBPNote: Consider verifying dataflow for IO of secondary
3058 // structure annotation read from Stockholm files
3059 // this was added to try to ensure that
3060 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3062 // anot[ae[aa].getPosition()].displayCharacter = "";
3064 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3065 if (firstColour == null)
3067 firstColour = anot[anpos].colour;
3071 jalview.datamodel.AlignmentAnnotation jaa = null;
3073 if (annotation.getGraph())
3075 float llim = 0, hlim = 0;
3076 // if (autoForView || an[i].isAutoCalculated()) {
3079 jaa = new jalview.datamodel.AlignmentAnnotation(
3080 annotation.getLabel(), annotation.getDescription(), anot,
3081 llim, hlim, annotation.getGraphType());
3083 jaa.graphGroup = annotation.getGraphGroup();
3084 jaa._linecolour = firstColour;
3085 if (annotation.getThresholdLine() != null)
3087 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3088 .getThresholdLine().getValue(), annotation
3089 .getThresholdLine().getLabel(), new java.awt.Color(
3090 annotation.getThresholdLine().getColour())));
3093 if (autoForView || annotation.isAutoCalculated())
3095 // Hardwire the symbol display line to ensure that labels for
3096 // histograms are displayed
3102 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3103 an[i].getDescription(), anot);
3104 jaa._linecolour = firstColour;
3106 // register new annotation
3107 if (an[i].getId() != null)
3109 annotationIds.put(an[i].getId(), jaa);
3110 jaa.annotationId = an[i].getId();
3112 // recover sequence association
3113 String sequenceRef = an[i].getSequenceRef();
3114 if (sequenceRef != null)
3116 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3117 SequenceI sequence = seqRefIds.get(sequenceRef);
3118 if (sequence == null)
3120 // in pre-2.9 projects sequence ref is to sequence name
3121 sequence = al.findName(sequenceRef);
3123 if (sequence != null)
3125 jaa.createSequenceMapping(sequence, 1, true);
3126 sequence.addAlignmentAnnotation(jaa);
3129 // and make a note of any group association
3130 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3132 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3133 .get(an[i].getGroupRef());
3136 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3137 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3142 if (an[i].hasScore())
3144 jaa.setScore(an[i].getScore());
3146 if (an[i].hasVisible())
3148 jaa.visible = an[i].getVisible();
3151 if (an[i].hasCentreColLabels())
3153 jaa.centreColLabels = an[i].getCentreColLabels();
3156 if (an[i].hasScaleColLabels())
3158 jaa.scaleColLabel = an[i].getScaleColLabels();
3160 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3162 // newer files have an 'autoCalculated' flag and store calculation
3163 // state in viewport properties
3164 jaa.autoCalculated = true; // means annotation will be marked for
3165 // update at end of load.
3167 if (an[i].hasGraphHeight())
3169 jaa.graphHeight = an[i].getGraphHeight();
3171 if (an[i].hasBelowAlignment())
3173 jaa.belowAlignment = an[i].isBelowAlignment();
3175 jaa.setCalcId(an[i].getCalcId());
3176 if (an[i].getPropertyCount() > 0)
3178 for (jalview.schemabinding.version2.Property prop : an[i]
3181 jaa.setProperty(prop.getName(), prop.getValue());
3184 if (jaa.autoCalculated)
3186 autoAlan.add(new JvAnnotRow(i, jaa));
3189 // if (!autoForView)
3191 // add autocalculated group annotation and any user created annotation
3193 al.addAnnotation(jaa);
3197 // ///////////////////////
3199 // Create alignment markup and styles for this view
3200 if (jms.getJGroupCount() > 0)
3202 JGroup[] groups = jms.getJGroup();
3203 boolean addAnnotSchemeGroup = false;
3204 for (int i = 0; i < groups.length; i++)
3206 JGroup jGroup = groups[i];
3207 ColourSchemeI cs = null;
3208 if (jGroup.getColour() != null)
3210 if (jGroup.getColour().startsWith("ucs"))
3212 cs = getUserColourScheme(jms, jGroup.getColour());
3214 else if (jGroup.getColour().equals("AnnotationColourGradient")
3215 && jGroup.getAnnotationColours() != null)
3217 addAnnotSchemeGroup = true;
3222 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3227 cs.setThreshold(jGroup.getPidThreshold(), true);
3231 Vector<SequenceI> seqs = new Vector<SequenceI>();
3233 for (int s = 0; s < jGroup.getSeqCount(); s++)
3235 String seqId = jGroup.getSeq(s) + "";
3236 SequenceI ts = seqRefIds.get(seqId);
3240 seqs.addElement(ts);
3244 if (seqs.size() < 1)
3249 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3250 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3251 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3253 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3255 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3256 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3257 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3258 .isShowUnconserved() : false);
3259 sg.thresholdTextColour = jGroup.getTextColThreshold();
3260 if (jGroup.hasShowConsensusHistogram())
3262 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3265 if (jGroup.hasShowSequenceLogo())
3267 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3269 if (jGroup.hasNormaliseSequenceLogo())
3271 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3273 if (jGroup.hasIgnoreGapsinConsensus())
3275 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3277 if (jGroup.getConsThreshold() != 0)
3279 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3280 "All", ResidueProperties.propHash, 3,
3281 sg.getSequences(null), 0, sg.getWidth() - 1);
3283 c.verdict(false, 25);
3284 sg.cs.setConservation(c);
3287 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3289 // re-instate unique group/annotation row reference
3290 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3294 for (AlignmentAnnotation jaa : jaal)
3297 if (jaa.autoCalculated)
3299 // match up and try to set group autocalc alignment row for this
3301 if (jaa.label.startsWith("Consensus for "))
3303 sg.setConsensus(jaa);
3305 // match up and try to set group autocalc alignment row for this
3307 if (jaa.label.startsWith("Conservation for "))
3309 sg.setConservationRow(jaa);
3316 if (addAnnotSchemeGroup)
3318 // reconstruct the annotation colourscheme
3319 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3320 null, al, jms, false);
3326 // only dataset in this model, so just return.
3329 // ///////////////////////////////
3332 // If we just load in the same jar file again, the sequenceSetId
3333 // will be the same, and we end up with multiple references
3334 // to the same sequenceSet. We must modify this id on load
3335 // so that each load of the file gives a unique id
3336 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3337 String viewId = (view.getId() == null ? null : view.getId()
3339 AlignFrame af = null;
3340 AlignViewport av = null;
3341 // now check to see if we really need to create a new viewport.
3342 if (multipleView && viewportsAdded.size() == 0)
3344 // We recovered an alignment for which a viewport already exists.
3345 // TODO: fix up any settings necessary for overlaying stored state onto
3346 // state recovered from another document. (may not be necessary).
3347 // we may need a binding from a viewport in memory to one recovered from
3349 // and then recover its containing af to allow the settings to be applied.
3350 // TODO: fix for vamsas demo
3352 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3354 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3355 if (seqsetobj != null)
3357 if (seqsetobj instanceof String)
3359 uniqueSeqSetId = (String) seqsetobj;
3361 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3367 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3373 * indicate that annotation colours are applied across all groups (pre
3374 * Jalview 2.8.1 behaviour)
3376 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3377 "2.8.1", object.getVersion());
3379 AlignmentPanel ap = null;
3380 boolean isnewview = true;
3383 // Check to see if this alignment already has a view id == viewId
3384 jalview.gui.AlignmentPanel views[] = Desktop
3385 .getAlignmentPanels(uniqueSeqSetId);
3386 if (views != null && views.length > 0)
3388 for (int v = 0; v < views.length; v++)
3390 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3392 // recover the existing alignpanel, alignframe, viewport
3393 af = views[v].alignFrame;
3396 // TODO: could even skip resetting view settings if we don't want to
3397 // change the local settings from other jalview processes
3406 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3407 uniqueSeqSetId, viewId, autoAlan);
3413 * Load any trees, PDB structures and viewers
3415 * Not done if flag is false (when this method is used for New View)
3417 if (loadTreesAndStructures)
3419 loadTrees(jms, view, af, av, ap);
3420 loadPDBStructures(jprovider, jseqs, af, ap);
3421 loadRnaViewers(jprovider, jseqs, ap);
3423 // and finally return.
3428 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3429 * panel is restored from separate jar entries, two (gapped and trimmed) per
3430 * sequence and secondary structure.
3432 * Currently each viewer shows just one sequence and structure (gapped and
3433 * trimmed), however this method is designed to support multiple sequences or
3434 * structures in viewers if wanted in future.
3440 private void loadRnaViewers(jarInputStreamProvider jprovider,
3441 JSeq[] jseqs, AlignmentPanel ap)
3444 * scan the sequences for references to viewers; create each one the first
3445 * time it is referenced, add Rna models to existing viewers
3447 for (JSeq jseq : jseqs)
3449 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3451 RnaViewer viewer = jseq.getRnaViewer(i);
3452 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3453 uniqueSetSuffix, ap);
3455 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3457 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3458 SequenceI seq = seqRefIds.get(jseq.getId());
3459 AlignmentAnnotation ann = this.annotationIds.get(ss
3460 .getAnnotationId());
3463 * add the structure to the Varna display (with session state copied
3464 * from the jar to a temporary file)
3466 boolean gapped = ss.isGapped();
3467 String rnaTitle = ss.getTitle();
3468 String sessionState = ss.getViewerState();
3469 String tempStateFile = copyJarEntry(jprovider, sessionState,
3471 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3472 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3474 appVarna.setInitialSelection(viewer.getSelectedRna());
3480 * Locate and return an already instantiated matching AppVarna, or create one
3484 * @param viewIdSuffix
3488 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3489 String viewIdSuffix, AlignmentPanel ap)
3492 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3493 * if load is repeated
3495 String postLoadId = viewer.getViewId() + viewIdSuffix;
3496 for (JInternalFrame frame : getAllFrames())
3498 if (frame instanceof AppVarna)
3500 AppVarna varna = (AppVarna) frame;
3501 if (postLoadId.equals(varna.getViewId()))
3503 // this viewer is already instantiated
3504 // could in future here add ap as another 'parent' of the
3505 // AppVarna window; currently just 1-to-many
3512 * viewer not found - make it
3514 RnaViewerModel model = new RnaViewerModel(postLoadId,
3515 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3516 viewer.getWidth(), viewer.getHeight(),
3517 viewer.getDividerLocation());
3518 AppVarna varna = new AppVarna(model, ap);
3524 * Load any saved trees
3532 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3533 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3535 // TODO result of automated refactoring - are all these parameters needed?
3538 for (int t = 0; t < jms.getTreeCount(); t++)
3541 Tree tree = jms.getTree(t);
3543 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3546 tp = af.ShowNewickTree(
3547 new jalview.io.NewickFile(tree.getNewick()),
3548 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3549 tree.getXpos(), tree.getYpos());
3550 if (tree.getId() != null)
3552 // perhaps bind the tree id to something ?
3557 // update local tree attributes ?
3558 // TODO: should check if tp has been manipulated by user - if so its
3559 // settings shouldn't be modified
3560 tp.setTitle(tree.getTitle());
3561 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3562 .getWidth(), tree.getHeight()));
3563 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3566 tp.treeCanvas.av = av; // af.viewport;
3567 tp.treeCanvas.ap = ap; // af.alignPanel;
3572 warn("There was a problem recovering stored Newick tree: \n"
3573 + tree.getNewick());
3577 tp.fitToWindow.setState(tree.getFitToWindow());
3578 tp.fitToWindow_actionPerformed(null);
3580 if (tree.getFontName() != null)
3582 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3583 .getFontStyle(), tree.getFontSize()));
3587 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3588 .getFontStyle(), tree.getFontSize()));
3591 tp.showPlaceholders(tree.getMarkUnlinked());
3592 tp.showBootstrap(tree.getShowBootstrap());
3593 tp.showDistances(tree.getShowDistances());
3595 tp.treeCanvas.threshold = tree.getThreshold();
3597 if (tree.getCurrentTree())
3599 af.viewport.setCurrentTree(tp.getTree());
3603 } catch (Exception ex)
3605 ex.printStackTrace();
3610 * Load and link any saved structure viewers.
3617 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3618 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3621 * Run through all PDB ids on the alignment, and collect mappings between
3622 * distinct view ids and all sequences referring to that view.
3624 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3626 for (int i = 0; i < jseqs.length; i++)
3628 if (jseqs[i].getPdbidsCount() > 0)
3630 Pdbids[] ids = jseqs[i].getPdbids();
3631 for (int p = 0; p < ids.length; p++)
3633 final int structureStateCount = ids[p].getStructureStateCount();
3634 for (int s = 0; s < structureStateCount; s++)
3636 // check to see if we haven't already created this structure view
3637 final StructureState structureState = ids[p]
3638 .getStructureState(s);
3639 String sviewid = (structureState.getViewId() == null) ? null
3640 : structureState.getViewId() + uniqueSetSuffix;
3641 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3642 // Originally : ids[p].getFile()
3643 // : TODO: verify external PDB file recovery still works in normal
3644 // jalview project load
3645 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3646 jpdb.setId(ids[p].getId());
3648 int x = structureState.getXpos();
3649 int y = structureState.getYpos();
3650 int width = structureState.getWidth();
3651 int height = structureState.getHeight();
3653 // Probably don't need to do this anymore...
3654 // Desktop.desktop.getComponentAt(x, y);
3655 // TODO: NOW: check that this recovers the PDB file correctly.
3656 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3657 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3659 if (sviewid == null)
3661 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3664 if (!structureViewers.containsKey(sviewid))
3666 structureViewers.put(sviewid,
3667 new StructureViewerModel(x, y, width, height, false,
3668 false, true, structureState.getViewId(),
3669 structureState.getType()));
3670 // Legacy pre-2.7 conversion JAL-823 :
3671 // do not assume any view has to be linked for colour by
3675 // assemble String[] { pdb files }, String[] { id for each
3676 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3677 // seqs_file 2}, boolean[] {
3678 // linkAlignPanel,superposeWithAlignpanel}} from hash
3679 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3680 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3681 | (structureState.hasAlignwithAlignPanel() ? structureState
3682 .getAlignwithAlignPanel() : false));
3685 * Default colour by linked panel to false if not specified (e.g.
3686 * for pre-2.7 projects)
3688 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3689 colourWithAlignPanel |= (structureState
3690 .hasColourwithAlignPanel() ? structureState
3691 .getColourwithAlignPanel() : false);
3692 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3695 * Default colour by viewer to true if not specified (e.g. for
3698 boolean colourByViewer = jmoldat.isColourByViewer();
3699 colourByViewer &= structureState.hasColourByJmol() ? structureState
3700 .getColourByJmol() : true;
3701 jmoldat.setColourByViewer(colourByViewer);
3703 if (jmoldat.getStateData().length() < structureState
3704 .getContent().length())
3707 jmoldat.setStateData(structureState.getContent());
3710 if (ids[p].getFile() != null)
3712 File mapkey = new File(ids[p].getFile());
3713 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3714 if (seqstrmaps == null)
3716 jmoldat.getFileData().put(
3718 seqstrmaps = jmoldat.new StructureData(pdbFile,
3721 if (!seqstrmaps.getSeqList().contains(seq))
3723 seqstrmaps.getSeqList().add(seq);
3729 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");
3736 // Instantiate the associated structure views
3737 for (Entry<String, StructureViewerModel> entry : structureViewers
3742 createOrLinkStructureViewer(entry, af, ap, jprovider);
3743 } catch (Exception e)
3745 System.err.println("Error loading structure viewer: "
3747 // failed - try the next one
3759 protected void createOrLinkStructureViewer(
3760 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3761 AlignmentPanel ap, jarInputStreamProvider jprovider)
3763 final StructureViewerModel stateData = viewerData.getValue();
3766 * Search for any viewer windows already open from other alignment views
3767 * that exactly match the stored structure state
3769 StructureViewerBase comp = findMatchingViewer(viewerData);
3773 linkStructureViewer(ap, comp, stateData);
3778 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3779 * "viewer_"+stateData.viewId
3781 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3783 createChimeraViewer(viewerData, af, jprovider);
3788 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3790 createJmolViewer(viewerData, af, jprovider);
3795 * Create a new Chimera viewer.
3801 protected void createChimeraViewer(
3802 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3803 jarInputStreamProvider jprovider)
3805 StructureViewerModel data = viewerData.getValue();
3806 String chimeraSessionFile = data.getStateData();
3809 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3811 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3812 * 'uniquified' sviewid used to reconstruct the viewer here
3814 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3815 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3818 Set<Entry<File, StructureData>> fileData = data.getFileData()
3820 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3821 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3822 for (Entry<File, StructureData> pdb : fileData)
3824 String filePath = pdb.getValue().getFilePath();
3825 String pdbId = pdb.getValue().getPdbId();
3826 // pdbs.add(new PDBEntry(filePath, pdbId));
3827 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3828 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3829 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3833 boolean colourByChimera = data.isColourByViewer();
3834 boolean colourBySequence = data.isColourWithAlignPanel();
3836 // TODO use StructureViewer as a factory here, see JAL-1761
3837 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3838 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3840 String newViewId = viewerData.getKey();
3842 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3843 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3844 colourBySequence, newViewId);
3845 cvf.setSize(data.getWidth(), data.getHeight());
3846 cvf.setLocation(data.getX(), data.getY());
3850 * Create a new Jmol window. First parse the Jmol state to translate filenames
3851 * loaded into the view, and record the order in which files are shown in the
3852 * Jmol view, so we can add the sequence mappings in same order.
3858 protected void createJmolViewer(
3859 final Entry<String, StructureViewerModel> viewerData,
3860 AlignFrame af, jarInputStreamProvider jprovider)
3862 final StructureViewerModel svattrib = viewerData.getValue();
3863 String state = svattrib.getStateData();
3866 * Pre-2.9: state element value is the Jmol state string
3868 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3871 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3873 state = readJarEntry(jprovider,
3874 getViewerJarEntryName(svattrib.getViewId()));
3877 List<String> pdbfilenames = new ArrayList<String>();
3878 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3879 List<String> pdbids = new ArrayList<String>();
3880 StringBuilder newFileLoc = new StringBuilder(64);
3881 int cp = 0, ncp, ecp;
3882 Map<File, StructureData> oldFiles = svattrib.getFileData();
3883 while ((ncp = state.indexOf("load ", cp)) > -1)
3887 // look for next filename in load statement
3888 newFileLoc.append(state.substring(cp,
3889 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3890 String oldfilenam = state.substring(ncp,
3891 ecp = state.indexOf("\"", ncp));
3892 // recover the new mapping data for this old filename
3893 // have to normalize filename - since Jmol and jalview do
3895 // translation differently.
3896 StructureData filedat = oldFiles.get(new File(oldfilenam));
3897 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3898 pdbfilenames.add(filedat.getFilePath());
3899 pdbids.add(filedat.getPdbId());
3900 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3901 newFileLoc.append("\"");
3902 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3903 // look for next file statement.
3904 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3908 // just append rest of state
3909 newFileLoc.append(state.substring(cp));
3913 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3914 newFileLoc = new StringBuilder(state);
3915 newFileLoc.append("; load append ");
3916 for (File id : oldFiles.keySet())
3918 // add this and any other pdb files that should be present in
3920 StructureData filedat = oldFiles.get(id);
3921 newFileLoc.append(filedat.getFilePath());
3922 pdbfilenames.add(filedat.getFilePath());
3923 pdbids.add(filedat.getPdbId());
3924 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3925 newFileLoc.append(" \"");
3926 newFileLoc.append(filedat.getFilePath());
3927 newFileLoc.append("\"");
3930 newFileLoc.append(";");
3933 if (newFileLoc.length() == 0)
3937 int histbug = newFileLoc.indexOf("history = ");
3941 * change "history = [true|false];" to "history = [1|0];"
3944 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3945 String val = (diff == -1) ? null : newFileLoc
3946 .substring(histbug, diff);
3947 if (val != null && val.length() >= 4)
3949 if (val.contains("e")) // eh? what can it be?
3951 if (val.trim().equals("true"))
3959 newFileLoc.replace(histbug, diff, val);
3964 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3966 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3967 final SequenceI[][] sq = seqmaps
3968 .toArray(new SequenceI[seqmaps.size()][]);
3969 final String fileloc = newFileLoc.toString();
3970 final String sviewid = viewerData.getKey();
3971 final AlignFrame alf = af;
3972 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3973 svattrib.getWidth(), svattrib.getHeight());
3976 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3981 JalviewStructureDisplayI sview = null;
3984 sview = new StructureViewer(alf.alignPanel
3985 .getStructureSelectionManager()).createView(
3986 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3987 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3988 addNewStructureViewer(sview);
3989 } catch (OutOfMemoryError ex)
3991 new OOMWarning("restoring structure view for PDB id " + id,
3992 (OutOfMemoryError) ex.getCause());
3993 if (sview != null && sview.isVisible())
3995 sview.closeViewer(false);
3996 sview.setVisible(false);
4002 } catch (InvocationTargetException ex)
4004 warn("Unexpected error when opening Jmol view.", ex);
4006 } catch (InterruptedException e)
4008 // e.printStackTrace();
4014 * Generates a name for the entry in the project jar file to hold state
4015 * information for a structure viewer
4020 protected String getViewerJarEntryName(String viewId)
4022 return VIEWER_PREFIX + viewId;
4026 * Returns any open frame that matches given structure viewer data. The match
4027 * is based on the unique viewId, or (for older project versions) the frame's
4033 protected StructureViewerBase findMatchingViewer(
4034 Entry<String, StructureViewerModel> viewerData)
4036 final String sviewid = viewerData.getKey();
4037 final StructureViewerModel svattrib = viewerData.getValue();
4038 StructureViewerBase comp = null;
4039 JInternalFrame[] frames = getAllFrames();
4040 for (JInternalFrame frame : frames)
4042 if (frame instanceof StructureViewerBase)
4045 * Post jalview 2.4 schema includes structure view id
4048 && ((StructureViewerBase) frame).getViewId()
4051 comp = (StructureViewerBase) frame;
4052 break; // break added in 2.9
4055 * Otherwise test for matching position and size of viewer frame
4057 else if (frame.getX() == svattrib.getX()
4058 && frame.getY() == svattrib.getY()
4059 && frame.getHeight() == svattrib.getHeight()
4060 && frame.getWidth() == svattrib.getWidth())
4062 comp = (StructureViewerBase) frame;
4063 // no break in faint hope of an exact match on viewId
4071 * Link an AlignmentPanel to an existing structure viewer.
4076 * @param useinViewerSuperpos
4077 * @param usetoColourbyseq
4078 * @param viewerColouring
4080 protected void linkStructureViewer(AlignmentPanel ap,
4081 StructureViewerBase viewer, StructureViewerModel stateData)
4083 // NOTE: if the jalview project is part of a shared session then
4084 // view synchronization should/could be done here.
4086 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4087 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4088 final boolean viewerColouring = stateData.isColourByViewer();
4089 Map<File, StructureData> oldFiles = stateData.getFileData();
4092 * Add mapping for sequences in this view to an already open viewer
4094 final AAStructureBindingModel binding = viewer.getBinding();
4095 for (File id : oldFiles.keySet())
4097 // add this and any other pdb files that should be present in the
4099 StructureData filedat = oldFiles.get(id);
4100 String pdbFile = filedat.getFilePath();
4101 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4102 binding.getSsm().setMapping(seq, null, pdbFile,
4103 jalview.io.AppletFormatAdapter.FILE);
4104 binding.addSequenceForStructFile(pdbFile, seq);
4106 // and add the AlignmentPanel's reference to the view panel
4107 viewer.addAlignmentPanel(ap);
4108 if (useinViewerSuperpos)
4110 viewer.useAlignmentPanelForSuperposition(ap);
4114 viewer.excludeAlignmentPanelForSuperposition(ap);
4116 if (usetoColourbyseq)
4118 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4122 viewer.excludeAlignmentPanelForColourbyseq(ap);
4127 * Get all frames within the Desktop.
4131 protected JInternalFrame[] getAllFrames()
4133 JInternalFrame[] frames = null;
4134 // TODO is this necessary - is it safe - risk of hanging?
4139 frames = Desktop.desktop.getAllFrames();
4140 } catch (ArrayIndexOutOfBoundsException e)
4142 // occasional No such child exceptions are thrown here...
4146 } catch (InterruptedException f)
4150 } while (frames == null);
4155 * Answers true if 'version' is equal to or later than 'supported', where each
4156 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4157 * changes. Development and test values for 'version' are leniently treated
4161 * - minimum version we are comparing against
4163 * - version of data being processsed
4166 public static boolean isVersionStringLaterThan(String supported,
4169 if (supported == null || version == null
4170 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4171 || version.equalsIgnoreCase("Test")
4172 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4174 System.err.println("Assuming project file with "
4175 + (version == null ? "null" : version)
4176 + " is compatible with Jalview version " + supported);
4181 return StringUtils.compareVersions(version, supported, "b") >= 0;
4185 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4187 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4189 if (newStructureViewers != null)
4191 sview.getBinding().setFinishedLoadingFromArchive(false);
4192 newStructureViewers.add(sview);
4196 protected void setLoadingFinishedForNewStructureViewers()
4198 if (newStructureViewers != null)
4200 for (JalviewStructureDisplayI sview : newStructureViewers)
4202 sview.getBinding().setFinishedLoadingFromArchive(true);
4204 newStructureViewers.clear();
4205 newStructureViewers = null;
4209 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4210 List<SequenceI> hiddenSeqs, AlignmentI al,
4211 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4212 String viewId, List<JvAnnotRow> autoAlan)
4214 AlignFrame af = null;
4215 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4216 uniqueSeqSetId, viewId);
4218 af.setFileName(file, "Jalview");
4220 for (int i = 0; i < JSEQ.length; i++)
4222 af.viewport.setSequenceColour(af.viewport.getAlignment()
4223 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4228 af.getViewport().setColourByReferenceSeq(true);
4229 af.getViewport().setDisplayReferenceSeq(true);
4232 af.viewport.setGatherViewsHere(view.getGatheredViews());
4234 if (view.getSequenceSetId() != null)
4236 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4238 af.viewport.setSequenceSetId(uniqueSeqSetId);
4241 // propagate shared settings to this new view
4242 af.viewport.setHistoryList(av.getHistoryList());
4243 af.viewport.setRedoList(av.getRedoList());
4247 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4249 // TODO: check if this method can be called repeatedly without
4250 // side-effects if alignpanel already registered.
4251 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4253 // apply Hidden regions to view.
4254 if (hiddenSeqs != null)
4256 for (int s = 0; s < JSEQ.length; s++)
4258 SequenceGroup hidden = new SequenceGroup();
4259 boolean isRepresentative = false;
4260 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4262 isRepresentative = true;
4263 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4264 .getHiddenSequences(r));
4265 hidden.addSequence(sequenceToHide, false);
4266 // remove from hiddenSeqs list so we don't try to hide it twice
4267 hiddenSeqs.remove(sequenceToHide);
4269 if (isRepresentative)
4271 SequenceI representativeSequence = al.getSequenceAt(s);
4272 hidden.addSequence(representativeSequence, false);
4273 af.viewport.hideRepSequences(representativeSequence, hidden);
4277 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4279 af.viewport.hideSequence(hseqs);
4282 // recover view properties and display parameters
4283 if (view.getViewName() != null)
4285 af.viewport.viewName = view.getViewName();
4286 af.setInitialTabVisible();
4288 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4291 af.viewport.setShowAnnotation(view.getShowAnnotation());
4292 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4294 af.viewport.setColourText(view.getShowColourText());
4296 af.viewport.setConservationSelected(view.getConservationSelected());
4297 af.viewport.setShowJVSuffix(view.getShowFullId());
4298 af.viewport.setRightAlignIds(view.getRightAlignIds());
4299 af.viewport.setFont(
4300 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4301 .getFontSize()), true);
4302 ViewStyleI vs = af.viewport.getViewStyle();
4303 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4304 af.viewport.setViewStyle(vs);
4305 // TODO: allow custom charWidth/Heights to be restored by updating them
4306 // after setting font - which means set above to false
4307 af.viewport.setRenderGaps(view.getRenderGaps());
4308 af.viewport.setWrapAlignment(view.getWrapAlignment());
4309 af.viewport.setShowAnnotation(view.getShowAnnotation());
4311 af.viewport.setShowBoxes(view.getShowBoxes());
4313 af.viewport.setShowText(view.getShowText());
4315 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4316 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4317 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4318 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4319 .isShowUnconserved() : false);
4320 af.viewport.setStartRes(view.getStartRes());
4321 af.viewport.setStartSeq(view.getStartSeq());
4322 af.alignPanel.updateLayout();
4323 ColourSchemeI cs = null;
4324 // apply colourschemes
4325 if (view.getBgColour() != null)
4327 if (view.getBgColour().startsWith("ucs"))
4329 cs = getUserColourScheme(jms, view.getBgColour());
4331 else if (view.getBgColour().startsWith("Annotation"))
4333 AnnotationColours viewAnnColour = view.getAnnotationColours();
4334 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4341 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4346 cs.setThreshold(view.getPidThreshold(), true);
4347 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4351 af.viewport.setGlobalColourScheme(cs);
4352 af.viewport.setColourAppliesToAllGroups(false);
4354 if (view.getConservationSelected() && cs != null)
4356 cs.setConservationInc(view.getConsThreshold());
4359 af.changeColour(cs);
4361 af.viewport.setColourAppliesToAllGroups(true);
4363 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4365 if (view.hasCentreColumnLabels())
4367 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4369 if (view.hasIgnoreGapsinConsensus())
4371 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4374 if (view.hasFollowHighlight())
4376 af.viewport.setFollowHighlight(view.getFollowHighlight());
4378 if (view.hasFollowSelection())
4380 af.viewport.followSelection = view.getFollowSelection();
4382 if (view.hasShowConsensusHistogram())
4384 af.viewport.setShowConsensusHistogram(view
4385 .getShowConsensusHistogram());
4389 af.viewport.setShowConsensusHistogram(true);
4391 if (view.hasShowSequenceLogo())
4393 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4397 af.viewport.setShowSequenceLogo(false);
4399 if (view.hasNormaliseSequenceLogo())
4401 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4403 if (view.hasShowDbRefTooltip())
4405 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4407 if (view.hasShowNPfeatureTooltip())
4409 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4411 if (view.hasShowGroupConsensus())
4413 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4417 af.viewport.setShowGroupConsensus(false);
4419 if (view.hasShowGroupConservation())
4421 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4425 af.viewport.setShowGroupConservation(false);
4428 // recover featre settings
4429 if (jms.getFeatureSettings() != null)
4431 FeaturesDisplayed fdi;
4432 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4433 String[] renderOrder = new String[jms.getFeatureSettings()
4434 .getSettingCount()];
4435 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4436 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4438 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4440 Setting setting = jms.getFeatureSettings().getSetting(fs);
4441 if (setting.hasMincolour())
4443 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4444 new Color(setting.getMincolour()), new Color(
4445 setting.getColour()), setting.getMin(),
4446 setting.getMax()) : new FeatureColour(new Color(
4447 setting.getMincolour()), new Color(setting.getColour()),
4449 if (setting.hasThreshold())
4451 gc.setThreshold(setting.getThreshold());
4452 int threshstate = setting.getThreshstate();
4453 // -1 = None, 0 = Below, 1 = Above threshold
4454 if (threshstate == 0)
4456 gc.setBelowThreshold(true);
4458 else if (threshstate == 1)
4460 gc.setAboveThreshold(true);
4463 gc.setAutoScaled(true); // default
4464 if (setting.hasAutoScale())
4466 gc.setAutoScaled(setting.getAutoScale());
4468 if (setting.hasColourByLabel())
4470 gc.setColourByLabel(setting.getColourByLabel());
4472 // and put in the feature colour table.
4473 featureColours.put(setting.getType(), gc);
4477 featureColours.put(setting.getType(), new FeatureColour(
4478 new Color(setting.getColour())));
4480 renderOrder[fs] = setting.getType();
4481 if (setting.hasOrder())
4483 featureOrder.put(setting.getType(), setting.getOrder());
4487 featureOrder.put(setting.getType(), new Float(fs
4488 / jms.getFeatureSettings().getSettingCount()));
4490 if (setting.getDisplay())
4492 fdi.setVisible(setting.getType());
4495 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4496 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4498 Group grp = jms.getFeatureSettings().getGroup(gs);
4499 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4501 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4502 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4503 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4504 FeatureRendererSettings frs = new FeatureRendererSettings(
4505 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4506 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4507 .transferSettings(frs);
4511 if (view.getHiddenColumnsCount() > 0)
4513 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4515 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4516 .getHiddenColumns(c).getEnd() // +1
4520 if (view.getCalcIdParam() != null)
4522 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4524 if (calcIdParam != null)
4526 if (recoverCalcIdParam(calcIdParam, af.viewport))
4531 warn("Couldn't recover parameters for "
4532 + calcIdParam.getCalcId());
4537 af.setMenusFromViewport(af.viewport);
4539 // TODO: we don't need to do this if the viewport is aready visible.
4541 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4542 * has a 'cdna/protein complement' view, in which case save it in order to
4543 * populate a SplitFrame once all views have been read in.
4545 String complementaryViewId = view.getComplementId();
4546 if (complementaryViewId == null)
4548 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4550 // recompute any autoannotation
4551 af.alignPanel.updateAnnotation(false, true);
4552 reorderAutoannotation(af, al, autoAlan);
4553 af.alignPanel.alignmentChanged();
4557 splitFrameCandidates.put(view, af);
4562 private ColourSchemeI constructAnnotationColour(
4563 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4564 JalviewModelSequence jms, boolean checkGroupAnnColour)
4566 boolean propagateAnnColour = false;
4567 ColourSchemeI cs = null;
4568 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4569 if (checkGroupAnnColour && al.getGroups() != null
4570 && al.getGroups().size() > 0)
4572 // pre 2.8.1 behaviour
4573 // check to see if we should transfer annotation colours
4574 propagateAnnColour = true;
4575 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4577 if (sg.cs instanceof AnnotationColourGradient)
4579 propagateAnnColour = false;
4583 // int find annotation
4584 if (annAlignment.getAlignmentAnnotation() != null)
4586 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4588 if (annAlignment.getAlignmentAnnotation()[i].label
4589 .equals(viewAnnColour.getAnnotation()))
4591 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4593 annAlignment.getAlignmentAnnotation()[i]
4594 .setThreshold(new jalview.datamodel.GraphLine(
4595 viewAnnColour.getThreshold(), "Threshold",
4596 java.awt.Color.black)
4601 if (viewAnnColour.getColourScheme().equals("None"))
4603 cs = new AnnotationColourGradient(
4604 annAlignment.getAlignmentAnnotation()[i],
4605 new java.awt.Color(viewAnnColour.getMinColour()),
4606 new java.awt.Color(viewAnnColour.getMaxColour()),
4607 viewAnnColour.getAboveThreshold());
4609 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4611 cs = new AnnotationColourGradient(
4612 annAlignment.getAlignmentAnnotation()[i],
4613 getUserColourScheme(jms,
4614 viewAnnColour.getColourScheme()),
4615 viewAnnColour.getAboveThreshold());
4619 cs = new AnnotationColourGradient(
4620 annAlignment.getAlignmentAnnotation()[i],
4621 ColourSchemeProperty.getColour(al,
4622 viewAnnColour.getColourScheme()),
4623 viewAnnColour.getAboveThreshold());
4625 if (viewAnnColour.hasPerSequence())
4627 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4630 if (viewAnnColour.hasPredefinedColours())
4632 ((AnnotationColourGradient) cs)
4633 .setPredefinedColours(viewAnnColour
4634 .isPredefinedColours());
4636 if (propagateAnnColour && al.getGroups() != null)
4638 // Also use these settings for all the groups
4639 for (int g = 0; g < al.getGroups().size(); g++)
4641 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4649 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4650 * new AnnotationColourGradient(
4651 * annAlignment.getAlignmentAnnotation()[i], new
4652 * java.awt.Color(viewAnnColour. getMinColour()), new
4653 * java.awt.Color(viewAnnColour. getMaxColour()),
4654 * viewAnnColour.getAboveThreshold()); } else
4657 sg.cs = new AnnotationColourGradient(
4658 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4659 viewAnnColour.getAboveThreshold());
4660 if (cs instanceof AnnotationColourGradient)
4662 if (viewAnnColour.hasPerSequence())
4664 ((AnnotationColourGradient) cs)
4665 .setSeqAssociated(viewAnnColour.isPerSequence());
4667 if (viewAnnColour.hasPredefinedColours())
4669 ((AnnotationColourGradient) cs)
4670 .setPredefinedColours(viewAnnColour
4671 .isPredefinedColours());
4687 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4688 List<JvAnnotRow> autoAlan)
4690 // copy over visualization settings for autocalculated annotation in the
4692 if (al.getAlignmentAnnotation() != null)
4695 * Kludge for magic autoannotation names (see JAL-811)
4697 String[] magicNames = new String[] { "Consensus", "Quality",
4699 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4700 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4701 for (String nm : magicNames)
4703 visan.put(nm, nullAnnot);
4705 for (JvAnnotRow auan : autoAlan)
4707 visan.put(auan.template.label
4708 + (auan.template.getCalcId() == null ? "" : "\t"
4709 + auan.template.getCalcId()), auan);
4711 int hSize = al.getAlignmentAnnotation().length;
4712 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4713 // work through any autoCalculated annotation already on the view
4714 // removing it if it should be placed in a different location on the
4715 // annotation panel.
4716 List<String> remains = new ArrayList<String>(visan.keySet());
4717 for (int h = 0; h < hSize; h++)
4719 jalview.datamodel.AlignmentAnnotation jalan = al
4720 .getAlignmentAnnotation()[h];
4721 if (jalan.autoCalculated)
4724 JvAnnotRow valan = visan.get(k = jalan.label);
4725 if (jalan.getCalcId() != null)
4727 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4732 // delete the auto calculated row from the alignment
4733 al.deleteAnnotation(jalan, false);
4737 if (valan != nullAnnot)
4739 if (jalan != valan.template)
4741 // newly created autoannotation row instance
4742 // so keep a reference to the visible annotation row
4743 // and copy over all relevant attributes
4744 if (valan.template.graphHeight >= 0)
4747 jalan.graphHeight = valan.template.graphHeight;
4749 jalan.visible = valan.template.visible;
4751 reorder.add(new JvAnnotRow(valan.order, jalan));
4756 // Add any (possibly stale) autocalculated rows that were not appended to
4757 // the view during construction
4758 for (String other : remains)
4760 JvAnnotRow othera = visan.get(other);
4761 if (othera != nullAnnot && othera.template.getCalcId() != null
4762 && othera.template.getCalcId().length() > 0)
4764 reorder.add(othera);
4767 // now put the automatic annotation in its correct place
4768 int s = 0, srt[] = new int[reorder.size()];
4769 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4770 for (JvAnnotRow jvar : reorder)
4773 srt[s++] = jvar.order;
4776 jalview.util.QuickSort.sort(srt, rws);
4777 // and re-insert the annotation at its correct position
4778 for (JvAnnotRow jvar : rws)
4780 al.addAnnotation(jvar.template, jvar.order);
4782 af.alignPanel.adjustAnnotationHeight();
4786 Hashtable skipList = null;
4789 * TODO remove this method
4792 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4793 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4794 * throw new Error("Implementation Error. No skipList defined for this
4795 * Jalview2XML instance."); } return (AlignFrame)
4796 * skipList.get(view.getSequenceSetId()); }
4800 * Check if the Jalview view contained in object should be skipped or not.
4803 * @return true if view's sequenceSetId is a key in skipList
4805 private boolean skipViewport(JalviewModel object)
4807 if (skipList == null)
4812 if (skipList.containsKey(id = object.getJalviewModelSequence()
4813 .getViewport()[0].getSequenceSetId()))
4815 if (Cache.log != null && Cache.log.isDebugEnabled())
4817 Cache.log.debug("Skipping seuqence set id " + id);
4824 public void addToSkipList(AlignFrame af)
4826 if (skipList == null)
4828 skipList = new Hashtable();
4830 skipList.put(af.getViewport().getSequenceSetId(), af);
4833 public void clearSkipList()
4835 if (skipList != null)
4842 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4843 boolean ignoreUnrefed)
4845 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4847 Vector dseqs = null;
4850 // create a list of new dataset sequences
4851 dseqs = new Vector();
4853 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4855 Sequence vamsasSeq = vamsasSet.getSequence(i);
4856 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4858 // create a new dataset
4861 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4862 dseqs.copyInto(dsseqs);
4863 ds = new jalview.datamodel.Alignment(dsseqs);
4864 debug("Created new dataset " + vamsasSet.getDatasetId()
4865 + " for alignment " + System.identityHashCode(al));
4866 addDatasetRef(vamsasSet.getDatasetId(), ds);
4868 // set the dataset for the newly imported alignment.
4869 if (al.getDataset() == null && !ignoreUnrefed)
4878 * sequence definition to create/merge dataset sequence for
4882 * vector to add new dataset sequence to
4884 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4885 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4887 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4889 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4890 SequenceI dsq = null;
4891 if (sq != null && sq.getDatasetSequence() != null)
4893 dsq = sq.getDatasetSequence();
4895 if (sq == null && ignoreUnrefed)
4899 String sqid = vamsasSeq.getDsseqid();
4902 // need to create or add a new dataset sequence reference to this sequence
4905 dsq = seqRefIds.get(sqid);
4910 // make a new dataset sequence
4911 dsq = sq.createDatasetSequence();
4914 // make up a new dataset reference for this sequence
4915 sqid = seqHash(dsq);
4917 dsq.setVamsasId(uniqueSetSuffix + sqid);
4918 seqRefIds.put(sqid, dsq);
4923 dseqs.addElement(dsq);
4928 ds.addSequence(dsq);
4934 { // make this dataset sequence sq's dataset sequence
4935 sq.setDatasetSequence(dsq);
4936 // and update the current dataset alignment
4941 if (!dseqs.contains(dsq))
4948 if (ds.findIndex(dsq) < 0)
4950 ds.addSequence(dsq);
4957 // TODO: refactor this as a merge dataset sequence function
4958 // now check that sq (the dataset sequence) sequence really is the union of
4959 // all references to it
4960 // boolean pre = sq.getStart() < dsq.getStart();
4961 // boolean post = sq.getEnd() > dsq.getEnd();
4965 // StringBuffer sb = new StringBuffer();
4966 String newres = jalview.analysis.AlignSeq.extractGaps(
4967 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4968 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4969 && newres.length() > dsq.getLength())
4971 // Update with the longer sequence.
4975 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4976 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4977 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4978 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4980 dsq.setSequence(newres);
4982 // TODO: merges will never happen if we 'know' we have the real dataset
4983 // sequence - this should be detected when id==dssid
4985 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4986 // + (pre ? "prepended" : "") + " "
4987 // + (post ? "appended" : ""));
4993 * TODO use AlignmentI here and in related methods - needs
4994 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4996 Hashtable<String, AlignmentI> datasetIds = null;
4998 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5000 private AlignmentI getDatasetFor(String datasetId)
5002 if (datasetIds == null)
5004 datasetIds = new Hashtable<String, AlignmentI>();
5007 if (datasetIds.containsKey(datasetId))
5009 return datasetIds.get(datasetId);
5014 private void addDatasetRef(String datasetId, AlignmentI dataset)
5016 if (datasetIds == null)
5018 datasetIds = new Hashtable<String, AlignmentI>();
5020 datasetIds.put(datasetId, dataset);
5024 * make a new dataset ID for this jalview dataset alignment
5029 private String getDatasetIdRef(AlignmentI dataset)
5031 if (dataset.getDataset() != null)
5033 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5035 String datasetId = makeHashCode(dataset, null);
5036 if (datasetId == null)
5038 // make a new datasetId and record it
5039 if (dataset2Ids == null)
5041 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5045 datasetId = dataset2Ids.get(dataset);
5047 if (datasetId == null)
5049 datasetId = "ds" + dataset2Ids.size() + 1;
5050 dataset2Ids.put(dataset, datasetId);
5056 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5058 for (int d = 0; d < sequence.getDBRefCount(); d++)
5060 DBRef dr = sequence.getDBRef(d);
5061 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5062 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5063 .getVersion(), sequence.getDBRef(d).getAccessionId());
5064 if (dr.getMapping() != null)
5066 entry.setMap(addMapping(dr.getMapping()));
5068 datasetSequence.addDBRef(entry);
5072 private jalview.datamodel.Mapping addMapping(Mapping m)
5074 SequenceI dsto = null;
5075 // Mapping m = dr.getMapping();
5076 int fr[] = new int[m.getMapListFromCount() * 2];
5077 Enumeration f = m.enumerateMapListFrom();
5078 for (int _i = 0; f.hasMoreElements(); _i += 2)
5080 MapListFrom mf = (MapListFrom) f.nextElement();
5081 fr[_i] = mf.getStart();
5082 fr[_i + 1] = mf.getEnd();
5084 int fto[] = new int[m.getMapListToCount() * 2];
5085 f = m.enumerateMapListTo();
5086 for (int _i = 0; f.hasMoreElements(); _i += 2)
5088 MapListTo mf = (MapListTo) f.nextElement();
5089 fto[_i] = mf.getStart();
5090 fto[_i + 1] = mf.getEnd();
5092 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5093 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5094 if (m.getMappingChoice() != null)
5096 MappingChoice mc = m.getMappingChoice();
5097 if (mc.getDseqFor() != null)
5099 String dsfor = "" + mc.getDseqFor();
5100 if (seqRefIds.containsKey(dsfor))
5105 jmap.setTo(seqRefIds.get(dsfor));
5109 frefedSequence.add(newMappingRef(dsfor, jmap));
5115 * local sequence definition
5117 Sequence ms = mc.getSequence();
5118 SequenceI djs = null;
5119 String sqid = ms.getDsseqid();
5120 if (sqid != null && sqid.length() > 0)
5123 * recover dataset sequence
5125 djs = seqRefIds.get(sqid);
5130 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5131 sqid = ((Object) ms).toString(); // make up a new hascode for
5132 // undefined dataset sequence hash
5133 // (unlikely to happen)
5139 * make a new dataset sequence and add it to refIds hash
5141 djs = new jalview.datamodel.Sequence(ms.getName(),
5143 djs.setStart(jmap.getMap().getToLowest());
5144 djs.setEnd(jmap.getMap().getToHighest());
5145 djs.setVamsasId(uniqueSetSuffix + sqid);
5147 incompleteSeqs.put(sqid, djs);
5148 seqRefIds.put(sqid, djs);
5151 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5160 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5161 boolean keepSeqRefs)
5164 JalviewModel jm = saveState(ap, null, null, null);
5169 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5173 uniqueSetSuffix = "";
5174 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5179 if (this.frefedSequence == null)
5181 frefedSequence = new Vector();
5184 viewportsAdded.clear();
5186 AlignFrame af = loadFromObject(jm, null, false, null);
5187 af.alignPanels.clear();
5188 af.closeMenuItem_actionPerformed(true);
5191 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5192 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5193 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5194 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5195 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5198 return af.alignPanel;
5202 * flag indicating if hashtables should be cleared on finalization TODO this
5203 * flag may not be necessary
5205 private final boolean _cleartables = true;
5207 private Hashtable jvids2vobj;
5212 * @see java.lang.Object#finalize()
5215 protected void finalize() throws Throwable
5217 // really make sure we have no buried refs left.
5222 this.seqRefIds = null;
5223 this.seqsToIds = null;
5227 private void warn(String msg)
5232 private void warn(String msg, Exception e)
5234 if (Cache.log != null)
5238 Cache.log.warn(msg, e);
5242 Cache.log.warn(msg);
5247 System.err.println("Warning: " + msg);
5250 e.printStackTrace();
5255 private void debug(String string)
5257 debug(string, null);
5260 private void debug(String msg, Exception e)
5262 if (Cache.log != null)
5266 Cache.log.debug(msg, e);
5270 Cache.log.debug(msg);
5275 System.err.println("Warning: " + msg);
5278 e.printStackTrace();
5284 * set the object to ID mapping tables used to write/recover objects and XML
5285 * ID strings for the jalview project. If external tables are provided then
5286 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5287 * object goes out of scope. - also populates the datasetIds hashtable with
5288 * alignment objects containing dataset sequences
5291 * Map from ID strings to jalview datamodel
5293 * Map from jalview datamodel to ID strings
5297 public void setObjectMappingTables(Hashtable vobj2jv,
5298 IdentityHashMap jv2vobj)
5300 this.jv2vobj = jv2vobj;
5301 this.vobj2jv = vobj2jv;
5302 Iterator ds = jv2vobj.keySet().iterator();
5304 while (ds.hasNext())
5306 Object jvobj = ds.next();
5307 id = jv2vobj.get(jvobj).toString();
5308 if (jvobj instanceof jalview.datamodel.Alignment)
5310 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5312 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5315 else if (jvobj instanceof jalview.datamodel.Sequence)
5317 // register sequence object so the XML parser can recover it.
5318 if (seqRefIds == null)
5320 seqRefIds = new HashMap<String, SequenceI>();
5322 if (seqsToIds == null)
5324 seqsToIds = new IdentityHashMap<SequenceI, String>();
5326 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5327 seqsToIds.put((SequenceI) jvobj, id);
5329 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5332 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5333 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5334 if (jvann.annotationId == null)
5336 jvann.annotationId = anid;
5338 if (!jvann.annotationId.equals(anid))
5340 // TODO verify that this is the correct behaviour
5341 this.warn("Overriding Annotation ID for " + anid
5342 + " from different id : " + jvann.annotationId);
5343 jvann.annotationId = anid;
5346 else if (jvobj instanceof String)
5348 if (jvids2vobj == null)
5350 jvids2vobj = new Hashtable();
5351 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5356 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5362 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5363 * objects created from the project archive. If string is null (default for
5364 * construction) then suffix will be set automatically.
5368 public void setUniqueSetSuffix(String string)
5370 uniqueSetSuffix = string;
5375 * uses skipList2 as the skipList for skipping views on sequence sets
5376 * associated with keys in the skipList
5380 public void setSkipList(Hashtable skipList2)
5382 skipList = skipList2;
5386 * Reads the jar entry of given name and returns its contents, or null if the
5387 * entry is not found.
5390 * @param jarEntryName
5393 protected String readJarEntry(jarInputStreamProvider jprovider,
5394 String jarEntryName)
5396 String result = null;
5397 BufferedReader in = null;
5402 * Reopen the jar input stream and traverse its entries to find a matching
5405 JarInputStream jin = jprovider.getJarInputStream();
5406 JarEntry entry = null;
5409 entry = jin.getNextJarEntry();
5410 } while (entry != null && !entry.getName().equals(jarEntryName));
5414 StringBuilder out = new StringBuilder(256);
5415 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5418 while ((data = in.readLine()) != null)
5422 result = out.toString();
5426 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5428 } catch (Exception ex)
5430 ex.printStackTrace();
5438 } catch (IOException e)
5449 * Returns an incrementing counter (0, 1, 2...)
5453 private synchronized int nextCounter()