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.jarInputStreamProvider;
84 import jalview.viewmodel.AlignmentViewport;
85 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
86 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
87 import jalview.ws.jws2.Jws2Discoverer;
88 import jalview.ws.jws2.dm.AAConSettings;
89 import jalview.ws.jws2.jabaws2.Jws2Instance;
90 import jalview.ws.params.ArgumentI;
91 import jalview.ws.params.AutoCalcSetting;
92 import jalview.ws.params.WsParamSetI;
94 import java.awt.Color;
95 import java.awt.Rectangle;
96 import java.io.BufferedReader;
97 import java.io.DataInputStream;
98 import java.io.DataOutputStream;
100 import java.io.FileInputStream;
101 import java.io.FileOutputStream;
102 import java.io.IOException;
103 import java.io.InputStreamReader;
104 import java.io.OutputStreamWriter;
105 import java.io.PrintWriter;
106 import java.lang.reflect.InvocationTargetException;
107 import java.net.MalformedURLException;
109 import java.util.ArrayList;
110 import java.util.Enumeration;
111 import java.util.HashMap;
112 import java.util.HashSet;
113 import java.util.Hashtable;
114 import java.util.IdentityHashMap;
115 import java.util.Iterator;
116 import java.util.LinkedHashMap;
117 import java.util.List;
118 import java.util.Map;
119 import java.util.Map.Entry;
120 import java.util.Set;
121 import java.util.StringTokenizer;
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 Vector frefedSequence = null;
170 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
173 * Map of reconstructed AlignFrame objects that appear to have come from
174 * SplitFrame objects (have a dna/protein complement view).
176 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
179 * Map from displayed rna structure models to their saved session state jar
182 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
185 * create/return unique hash string for sq
188 * @return new or existing unique string for sq
190 String seqHash(SequenceI sq)
192 if (seqsToIds == null)
196 if (seqsToIds.containsKey(sq))
198 return seqsToIds.get(sq);
202 // create sequential key
203 String key = "sq" + (seqsToIds.size() + 1);
204 key = makeHashCode(sq, key); // check we don't have an external reference
206 seqsToIds.put(sq, key);
215 if (seqRefIds != null)
219 if (seqsToIds != null)
229 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
230 // seqRefIds = new Hashtable();
231 // seqsToIds = new IdentityHashMap();
237 if (seqsToIds == null)
239 seqsToIds = new IdentityHashMap<SequenceI, String>();
241 if (seqRefIds == null)
243 seqRefIds = new HashMap<String, SequenceI>();
251 public Jalview2XML(boolean raiseGUI)
253 this.raiseGUI = raiseGUI;
256 public void resolveFrefedSequences()
258 if (frefedSequence.size() > 0)
260 int r = 0, rSize = frefedSequence.size();
263 Object[] ref = (Object[]) frefedSequence.elementAt(r);
266 String sref = (String) ref[0];
267 if (seqRefIds.containsKey(sref))
269 if (ref[1] instanceof jalview.datamodel.Mapping)
271 SequenceI seq = seqRefIds.get(sref);
272 while (seq.getDatasetSequence() != null)
274 seq = seq.getDatasetSequence();
276 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
280 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
282 SequenceI seq = seqRefIds.get(sref);
283 while (seq.getDatasetSequence() != null)
285 seq = seq.getDatasetSequence();
288 && ref[2] instanceof jalview.datamodel.Mapping)
290 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
291 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
292 seq, mp.getTo(), mp.getMap());
297 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
298 + ref[2].getClass() + " type objects.");
304 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
305 + ref[1].getClass() + " type objects.");
308 frefedSequence.remove(r);
314 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
316 + " with objecttype "
317 + ref[1].getClass());
324 frefedSequence.remove(r);
332 * This maintains a map of viewports, the key being the seqSetId. Important to
333 * set historyItem and redoList for multiple views
335 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
337 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
339 String uniqueSetSuffix = "";
342 * List of pdbfiles added to Jar
344 List<String> pdbfiles = null;
346 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
347 public void saveState(File statefile)
349 FileOutputStream fos = null;
352 fos = new FileOutputStream(statefile);
353 JarOutputStream jout = new JarOutputStream(fos);
356 } catch (Exception e)
358 // TODO: inform user of the problem - they need to know if their data was
360 if (errorMessage == null)
362 errorMessage = "Couldn't write Jalview Archive to output file '"
363 + statefile + "' - See console error log for details";
367 errorMessage += "(output file was '" + statefile + "')";
377 } catch (IOException e)
387 * Writes a jalview project archive to the given Jar output stream.
391 public void saveState(JarOutputStream jout)
393 AlignFrame[] frames = Desktop.getAlignFrames();
400 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
403 * ensure cached data is clear before starting
405 // todo tidy up seqRefIds, seqsToIds initialisation / reset
407 splitFrameCandidates.clear();
412 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
413 // //////////////////////////////////////////////////
415 List<String> shortNames = new ArrayList<String>();
416 List<String> viewIds = new ArrayList<String>();
419 for (int i = frames.length - 1; i > -1; i--)
421 AlignFrame af = frames[i];
425 .containsKey(af.getViewport().getSequenceSetId()))
430 String shortName = makeFilename(af, shortNames);
432 int ap, apSize = af.alignPanels.size();
434 for (ap = 0; ap < apSize; ap++)
436 AlignmentPanel apanel = af.alignPanels.get(ap);
437 String fileName = apSize == 1 ? shortName : ap + shortName;
438 if (!fileName.endsWith(".xml"))
440 fileName = fileName + ".xml";
443 saveState(apanel, fileName, jout, viewIds);
445 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
447 if (!dsses.containsKey(dssid))
449 dsses.put(dssid, af);
454 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
460 } catch (Exception foo)
465 } catch (Exception ex)
467 // TODO: inform user of the problem - they need to know if their data was
469 if (errorMessage == null)
471 errorMessage = "Couldn't write Jalview Archive - see error output for details";
473 ex.printStackTrace();
478 * Generates a distinct file name, based on the title of the AlignFrame, by
479 * appending _n for increasing n until an unused name is generated. The new
480 * name (without its extension) is added to the list.
484 * @return the generated name, with .xml extension
486 protected String makeFilename(AlignFrame af, List<String> namesUsed)
488 String shortName = af.getTitle();
490 if (shortName.indexOf(File.separatorChar) > -1)
492 shortName = shortName.substring(shortName
493 .lastIndexOf(File.separatorChar) + 1);
498 while (namesUsed.contains(shortName))
500 if (shortName.endsWith("_" + (count - 1)))
502 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
505 shortName = shortName.concat("_" + count);
509 namesUsed.add(shortName);
511 if (!shortName.endsWith(".xml"))
513 shortName = shortName + ".xml";
518 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
519 public boolean saveAlignment(AlignFrame af, String jarFile,
525 int apSize = af.alignPanels.size();
526 FileOutputStream fos = new FileOutputStream(jarFile);
527 JarOutputStream jout = new JarOutputStream(fos);
528 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
529 List<String> viewIds = new ArrayList<String>();
531 for (AlignmentPanel apanel : af.alignPanels)
533 String jfileName = apSize == 1 ? fileName : fileName + ap;
535 if (!jfileName.endsWith(".xml"))
537 jfileName = jfileName + ".xml";
539 saveState(apanel, jfileName, jout, viewIds);
540 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
542 if (!dsses.containsKey(dssid))
544 dsses.put(dssid, af);
547 writeDatasetFor(dsses, fileName, jout);
551 } catch (Exception foo)
557 } catch (Exception ex)
559 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
560 ex.printStackTrace();
565 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
566 String fileName, JarOutputStream jout)
569 for (String dssids : dsses.keySet())
571 AlignFrame _af = dsses.get(dssids);
572 String jfileName = fileName + " Dataset for " + _af.getTitle();
573 if (!jfileName.endsWith(".xml"))
575 jfileName = jfileName + ".xml";
577 saveState(_af.alignPanel, jfileName, true, jout, null);
582 * create a JalviewModel from an alignment view and marshall it to a
586 * panel to create jalview model for
588 * name of alignment panel written to output stream
595 public JalviewModel saveState(AlignmentPanel ap, String fileName,
596 JarOutputStream jout, List<String> viewIds)
598 return saveState(ap, fileName, false, jout, viewIds);
602 * create a JalviewModel from an alignment view and marshall it to a
606 * panel to create jalview model for
608 * name of alignment panel written to output stream
610 * when true, only write the dataset for the alignment, not the data
611 * associated with the view.
617 public JalviewModel saveState(AlignmentPanel ap, String fileName,
618 boolean storeDS, JarOutputStream jout, List<String> viewIds)
622 viewIds = new ArrayList<String>();
627 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
629 AlignViewport av = ap.av;
631 JalviewModel object = new JalviewModel();
632 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
634 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
635 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
636 "Development Build"));
638 jalview.datamodel.AlignmentI jal = av.getAlignment();
640 if (av.hasHiddenRows())
642 jal = jal.getHiddenSequences().getFullAlignment();
645 SequenceSet vamsasSet = new SequenceSet();
647 JalviewModelSequence jms = new JalviewModelSequence();
649 vamsasSet.setGapChar(jal.getGapCharacter() + "");
651 if (jal.getDataset() != null)
653 // dataset id is the dataset's hashcode
654 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
657 // switch jal and the dataset
658 jal = jal.getDataset();
661 if (jal.getProperties() != null)
663 Enumeration en = jal.getProperties().keys();
664 while (en.hasMoreElements())
666 String key = en.nextElement().toString();
667 SequenceSetProperties ssp = new SequenceSetProperties();
669 ssp.setValue(jal.getProperties().get(key).toString());
670 vamsasSet.addSequenceSetProperties(ssp);
675 Set<String> calcIdSet = new HashSet<String>();
678 for (int i = 0; i < jal.getHeight(); i++)
680 final SequenceI jds = jal.getSequenceAt(i);
681 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
682 : jds.getDatasetSequence();
683 String id = seqHash(jds);
685 if (seqRefIds.get(id) != null)
687 // This happens for two reasons: 1. multiple views are being serialised.
688 // 2. the hashCode has collided with another sequence's code. This DOES
689 // HAPPEN! (PF00072.15.stk does this)
690 // JBPNote: Uncomment to debug writing out of files that do not read
691 // back in due to ArrayOutOfBoundExceptions.
692 // System.err.println("vamsasSeq backref: "+id+"");
693 // System.err.println(jds.getName()+"
694 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
695 // System.err.println("Hashcode: "+seqHash(jds));
696 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
697 // System.err.println(rsq.getName()+"
698 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
699 // System.err.println("Hashcode: "+seqHash(rsq));
703 vamsasSeq = createVamsasSequence(id, jds);
704 vamsasSet.addSequence(vamsasSeq);
705 seqRefIds.put(id, jds);
709 jseq.setStart(jds.getStart());
710 jseq.setEnd(jds.getEnd());
711 jseq.setColour(av.getSequenceColour(jds).getRGB());
713 jseq.setId(id); // jseq id should be a string not a number
716 // Store any sequences this sequence represents
717 if (av.hasHiddenRows())
719 jseq.setHidden(av.getAlignment().getHiddenSequences()
722 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
724 jalview.datamodel.SequenceI[] reps = av
725 .getRepresentedSequences(jal.getSequenceAt(i))
726 .getSequencesInOrder(jal);
728 for (int h = 0; h < reps.length; h++)
730 if (reps[h] != jal.getSequenceAt(i))
732 jseq.addHiddenSequences(jal.findIndex(reps[h]));
739 if (jds.getSequenceFeatures() != null)
741 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
743 while (index < sf.length)
745 Features features = new Features();
747 features.setBegin(sf[index].getBegin());
748 features.setEnd(sf[index].getEnd());
749 features.setDescription(sf[index].getDescription());
750 features.setType(sf[index].getType());
751 features.setFeatureGroup(sf[index].getFeatureGroup());
752 features.setScore(sf[index].getScore());
753 if (sf[index].links != null)
755 for (int l = 0; l < sf[index].links.size(); l++)
757 OtherData keyValue = new OtherData();
758 keyValue.setKey("LINK_" + l);
759 keyValue.setValue(sf[index].links.elementAt(l).toString());
760 features.addOtherData(keyValue);
763 if (sf[index].otherDetails != null)
766 Enumeration keys = sf[index].otherDetails.keys();
767 while (keys.hasMoreElements())
769 key = keys.nextElement().toString();
770 OtherData keyValue = new OtherData();
771 keyValue.setKey(key);
772 keyValue.setValue(sf[index].otherDetails.get(key).toString());
773 features.addOtherData(keyValue);
777 jseq.addFeatures(features);
782 if (jdatasq.getAllPDBEntries() != null)
784 Enumeration en = jdatasq.getAllPDBEntries().elements();
785 while (en.hasMoreElements())
787 Pdbids pdb = new Pdbids();
788 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
791 String pdbId = entry.getId();
793 pdb.setType(entry.getType());
796 * Store any structure views associated with this sequence. This
797 * section copes with duplicate entries in the project, so a dataset
798 * only view *should* be coped with sensibly.
800 // This must have been loaded, is it still visible?
801 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
802 String matchedFile = null;
803 for (int f = frames.length - 1; f > -1; f--)
805 if (frames[f] instanceof StructureViewerBase)
807 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
808 matchedFile = saveStructureState(ap, jds, pdb, entry,
809 viewIds, matchedFile, viewFrame);
811 * Only store each structure viewer's state once in the project
812 * jar. First time through only (storeDS==false)
814 String viewId = viewFrame.getViewId();
815 if (!storeDS && !viewIds.contains(viewId))
820 String viewerState = viewFrame.getStateInfo();
821 writeJarEntry(jout, getViewerJarEntryName(viewId),
822 viewerState.getBytes());
823 } catch (IOException e)
825 System.err.println("Error saving viewer state: "
832 if (matchedFile != null || entry.getFile() != null)
834 if (entry.getFile() != null)
837 matchedFile = entry.getFile();
839 pdb.setFile(matchedFile); // entry.getFile());
840 if (pdbfiles == null)
842 pdbfiles = new ArrayList<String>();
845 if (!pdbfiles.contains(pdbId))
848 copyFileToJar(jout, matchedFile, pdbId);
852 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
854 PdbentryItem item = new PdbentryItem();
855 Hashtable properties = entry.getProperty();
856 Enumeration en2 = properties.keys();
857 while (en2.hasMoreElements())
859 Property prop = new Property();
860 String key = en2.nextElement().toString();
862 prop.setValue(properties.get(key).toString());
863 item.addProperty(prop);
865 pdb.addPdbentryItem(item);
872 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
877 if (!storeDS && av.hasHiddenRows())
879 jal = av.getAlignment();
882 if (jal.getCodonFrames() != null)
884 Set<AlignedCodonFrame> jac = jal.getCodonFrames();
885 for (AlignedCodonFrame acf : jac)
887 AlcodonFrame alc = new AlcodonFrame();
888 vamsasSet.addAlcodonFrame(alc);
889 if (acf.getProtMappings() != null
890 && acf.getProtMappings().length > 0)
892 SequenceI[] dnas = acf.getdnaSeqs();
893 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
894 for (int m = 0; m < pmaps.length; m++)
896 AlcodMap alcmap = new AlcodMap();
897 alcmap.setDnasq(seqHash(dnas[m]));
898 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
900 alc.addAlcodMap(alcmap);
905 // AlcodonFrame alc = new AlcodonFrame();
906 // vamsasSet.addAlcodonFrame(alc);
907 // for (int p = 0; p < acf.aaWidth; p++)
909 // Alcodon cmap = new Alcodon();
910 // if (acf.codons[p] != null)
912 // // Null codons indicate a gapped column in the translated peptide
914 // cmap.setPos1(acf.codons[p][0]);
915 // cmap.setPos2(acf.codons[p][1]);
916 // cmap.setPos3(acf.codons[p][2]);
918 // alc.addAlcodon(cmap);
920 // if (acf.getProtMappings() != null
921 // && acf.getProtMappings().length > 0)
923 // SequenceI[] dnas = acf.getdnaSeqs();
924 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
925 // for (int m = 0; m < pmaps.length; m++)
927 // AlcodMap alcmap = new AlcodMap();
928 // alcmap.setDnasq(seqHash(dnas[m]));
929 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
931 // alc.addAlcodMap(alcmap);
938 // /////////////////////////////////
939 if (!storeDS && av.currentTree != null)
941 // FIND ANY ASSOCIATED TREES
942 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
943 if (Desktop.desktop != null)
945 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
947 for (int t = 0; t < frames.length; t++)
949 if (frames[t] instanceof TreePanel)
951 TreePanel tp = (TreePanel) frames[t];
953 if (tp.treeCanvas.av.getAlignment() == jal)
955 Tree tree = new Tree();
956 tree.setTitle(tp.getTitle());
957 tree.setCurrentTree((av.currentTree == tp.getTree()));
958 tree.setNewick(tp.getTree().toString());
959 tree.setThreshold(tp.treeCanvas.threshold);
961 tree.setFitToWindow(tp.fitToWindow.getState());
962 tree.setFontName(tp.getTreeFont().getName());
963 tree.setFontSize(tp.getTreeFont().getSize());
964 tree.setFontStyle(tp.getTreeFont().getStyle());
965 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
967 tree.setShowBootstrap(tp.bootstrapMenu.getState());
968 tree.setShowDistances(tp.distanceMenu.getState());
970 tree.setHeight(tp.getHeight());
971 tree.setWidth(tp.getWidth());
972 tree.setXpos(tp.getX());
973 tree.setYpos(tp.getY());
974 tree.setId(makeHashCode(tp, null));
984 * store forward refs from an annotationRow to any groups
986 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
989 for (SequenceI sq : jal.getSequences())
991 // Store annotation on dataset sequences only
992 AlignmentAnnotation[] aa = sq.getAnnotation();
993 if (aa != null && aa.length > 0)
995 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1002 if (jal.getAlignmentAnnotation() != null)
1004 // Store the annotation shown on the alignment.
1005 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1006 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1011 if (jal.getGroups() != null)
1013 JGroup[] groups = new JGroup[jal.getGroups().size()];
1015 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1017 JGroup jGroup = new JGroup();
1018 groups[++i] = jGroup;
1020 jGroup.setStart(sg.getStartRes());
1021 jGroup.setEnd(sg.getEndRes());
1022 jGroup.setName(sg.getName());
1023 if (groupRefs.containsKey(sg))
1025 // group has references so set its ID field
1026 jGroup.setId(groupRefs.get(sg));
1030 if (sg.cs.conservationApplied())
1032 jGroup.setConsThreshold(sg.cs.getConservationInc());
1034 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1036 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1040 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1043 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1045 jGroup.setColour("AnnotationColourGradient");
1046 jGroup.setAnnotationColours(constructAnnotationColours(
1047 (jalview.schemes.AnnotationColourGradient) sg.cs,
1050 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1052 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1056 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1059 jGroup.setPidThreshold(sg.cs.getThreshold());
1062 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1063 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1064 jGroup.setDisplayText(sg.getDisplayText());
1065 jGroup.setColourText(sg.getColourText());
1066 jGroup.setTextCol1(sg.textColour.getRGB());
1067 jGroup.setTextCol2(sg.textColour2.getRGB());
1068 jGroup.setTextColThreshold(sg.thresholdTextColour);
1069 jGroup.setShowUnconserved(sg.getShowNonconserved());
1070 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1071 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1072 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1073 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1074 for (SequenceI seq : sg.getSequences())
1076 jGroup.addSeq(seqHash(seq));
1080 jms.setJGroup(groups);
1084 // /////////SAVE VIEWPORT
1085 Viewport view = new Viewport();
1086 view.setTitle(ap.alignFrame.getTitle());
1087 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1088 av.getSequenceSetId()));
1089 view.setId(av.getViewId());
1090 if (av.getCodingComplement() != null)
1092 view.setComplementId(av.getCodingComplement().getViewId());
1094 view.setViewName(av.viewName);
1095 view.setGatheredViews(av.isGatherViewsHere());
1097 Rectangle size = ap.av.getExplodedGeometry();
1098 Rectangle position = size;
1101 size = ap.alignFrame.getBounds();
1102 if (av.getCodingComplement() != null)
1104 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1112 view.setXpos(position.x);
1113 view.setYpos(position.y);
1115 view.setWidth(size.width);
1116 view.setHeight(size.height);
1118 view.setStartRes(av.startRes);
1119 view.setStartSeq(av.startSeq);
1121 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1123 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1126 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1128 AnnotationColours ac = constructAnnotationColours(
1129 (jalview.schemes.AnnotationColourGradient) av
1130 .getGlobalColourScheme(),
1133 view.setAnnotationColours(ac);
1134 view.setBgColour("AnnotationColourGradient");
1138 view.setBgColour(ColourSchemeProperty.getColourName(av
1139 .getGlobalColourScheme()));
1142 ColourSchemeI cs = av.getGlobalColourScheme();
1146 if (cs.conservationApplied())
1148 view.setConsThreshold(cs.getConservationInc());
1149 if (cs instanceof jalview.schemes.UserColourScheme)
1151 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1155 if (cs instanceof ResidueColourScheme)
1157 view.setPidThreshold(cs.getThreshold());
1161 view.setConservationSelected(av.getConservationSelected());
1162 view.setPidSelected(av.getAbovePIDThreshold());
1163 view.setFontName(av.font.getName());
1164 view.setFontSize(av.font.getSize());
1165 view.setFontStyle(av.font.getStyle());
1166 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1167 view.setRenderGaps(av.isRenderGaps());
1168 view.setShowAnnotation(av.isShowAnnotation());
1169 view.setShowBoxes(av.getShowBoxes());
1170 view.setShowColourText(av.getColourText());
1171 view.setShowFullId(av.getShowJVSuffix());
1172 view.setRightAlignIds(av.isRightAlignIds());
1173 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1174 view.setShowText(av.getShowText());
1175 view.setShowUnconserved(av.getShowUnconserved());
1176 view.setWrapAlignment(av.getWrapAlignment());
1177 view.setTextCol1(av.getTextColour().getRGB());
1178 view.setTextCol2(av.getTextColour2().getRGB());
1179 view.setTextColThreshold(av.getThresholdTextColour());
1180 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1181 view.setShowSequenceLogo(av.isShowSequenceLogo());
1182 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1183 view.setShowGroupConsensus(av.isShowGroupConsensus());
1184 view.setShowGroupConservation(av.isShowGroupConservation());
1185 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1186 view.setShowDbRefTooltip(av.isShowDBRefs());
1187 view.setFollowHighlight(av.isFollowHighlight());
1188 view.setFollowSelection(av.followSelection);
1189 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1190 if (av.getFeaturesDisplayed() != null)
1192 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1194 String[] renderOrder = ap.getSeqPanel().seqCanvas
1195 .getFeatureRenderer().getRenderOrder()
1196 .toArray(new String[0]);
1198 Vector<String> settingsAdded = new Vector<String>();
1199 if (renderOrder != null)
1201 for (int ro = 0; ro < renderOrder.length; ro++)
1203 FeatureColourI gstyle = ap.getSeqPanel().seqCanvas
1204 .getFeatureRenderer()
1205 .getFeatureStyle(renderOrder[ro]);
1206 Setting setting = new Setting();
1207 setting.setType(renderOrder[ro]);
1208 if (!gstyle.isSimpleColour())
1210 setting.setColour(gstyle.getMaxColour().getRGB());
1211 setting.setMincolour(gstyle.getMinColour().getRGB());
1212 setting.setMin(gstyle.getMin());
1213 setting.setMax(gstyle.getMax());
1214 setting.setColourByLabel(gstyle.isColourByLabel());
1215 setting.setAutoScale(gstyle.isAutoScaled());
1216 setting.setThreshold(gstyle.getThreshold());
1217 // -1 = No threshold, 0 = Below, 1 = Above
1218 setting.setThreshstate(gstyle.isAboveThreshold() ? 1
1219 : (gstyle.isBelowThreshold() ? 0 : -1));
1223 setting.setColour(gstyle.getColour().getRGB());
1226 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1228 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1229 .getOrder(renderOrder[ro]);
1232 setting.setOrder(rorder);
1234 fs.addSetting(setting);
1235 settingsAdded.addElement(renderOrder[ro]);
1239 // is groups actually supposed to be a map here ?
1240 Iterator<String> en = ap.getSeqPanel().seqCanvas
1241 .getFeatureRenderer()
1242 .getFeatureGroups().iterator();
1243 Vector<String> groupsAdded = new Vector<String>();
1244 while (en.hasNext())
1246 String grp = en.next().toString();
1247 if (groupsAdded.contains(grp))
1251 Group g = new Group();
1253 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1254 .getFeatureRenderer().checkGroupVisibility(grp, false))
1257 groupsAdded.addElement(grp);
1259 jms.setFeatureSettings(fs);
1262 if (av.hasHiddenColumns())
1264 if (av.getColumnSelection() == null
1265 || av.getColumnSelection().getHiddenColumns() == null)
1267 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1271 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1274 int[] region = av.getColumnSelection().getHiddenColumns()
1276 HiddenColumns hc = new HiddenColumns();
1277 hc.setStart(region[0]);
1278 hc.setEnd(region[1]);
1279 view.addHiddenColumns(hc);
1283 if (calcIdSet.size() > 0)
1285 for (String calcId : calcIdSet)
1287 if (calcId.trim().length() > 0)
1289 CalcIdParam cidp = createCalcIdParam(calcId, av);
1290 // Some calcIds have no parameters.
1293 view.addCalcIdParam(cidp);
1299 jms.addViewport(view);
1301 object.setJalviewModelSequence(jms);
1302 object.getVamsasModel().addSequenceSet(vamsasSet);
1304 if (jout != null && fileName != null)
1306 // We may not want to write the object to disk,
1307 // eg we can copy the alignViewport to a new view object
1308 // using save and then load
1311 System.out.println("Writing jar entry " + fileName);
1312 JarEntry entry = new JarEntry(fileName);
1313 jout.putNextEntry(entry);
1314 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1316 Marshaller marshaller = new Marshaller(pout);
1317 marshaller.marshal(object);
1320 } catch (Exception ex)
1322 // TODO: raise error in GUI if marshalling failed.
1323 ex.printStackTrace();
1330 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1331 * for each viewer, with
1333 * <li>viewer geometry (position, size, split pane divider location)</li>
1334 * <li>index of the selected structure in the viewer (currently shows gapped
1336 * <li>the id of the annotation holding RNA secondary structure</li>
1337 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1339 * Varna viewer state is also written out (in native Varna XML) to separate
1340 * project jar entries. A separate entry is written for each RNA structure
1341 * displayed, with the naming convention
1343 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1351 * @param storeDataset
1353 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1354 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1355 boolean storeDataset)
1357 if (Desktop.desktop == null)
1361 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1362 for (int f = frames.length - 1; f > -1; f--)
1364 if (frames[f] instanceof AppVarna)
1366 AppVarna varna = (AppVarna) frames[f];
1368 * link the sequence to every viewer that is showing it and is linked to
1369 * its alignment panel
1371 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1373 String viewId = varna.getViewId();
1374 RnaViewer rna = new RnaViewer();
1375 rna.setViewId(viewId);
1376 rna.setTitle(varna.getTitle());
1377 rna.setXpos(varna.getX());
1378 rna.setYpos(varna.getY());
1379 rna.setWidth(varna.getWidth());
1380 rna.setHeight(varna.getHeight());
1381 rna.setDividerLocation(varna.getDividerLocation());
1382 rna.setSelectedRna(varna.getSelectedIndex());
1383 jseq.addRnaViewer(rna);
1386 * Store each Varna panel's state once in the project per sequence.
1387 * First time through only (storeDataset==false)
1389 // boolean storeSessions = false;
1390 // String sequenceViewId = viewId + seqsToIds.get(jds);
1391 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1393 // viewIds.add(sequenceViewId);
1394 // storeSessions = true;
1396 for (RnaModel model : varna.getModels())
1398 if (model.seq == jds)
1401 * VARNA saves each view (sequence or alignment secondary
1402 * structure, gapped or trimmed) as a separate XML file
1404 String jarEntryName = rnaSessions.get(model);
1405 if (jarEntryName == null)
1408 String varnaStateFile = varna.getStateInfo(model.rna);
1409 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1410 copyFileToJar(jout, varnaStateFile, jarEntryName);
1411 rnaSessions.put(model, jarEntryName);
1413 SecondaryStructure ss = new SecondaryStructure();
1414 String annotationId = varna.getAnnotation(jds).annotationId;
1415 ss.setAnnotationId(annotationId);
1416 ss.setViewerState(jarEntryName);
1417 ss.setGapped(model.gapped);
1418 ss.setTitle(model.title);
1419 rna.addSecondaryStructure(ss);
1428 * Copy the contents of a file to a new entry added to the output jar
1432 * @param jarEntryName
1434 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1435 String jarEntryName)
1437 DataInputStream dis = null;
1440 File file = new File(infilePath);
1441 if (file.exists() && jout != null)
1443 dis = new DataInputStream(new FileInputStream(file));
1444 byte[] data = new byte[(int) file.length()];
1445 dis.readFully(data);
1446 writeJarEntry(jout, jarEntryName, data);
1448 } catch (Exception ex)
1450 ex.printStackTrace();
1458 } catch (IOException e)
1467 * Write the data to a new entry of given name in the output jar file
1470 * @param jarEntryName
1472 * @throws IOException
1474 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1475 byte[] data) throws IOException
1479 System.out.println("Writing jar entry " + jarEntryName);
1480 jout.putNextEntry(new JarEntry(jarEntryName));
1481 DataOutputStream dout = new DataOutputStream(jout);
1482 dout.write(data, 0, data.length);
1489 * Save the state of a structure viewer
1494 * the archive XML element under which to save the state
1497 * @param matchedFile
1501 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1502 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1503 String matchedFile, StructureViewerBase viewFrame)
1505 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1508 * Look for any bindings for this viewer to the PDB file of interest
1509 * (including part matches excluding chain id)
1511 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1513 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1514 final String pdbId = pdbentry.getId();
1515 if (!pdbId.equals(entry.getId())
1516 && !(entry.getId().length() > 4 && entry.getId()
1517 .toLowerCase().startsWith(pdbId.toLowerCase())))
1520 * not interested in a binding to a different PDB entry here
1524 if (matchedFile == null)
1526 matchedFile = pdbentry.getFile();
1528 else if (!matchedFile.equals(pdbentry.getFile()))
1531 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1532 + pdbentry.getFile());
1536 // can get at it if the ID
1537 // match is ambiguous (e.g.
1540 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1542 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1543 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1545 StructureState state = new StructureState();
1546 state.setVisible(true);
1547 state.setXpos(viewFrame.getX());
1548 state.setYpos(viewFrame.getY());
1549 state.setWidth(viewFrame.getWidth());
1550 state.setHeight(viewFrame.getHeight());
1551 final String viewId = viewFrame.getViewId();
1552 state.setViewId(viewId);
1553 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1554 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1555 state.setColourByJmol(viewFrame.isColouredByViewer());
1556 state.setType(viewFrame.getViewerType().toString());
1557 pdb.addStructureState(state);
1564 private AnnotationColours constructAnnotationColours(
1565 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1566 JalviewModelSequence jms)
1568 AnnotationColours ac = new AnnotationColours();
1569 ac.setAboveThreshold(acg.getAboveThreshold());
1570 ac.setThreshold(acg.getAnnotationThreshold());
1571 ac.setAnnotation(acg.getAnnotation());
1572 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1574 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1579 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1583 ac.setMaxColour(acg.getMaxColour().getRGB());
1584 ac.setMinColour(acg.getMinColour().getRGB());
1585 ac.setPerSequence(acg.isSeqAssociated());
1586 ac.setPredefinedColours(acg.isPredefinedColours());
1590 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1591 IdentityHashMap<SequenceGroup, String> groupRefs,
1592 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1593 SequenceSet vamsasSet)
1596 for (int i = 0; i < aa.length; i++)
1598 Annotation an = new Annotation();
1600 AlignmentAnnotation annotation = aa[i];
1601 if (annotation.annotationId != null)
1603 annotationIds.put(annotation.annotationId, annotation);
1606 an.setId(annotation.annotationId);
1608 an.setVisible(annotation.visible);
1610 an.setDescription(annotation.description);
1612 if (annotation.sequenceRef != null)
1614 // 2.9 JAL-1781 xref on sequence id rather than name
1615 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1617 if (annotation.groupRef != null)
1619 String groupIdr = groupRefs.get(annotation.groupRef);
1620 if (groupIdr == null)
1622 // make a locally unique String
1624 annotation.groupRef,
1625 groupIdr = ("" + System.currentTimeMillis()
1626 + annotation.groupRef.getName() + groupRefs
1629 an.setGroupRef(groupIdr.toString());
1632 // store all visualization attributes for annotation
1633 an.setGraphHeight(annotation.graphHeight);
1634 an.setCentreColLabels(annotation.centreColLabels);
1635 an.setScaleColLabels(annotation.scaleColLabel);
1636 an.setShowAllColLabels(annotation.showAllColLabels);
1637 an.setBelowAlignment(annotation.belowAlignment);
1639 if (annotation.graph > 0)
1642 an.setGraphType(annotation.graph);
1643 an.setGraphGroup(annotation.graphGroup);
1644 if (annotation.getThreshold() != null)
1646 ThresholdLine line = new ThresholdLine();
1647 line.setLabel(annotation.getThreshold().label);
1648 line.setValue(annotation.getThreshold().value);
1649 line.setColour(annotation.getThreshold().colour.getRGB());
1650 an.setThresholdLine(line);
1658 an.setLabel(annotation.label);
1660 if (annotation == av.getAlignmentQualityAnnot()
1661 || annotation == av.getAlignmentConservationAnnotation()
1662 || annotation == av.getAlignmentConsensusAnnotation()
1663 || annotation.autoCalculated)
1665 // new way of indicating autocalculated annotation -
1666 an.setAutoCalculated(annotation.autoCalculated);
1668 if (annotation.hasScore())
1670 an.setScore(annotation.getScore());
1673 if (annotation.getCalcId() != null)
1675 calcIdSet.add(annotation.getCalcId());
1676 an.setCalcId(annotation.getCalcId());
1678 if (annotation.hasProperties())
1680 for (String pr : annotation.getProperties())
1682 Property prop = new Property();
1684 prop.setValue(annotation.getProperty(pr));
1685 an.addProperty(prop);
1689 AnnotationElement ae;
1690 if (annotation.annotations != null)
1692 an.setScoreOnly(false);
1693 for (int a = 0; a < annotation.annotations.length; a++)
1695 if ((annotation == null) || (annotation.annotations[a] == null))
1700 ae = new AnnotationElement();
1701 if (annotation.annotations[a].description != null)
1703 ae.setDescription(annotation.annotations[a].description);
1705 if (annotation.annotations[a].displayCharacter != null)
1707 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1710 if (!Float.isNaN(annotation.annotations[a].value))
1712 ae.setValue(annotation.annotations[a].value);
1716 if (annotation.annotations[a].secondaryStructure > ' ')
1718 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1722 if (annotation.annotations[a].colour != null
1723 && annotation.annotations[a].colour != java.awt.Color.black)
1725 ae.setColour(annotation.annotations[a].colour.getRGB());
1728 an.addAnnotationElement(ae);
1729 if (annotation.autoCalculated)
1731 // only write one non-null entry into the annotation row -
1732 // sufficient to get the visualization attributes necessary to
1740 an.setScoreOnly(true);
1742 if (!storeDS || (storeDS && !annotation.autoCalculated))
1744 // skip autocalculated annotation - these are only provided for
1746 vamsasSet.addAnnotation(an);
1752 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1754 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1755 if (settings != null)
1757 CalcIdParam vCalcIdParam = new CalcIdParam();
1758 vCalcIdParam.setCalcId(calcId);
1759 vCalcIdParam.addServiceURL(settings.getServiceURI());
1760 // generic URI allowing a third party to resolve another instance of the
1761 // service used for this calculation
1762 for (String urls : settings.getServiceURLs())
1764 vCalcIdParam.addServiceURL(urls);
1766 vCalcIdParam.setVersion("1.0");
1767 if (settings.getPreset() != null)
1769 WsParamSetI setting = settings.getPreset();
1770 vCalcIdParam.setName(setting.getName());
1771 vCalcIdParam.setDescription(setting.getDescription());
1775 vCalcIdParam.setName("");
1776 vCalcIdParam.setDescription("Last used parameters");
1778 // need to be able to recover 1) settings 2) user-defined presets or
1779 // recreate settings from preset 3) predefined settings provided by
1780 // service - or settings that can be transferred (or discarded)
1781 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1783 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1784 // todo - decide if updateImmediately is needed for any projects.
1786 return vCalcIdParam;
1791 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1794 if (calcIdParam.getVersion().equals("1.0"))
1796 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1797 .getPreferredServiceFor(calcIdParam.getServiceURL());
1798 if (service != null)
1800 WsParamSetI parmSet = null;
1803 parmSet = service.getParamStore().parseServiceParameterFile(
1804 calcIdParam.getName(), calcIdParam.getDescription(),
1805 calcIdParam.getServiceURL(),
1806 calcIdParam.getParameters().replace("|\\n|", "\n"));
1807 } catch (IOException x)
1809 warn("Couldn't parse parameter data for "
1810 + calcIdParam.getCalcId(), x);
1813 List<ArgumentI> argList = null;
1814 if (calcIdParam.getName().length() > 0)
1816 parmSet = service.getParamStore()
1817 .getPreset(calcIdParam.getName());
1818 if (parmSet != null)
1820 // TODO : check we have a good match with settings in AACon -
1821 // otherwise we'll need to create a new preset
1826 argList = parmSet.getArguments();
1829 AAConSettings settings = new AAConSettings(
1830 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1831 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1832 calcIdParam.isNeedsUpdate());
1837 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1841 throw new Error(MessageManager.formatMessage(
1842 "error.unsupported_version_calcIdparam",
1843 new Object[] { calcIdParam.toString() }));
1847 * External mapping between jalview objects and objects yielding a valid and
1848 * unique object ID string. This is null for normal Jalview project IO, but
1849 * non-null when a jalview project is being read or written as part of a
1852 IdentityHashMap jv2vobj = null;
1855 * Construct a unique ID for jvobj using either existing bindings or if none
1856 * exist, the result of the hashcode call for the object.
1859 * jalview data object
1860 * @return unique ID for referring to jvobj
1862 private String makeHashCode(Object jvobj, String altCode)
1864 if (jv2vobj != null)
1866 Object id = jv2vobj.get(jvobj);
1869 return id.toString();
1871 // check string ID mappings
1872 if (jvids2vobj != null && jvobj instanceof String)
1874 id = jvids2vobj.get(jvobj);
1878 return id.toString();
1880 // give up and warn that something has gone wrong
1881 warn("Cannot find ID for object in external mapping : " + jvobj);
1887 * return local jalview object mapped to ID, if it exists
1891 * @return null or object bound to idcode
1893 private Object retrieveExistingObj(String idcode)
1895 if (idcode != null && vobj2jv != null)
1897 return vobj2jv.get(idcode);
1903 * binding from ID strings from external mapping table to jalview data model
1906 private Hashtable vobj2jv;
1908 private Sequence createVamsasSequence(String id, SequenceI jds)
1910 return createVamsasSequence(true, id, jds, null);
1913 private Sequence createVamsasSequence(boolean recurse, String id,
1914 SequenceI jds, SequenceI parentseq)
1916 Sequence vamsasSeq = new Sequence();
1917 vamsasSeq.setId(id);
1918 vamsasSeq.setName(jds.getName());
1919 vamsasSeq.setSequence(jds.getSequenceAsString());
1920 vamsasSeq.setDescription(jds.getDescription());
1921 jalview.datamodel.DBRefEntry[] dbrefs = null;
1922 if (jds.getDatasetSequence() != null)
1924 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1925 if (jds.getDatasetSequence().getDBRefs() != null)
1927 dbrefs = jds.getDatasetSequence().getDBRefs();
1932 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1933 // dataset sequences only
1934 dbrefs = jds.getDBRefs();
1938 for (int d = 0; d < dbrefs.length; d++)
1940 DBRef dbref = new DBRef();
1941 dbref.setSource(dbrefs[d].getSource());
1942 dbref.setVersion(dbrefs[d].getVersion());
1943 dbref.setAccessionId(dbrefs[d].getAccessionId());
1944 if (dbrefs[d].hasMap())
1946 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1948 dbref.setMapping(mp);
1950 vamsasSeq.addDBRef(dbref);
1956 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1957 SequenceI parentseq, SequenceI jds, boolean recurse)
1960 if (jmp.getMap() != null)
1964 jalview.util.MapList mlst = jmp.getMap();
1965 List<int[]> r = mlst.getFromRanges();
1966 for (int[] range : r)
1968 MapListFrom mfrom = new MapListFrom();
1969 mfrom.setStart(range[0]);
1970 mfrom.setEnd(range[1]);
1971 mp.addMapListFrom(mfrom);
1973 r = mlst.getToRanges();
1974 for (int[] range : r)
1976 MapListTo mto = new MapListTo();
1977 mto.setStart(range[0]);
1978 mto.setEnd(range[1]);
1979 mp.addMapListTo(mto);
1981 mp.setMapFromUnit(mlst.getFromRatio());
1982 mp.setMapToUnit(mlst.getToRatio());
1983 if (jmp.getTo() != null)
1985 MappingChoice mpc = new MappingChoice();
1987 && (parentseq != jmp.getTo() || parentseq
1988 .getDatasetSequence() != jmp.getTo()))
1990 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1996 SequenceI ps = null;
1997 if (parentseq != jmp.getTo()
1998 && parentseq.getDatasetSequence() != jmp.getTo())
2000 // chaining dbref rather than a handshaking one
2001 jmpid = seqHash(ps = jmp.getTo());
2005 jmpid = seqHash(ps = parentseq);
2007 mpc.setDseqFor(jmpid);
2008 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2010 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2011 seqRefIds.put(mpc.getDseqFor(), ps);
2015 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2018 mp.setMappingChoice(mpc);
2024 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2025 List<UserColourScheme> userColours, JalviewModelSequence jms)
2028 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2029 boolean newucs = false;
2030 if (!userColours.contains(ucs))
2032 userColours.add(ucs);
2035 id = "ucs" + userColours.indexOf(ucs);
2038 // actually create the scheme's entry in the XML model
2039 java.awt.Color[] colours = ucs.getColours();
2040 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2041 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2043 for (int i = 0; i < colours.length; i++)
2045 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2046 col.setName(ResidueProperties.aa[i]);
2047 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2048 jbucs.addColour(col);
2050 if (ucs.getLowerCaseColours() != null)
2052 colours = ucs.getLowerCaseColours();
2053 for (int i = 0; i < colours.length; i++)
2055 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2056 col.setName(ResidueProperties.aa[i].toLowerCase());
2057 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2058 jbucs.addColour(col);
2063 uc.setUserColourScheme(jbucs);
2064 jms.addUserColours(uc);
2070 jalview.schemes.UserColourScheme getUserColourScheme(
2071 JalviewModelSequence jms, String id)
2073 UserColours[] uc = jms.getUserColours();
2074 UserColours colours = null;
2076 for (int i = 0; i < uc.length; i++)
2078 if (uc[i].getId().equals(id))
2086 java.awt.Color[] newColours = new java.awt.Color[24];
2088 for (int i = 0; i < 24; i++)
2090 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2091 .getUserColourScheme().getColour(i).getRGB(), 16));
2094 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2097 if (colours.getUserColourScheme().getColourCount() > 24)
2099 newColours = new java.awt.Color[23];
2100 for (int i = 0; i < 23; i++)
2102 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2103 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2105 ucs.setLowerCaseColours(newColours);
2112 * contains last error message (if any) encountered by XML loader.
2114 String errorMessage = null;
2117 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2118 * exceptions are raised during project XML parsing
2120 public boolean attemptversion1parse = true;
2123 * Load a jalview project archive from a jar file
2126 * - HTTP URL or filename
2128 public AlignFrame loadJalviewAlign(final String file)
2131 jalview.gui.AlignFrame af = null;
2135 // create list to store references for any new Jmol viewers created
2136 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2137 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2138 // Workaround is to make sure caller implements the JarInputStreamProvider
2140 // so we can re-open the jar input stream for each entry.
2142 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2143 af = loadJalviewAlign(jprovider);
2145 } catch (MalformedURLException e)
2147 errorMessage = "Invalid URL format for '" + file + "'";
2153 SwingUtilities.invokeAndWait(new Runnable()
2158 setLoadingFinishedForNewStructureViewers();
2161 } catch (Exception x)
2163 System.err.println("Error loading alignment: " + x.getMessage());
2169 private jarInputStreamProvider createjarInputStreamProvider(
2170 final String file) throws MalformedURLException
2173 errorMessage = null;
2174 uniqueSetSuffix = null;
2176 viewportsAdded.clear();
2177 frefedSequence = null;
2179 if (file.startsWith("http://"))
2181 url = new URL(file);
2183 final URL _url = url;
2184 return new jarInputStreamProvider()
2188 public JarInputStream getJarInputStream() throws IOException
2192 return new JarInputStream(_url.openStream());
2196 return new JarInputStream(new FileInputStream(file));
2201 public String getFilename()
2209 * Recover jalview session from a jalview project archive. Caller may
2210 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2211 * themselves. Any null fields will be initialised with default values,
2212 * non-null fields are left alone.
2217 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2219 errorMessage = null;
2220 if (uniqueSetSuffix == null)
2222 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2224 if (seqRefIds == null)
2226 seqRefIds = new HashMap<String, SequenceI>();
2228 if (frefedSequence == null)
2230 frefedSequence = new Vector();
2233 AlignFrame af = null, _af = null;
2234 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2235 final String file = jprovider.getFilename();
2238 JarInputStream jin = null;
2239 JarEntry jarentry = null;
2244 jin = jprovider.getJarInputStream();
2245 for (int i = 0; i < entryCount; i++)
2247 jarentry = jin.getNextJarEntry();
2250 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2252 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2253 JalviewModel object = new JalviewModel();
2255 Unmarshaller unmar = new Unmarshaller(object);
2256 unmar.setValidation(false);
2257 object = (JalviewModel) unmar.unmarshal(in);
2258 if (true) // !skipViewport(object))
2260 _af = loadFromObject(object, file, true, jprovider);
2261 if (object.getJalviewModelSequence().getViewportCount() > 0)
2264 if (af.viewport.isGatherViewsHere())
2266 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2272 else if (jarentry != null)
2274 // Some other file here.
2277 } while (jarentry != null);
2278 resolveFrefedSequences();
2279 } catch (IOException ex)
2281 ex.printStackTrace();
2282 errorMessage = "Couldn't locate Jalview XML file : " + file;
2283 System.err.println("Exception whilst loading jalview XML file : "
2285 } catch (Exception ex)
2287 System.err.println("Parsing as Jalview Version 2 file failed.");
2288 ex.printStackTrace(System.err);
2289 if (attemptversion1parse)
2291 // Is Version 1 Jar file?
2294 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2295 } catch (Exception ex2)
2297 System.err.println("Exception whilst loading as jalviewXMLV1:");
2298 ex2.printStackTrace();
2302 if (Desktop.instance != null)
2304 Desktop.instance.stopLoading();
2308 System.out.println("Successfully loaded archive file");
2311 ex.printStackTrace();
2313 System.err.println("Exception whilst loading jalview XML file : "
2315 } catch (OutOfMemoryError e)
2317 // Don't use the OOM Window here
2318 errorMessage = "Out of memory loading jalview XML file";
2319 System.err.println("Out of memory whilst loading jalview XML file");
2320 e.printStackTrace();
2323 if (Desktop.instance != null)
2325 Desktop.instance.stopLoading();
2329 * Regather multiple views (with the same sequence set id) to the frame (if
2330 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2331 * views instead of separate frames. Note this doesn't restore a state where
2332 * some expanded views in turn have tabbed views - the last "first tab" read
2333 * in will play the role of gatherer for all.
2335 for (AlignFrame fr : gatherToThisFrame.values())
2337 Desktop.instance.gatherViews(fr);
2340 restoreSplitFrames();
2342 if (errorMessage != null)
2350 * Try to reconstruct and display SplitFrame windows, where each contains
2351 * complementary dna and protein alignments. Done by pairing up AlignFrame
2352 * objects (created earlier) which have complementary viewport ids associated.
2354 protected void restoreSplitFrames()
2356 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2357 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2358 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2361 * Identify the DNA alignments
2363 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2366 AlignFrame af = candidate.getValue();
2367 if (af.getViewport().getAlignment().isNucleotide())
2369 dna.put(candidate.getKey().getId(), af);
2374 * Try to match up the protein complements
2376 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2379 AlignFrame af = candidate.getValue();
2380 if (!af.getViewport().getAlignment().isNucleotide())
2382 String complementId = candidate.getKey().getComplementId();
2383 // only non-null complements should be in the Map
2384 if (complementId != null && dna.containsKey(complementId))
2386 final AlignFrame dnaFrame = dna.get(complementId);
2387 SplitFrame sf = createSplitFrame(dnaFrame, af);
2388 addedToSplitFrames.add(dnaFrame);
2389 addedToSplitFrames.add(af);
2390 if (af.viewport.isGatherViewsHere())
2399 * Open any that we failed to pair up (which shouldn't happen!) as
2400 * standalone AlignFrame's.
2402 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2405 AlignFrame af = candidate.getValue();
2406 if (!addedToSplitFrames.contains(af))
2408 Viewport view = candidate.getKey();
2409 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2411 System.err.println("Failed to restore view " + view.getTitle()
2412 + " to split frame");
2417 * Gather back into tabbed views as flagged.
2419 for (SplitFrame sf : gatherTo)
2421 Desktop.instance.gatherViews(sf);
2424 splitFrameCandidates.clear();
2428 * Construct and display one SplitFrame holding DNA and protein alignments.
2431 * @param proteinFrame
2434 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2435 AlignFrame proteinFrame)
2437 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2438 String title = MessageManager.getString("label.linked_view_title");
2439 int width = (int) dnaFrame.getBounds().getWidth();
2440 int height = (int) (dnaFrame.getBounds().getHeight()
2441 + proteinFrame.getBounds().getHeight() + 50);
2444 * SplitFrame location is saved to both enclosed frames
2446 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2447 Desktop.addInternalFrame(splitFrame, title, width, height);
2450 * And compute cDNA consensus (couldn't do earlier with consensus as
2451 * mappings were not yet present)
2453 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2459 * check errorMessage for a valid error message and raise an error box in the
2460 * GUI or write the current errorMessage to stderr and then clear the error
2463 protected void reportErrors()
2465 reportErrors(false);
2468 protected void reportErrors(final boolean saving)
2470 if (errorMessage != null)
2472 final String finalErrorMessage = errorMessage;
2475 javax.swing.SwingUtilities.invokeLater(new Runnable()
2480 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2481 finalErrorMessage, "Error "
2482 + (saving ? "saving" : "loading")
2483 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2489 System.err.println("Problem loading Jalview file: " + errorMessage);
2492 errorMessage = null;
2495 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2498 * when set, local views will be updated from view stored in JalviewXML
2499 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2500 * sync if this is set to true.
2502 private final boolean updateLocalViews = false;
2505 * Returns the path to a temporary file holding the PDB file for the given PDB
2506 * id. The first time of asking, searches for a file of that name in the
2507 * Jalview project jar, and copies it to a new temporary file. Any repeat
2508 * requests just return the path to the file previously created.
2514 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2516 if (alreadyLoadedPDB.containsKey(pdbId))
2518 return alreadyLoadedPDB.get(pdbId).toString();
2521 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2522 if (tempFile != null)
2524 alreadyLoadedPDB.put(pdbId, tempFile);
2530 * Copies the jar entry of given name to a new temporary file and returns the
2531 * path to the file, or null if the entry is not found.
2534 * @param jarEntryName
2536 * a prefix for the temporary file name, must be at least three
2540 protected String copyJarEntry(jarInputStreamProvider jprovider,
2541 String jarEntryName, String prefix)
2543 BufferedReader in = null;
2544 PrintWriter out = null;
2548 JarInputStream jin = jprovider.getJarInputStream();
2550 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2551 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2552 * FileInputStream(jprovider)); }
2555 JarEntry entry = null;
2558 entry = jin.getNextJarEntry();
2559 } while (entry != null && !entry.getName().equals(jarEntryName));
2562 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2563 File outFile = File.createTempFile(prefix, ".tmp");
2564 outFile.deleteOnExit();
2565 out = new PrintWriter(new FileOutputStream(outFile));
2568 while ((data = in.readLine()) != null)
2573 String t = outFile.getAbsolutePath();
2578 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2580 } catch (Exception ex)
2582 ex.printStackTrace();
2590 } catch (IOException e)
2604 private class JvAnnotRow
2606 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2613 * persisted version of annotation row from which to take vis properties
2615 public jalview.datamodel.AlignmentAnnotation template;
2618 * original position of the annotation row in the alignment
2624 * Load alignment frame from jalview XML DOM object
2629 * filename source string
2630 * @param loadTreesAndStructures
2631 * when false only create Viewport
2633 * data source provider
2634 * @return alignment frame created from view stored in DOM
2636 AlignFrame loadFromObject(JalviewModel object, String file,
2637 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2639 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2640 Sequence[] vamsasSeq = vamsasSet.getSequence();
2642 JalviewModelSequence jms = object.getJalviewModelSequence();
2644 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2647 // ////////////////////////////////
2650 List<SequenceI> hiddenSeqs = null;
2651 jalview.datamodel.Sequence jseq;
2653 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2655 boolean multipleView = false;
2657 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2658 int vi = 0; // counter in vamsasSeq array
2659 for (int i = 0; i < jseqs.length; i++)
2661 String seqId = jseqs[i].getId();
2663 if (seqRefIds.get(seqId) != null)
2665 tmpseqs.add(seqRefIds.get(seqId));
2666 multipleView = true;
2670 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2671 vamsasSeq[vi].getSequence());
2672 jseq.setDescription(vamsasSeq[vi].getDescription());
2673 jseq.setStart(jseqs[i].getStart());
2674 jseq.setEnd(jseqs[i].getEnd());
2675 jseq.setVamsasId(uniqueSetSuffix + seqId);
2676 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2681 if (jseqs[i].getHidden())
2683 if (hiddenSeqs == null)
2685 hiddenSeqs = new ArrayList<SequenceI>();
2688 hiddenSeqs.add(seqRefIds.get(seqId));
2694 // Create the alignment object from the sequence set
2695 // ///////////////////////////////
2696 SequenceI[] orderedSeqs = tmpseqs
2697 .toArray(new SequenceI[tmpseqs.size()]);
2699 Alignment al = new Alignment(orderedSeqs);
2701 // / Add the alignment properties
2702 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2704 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2705 al.setProperty(ssp.getKey(), ssp.getValue());
2709 // SequenceFeatures are added to the DatasetSequence,
2710 // so we must create or recover the dataset before loading features
2711 // ///////////////////////////////
2712 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2714 // older jalview projects do not have a dataset id.
2715 al.setDataset(null);
2719 // recover dataset - passing on flag indicating if this a 'viewless'
2720 // sequence set (a.k.a. a stored dataset for the project)
2721 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2722 .getViewportCount() == 0);
2724 // ///////////////////////////////
2726 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2729 // load sequence features, database references and any associated PDB
2730 // structures for the alignment
2731 for (int i = 0; i < vamsasSeq.length; i++)
2733 if (jseqs[i].getFeaturesCount() > 0)
2735 Features[] features = jseqs[i].getFeatures();
2736 for (int f = 0; f < features.length; f++)
2738 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2739 features[f].getType(), features[f].getDescription(),
2740 features[f].getStatus(), features[f].getBegin(),
2741 features[f].getEnd(), features[f].getFeatureGroup());
2743 sf.setScore(features[f].getScore());
2744 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2746 OtherData keyValue = features[f].getOtherData(od);
2747 if (keyValue.getKey().startsWith("LINK"))
2749 sf.addLink(keyValue.getValue());
2753 sf.setValue(keyValue.getKey(), keyValue.getValue());
2758 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2761 if (vamsasSeq[i].getDBRefCount() > 0)
2763 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2765 if (jseqs[i].getPdbidsCount() > 0)
2767 Pdbids[] ids = jseqs[i].getPdbids();
2768 for (int p = 0; p < ids.length; p++)
2770 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2771 entry.setId(ids[p].getId());
2772 if (ids[p].getType() != null)
2774 if (ids[p].getType().equalsIgnoreCase("PDB"))
2776 entry.setType(PDBEntry.Type.PDB);
2780 entry.setType(PDBEntry.Type.FILE);
2783 if (ids[p].getFile() != null)
2785 if (!pdbloaded.containsKey(ids[p].getFile()))
2787 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2791 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2794 StructureSelectionManager.getStructureSelectionManager(
2795 Desktop.instance).registerPDBEntry(entry);
2796 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2800 } // end !multipleview
2802 // ///////////////////////////////
2803 // LOAD SEQUENCE MAPPINGS
2805 if (vamsasSet.getAlcodonFrameCount() > 0)
2807 // TODO Potentially this should only be done once for all views of an
2809 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2810 for (int i = 0; i < alc.length; i++)
2812 AlignedCodonFrame cf = new AlignedCodonFrame();
2813 if (alc[i].getAlcodMapCount() > 0)
2815 AlcodMap[] maps = alc[i].getAlcodMap();
2816 for (int m = 0; m < maps.length; m++)
2818 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2820 jalview.datamodel.Mapping mapping = null;
2821 // attach to dna sequence reference.
2822 if (maps[m].getMapping() != null)
2824 mapping = addMapping(maps[m].getMapping());
2828 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2833 frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
2838 al.addCodonFrame(cf);
2842 // ////////////////////////////////
2844 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2847 * store any annotations which forward reference a group's ID
2849 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2851 if (vamsasSet.getAnnotationCount() > 0)
2853 Annotation[] an = vamsasSet.getAnnotation();
2855 for (int i = 0; i < an.length; i++)
2857 Annotation annotation = an[i];
2860 * test if annotation is automatically calculated for this view only
2862 boolean autoForView = false;
2863 if (annotation.getLabel().equals("Quality")
2864 || annotation.getLabel().equals("Conservation")
2865 || annotation.getLabel().equals("Consensus"))
2867 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2869 if (!annotation.hasAutoCalculated())
2871 annotation.setAutoCalculated(true);
2875 || (annotation.hasAutoCalculated() && annotation
2876 .isAutoCalculated()))
2878 // remove ID - we don't recover annotation from other views for
2879 // view-specific annotation
2880 annotation.setId(null);
2883 // set visiblity for other annotation in this view
2884 String annotationId = annotation.getId();
2885 if (annotationId != null && annotationIds.containsKey(annotationId))
2887 AlignmentAnnotation jda = annotationIds.get(annotationId);
2888 // in principle Visible should always be true for annotation displayed
2889 // in multiple views
2890 if (annotation.hasVisible())
2892 jda.visible = annotation.getVisible();
2895 al.addAnnotation(jda);
2899 // Construct new annotation from model.
2900 AnnotationElement[] ae = annotation.getAnnotationElement();
2901 jalview.datamodel.Annotation[] anot = null;
2902 java.awt.Color firstColour = null;
2904 if (!annotation.getScoreOnly())
2906 anot = new jalview.datamodel.Annotation[al.getWidth()];
2907 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2909 anpos = ae[aa].getPosition();
2911 if (anpos >= anot.length)
2916 anot[anpos] = new jalview.datamodel.Annotation(
2918 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2919 (ae[aa].getSecondaryStructure() == null || ae[aa]
2920 .getSecondaryStructure().length() == 0) ? ' '
2921 : ae[aa].getSecondaryStructure().charAt(0),
2925 // JBPNote: Consider verifying dataflow for IO of secondary
2926 // structure annotation read from Stockholm files
2927 // this was added to try to ensure that
2928 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2930 // anot[ae[aa].getPosition()].displayCharacter = "";
2932 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2933 if (firstColour == null)
2935 firstColour = anot[anpos].colour;
2939 jalview.datamodel.AlignmentAnnotation jaa = null;
2941 if (annotation.getGraph())
2943 float llim = 0, hlim = 0;
2944 // if (autoForView || an[i].isAutoCalculated()) {
2947 jaa = new jalview.datamodel.AlignmentAnnotation(
2948 annotation.getLabel(), annotation.getDescription(), anot,
2949 llim, hlim, annotation.getGraphType());
2951 jaa.graphGroup = annotation.getGraphGroup();
2952 jaa._linecolour = firstColour;
2953 if (annotation.getThresholdLine() != null)
2955 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
2956 .getThresholdLine().getValue(), annotation
2957 .getThresholdLine().getLabel(), new java.awt.Color(
2958 annotation.getThresholdLine().getColour())));
2961 if (autoForView || annotation.isAutoCalculated())
2963 // Hardwire the symbol display line to ensure that labels for
2964 // histograms are displayed
2970 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2971 an[i].getDescription(), anot);
2972 jaa._linecolour = firstColour;
2974 // register new annotation
2975 if (an[i].getId() != null)
2977 annotationIds.put(an[i].getId(), jaa);
2978 jaa.annotationId = an[i].getId();
2980 // recover sequence association
2981 String sequenceRef = an[i].getSequenceRef();
2982 if (sequenceRef != null)
2984 // from 2.9 sequenceRef is to sequence id (JAL-1781)
2985 SequenceI sequence = seqRefIds.get(sequenceRef);
2986 if (sequence == null)
2988 // in pre-2.9 projects sequence ref is to sequence name
2989 sequence = al.findName(sequenceRef);
2991 if (sequence != null)
2993 jaa.createSequenceMapping(sequence, 1, true);
2994 sequence.addAlignmentAnnotation(jaa);
2997 // and make a note of any group association
2998 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3000 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3001 .get(an[i].getGroupRef());
3004 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3005 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3010 if (an[i].hasScore())
3012 jaa.setScore(an[i].getScore());
3014 if (an[i].hasVisible())
3016 jaa.visible = an[i].getVisible();
3019 if (an[i].hasCentreColLabels())
3021 jaa.centreColLabels = an[i].getCentreColLabels();
3024 if (an[i].hasScaleColLabels())
3026 jaa.scaleColLabel = an[i].getScaleColLabels();
3028 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3030 // newer files have an 'autoCalculated' flag and store calculation
3031 // state in viewport properties
3032 jaa.autoCalculated = true; // means annotation will be marked for
3033 // update at end of load.
3035 if (an[i].hasGraphHeight())
3037 jaa.graphHeight = an[i].getGraphHeight();
3039 if (an[i].hasBelowAlignment())
3041 jaa.belowAlignment = an[i].isBelowAlignment();
3043 jaa.setCalcId(an[i].getCalcId());
3044 if (an[i].getPropertyCount() > 0)
3046 for (jalview.schemabinding.version2.Property prop : an[i]
3049 jaa.setProperty(prop.getName(), prop.getValue());
3052 if (jaa.autoCalculated)
3054 autoAlan.add(new JvAnnotRow(i, jaa));
3057 // if (!autoForView)
3059 // add autocalculated group annotation and any user created annotation
3061 al.addAnnotation(jaa);
3065 // ///////////////////////
3067 // Create alignment markup and styles for this view
3068 if (jms.getJGroupCount() > 0)
3070 JGroup[] groups = jms.getJGroup();
3071 boolean addAnnotSchemeGroup = false;
3072 for (int i = 0; i < groups.length; i++)
3074 JGroup jGroup = groups[i];
3075 ColourSchemeI cs = null;
3076 if (jGroup.getColour() != null)
3078 if (jGroup.getColour().startsWith("ucs"))
3080 cs = getUserColourScheme(jms, jGroup.getColour());
3082 else if (jGroup.getColour().equals("AnnotationColourGradient")
3083 && jGroup.getAnnotationColours() != null)
3085 addAnnotSchemeGroup = true;
3090 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3095 cs.setThreshold(jGroup.getPidThreshold(), true);
3099 Vector<SequenceI> seqs = new Vector<SequenceI>();
3101 for (int s = 0; s < jGroup.getSeqCount(); s++)
3103 String seqId = jGroup.getSeq(s) + "";
3104 SequenceI ts = seqRefIds.get(seqId);
3108 seqs.addElement(ts);
3112 if (seqs.size() < 1)
3117 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3118 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3119 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3121 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3123 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3124 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3125 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3126 .isShowUnconserved() : false);
3127 sg.thresholdTextColour = jGroup.getTextColThreshold();
3128 if (jGroup.hasShowConsensusHistogram())
3130 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3133 if (jGroup.hasShowSequenceLogo())
3135 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3137 if (jGroup.hasNormaliseSequenceLogo())
3139 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3141 if (jGroup.hasIgnoreGapsinConsensus())
3143 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3145 if (jGroup.getConsThreshold() != 0)
3147 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3148 "All", ResidueProperties.propHash, 3,
3149 sg.getSequences(null), 0, sg.getWidth() - 1);
3151 c.verdict(false, 25);
3152 sg.cs.setConservation(c);
3155 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3157 // re-instate unique group/annotation row reference
3158 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3162 for (AlignmentAnnotation jaa : jaal)
3165 if (jaa.autoCalculated)
3167 // match up and try to set group autocalc alignment row for this
3169 if (jaa.label.startsWith("Consensus for "))
3171 sg.setConsensus(jaa);
3173 // match up and try to set group autocalc alignment row for this
3175 if (jaa.label.startsWith("Conservation for "))
3177 sg.setConservationRow(jaa);
3184 if (addAnnotSchemeGroup)
3186 // reconstruct the annotation colourscheme
3187 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3188 null, al, jms, false);
3194 // only dataset in this model, so just return.
3197 // ///////////////////////////////
3200 // If we just load in the same jar file again, the sequenceSetId
3201 // will be the same, and we end up with multiple references
3202 // to the same sequenceSet. We must modify this id on load
3203 // so that each load of the file gives a unique id
3204 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3205 String viewId = (view.getId() == null ? null : view.getId()
3207 AlignFrame af = null;
3208 AlignViewport av = null;
3209 // now check to see if we really need to create a new viewport.
3210 if (multipleView && viewportsAdded.size() == 0)
3212 // We recovered an alignment for which a viewport already exists.
3213 // TODO: fix up any settings necessary for overlaying stored state onto
3214 // state recovered from another document. (may not be necessary).
3215 // we may need a binding from a viewport in memory to one recovered from
3217 // and then recover its containing af to allow the settings to be applied.
3218 // TODO: fix for vamsas demo
3220 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3222 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3223 if (seqsetobj != null)
3225 if (seqsetobj instanceof String)
3227 uniqueSeqSetId = (String) seqsetobj;
3229 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3235 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3241 * indicate that annotation colours are applied across all groups (pre
3242 * Jalview 2.8.1 behaviour)
3244 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3245 "2.8.1", object.getVersion());
3247 AlignmentPanel ap = null;
3248 boolean isnewview = true;
3251 // Check to see if this alignment already has a view id == viewId
3252 jalview.gui.AlignmentPanel views[] = Desktop
3253 .getAlignmentPanels(uniqueSeqSetId);
3254 if (views != null && views.length > 0)
3256 for (int v = 0; v < views.length; v++)
3258 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3260 // recover the existing alignpanel, alignframe, viewport
3261 af = views[v].alignFrame;
3264 // TODO: could even skip resetting view settings if we don't want to
3265 // change the local settings from other jalview processes
3274 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3275 uniqueSeqSetId, viewId, autoAlan);
3281 * Load any trees, PDB structures and viewers
3283 * Not done if flag is false (when this method is used for New View)
3285 if (loadTreesAndStructures)
3287 loadTrees(jms, view, af, av, ap);
3288 loadPDBStructures(jprovider, jseqs, af, ap);
3289 loadRnaViewers(jprovider, jseqs, ap);
3291 // and finally return.
3296 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3297 * panel is restored from separate jar entries, two (gapped and trimmed) per
3298 * sequence and secondary structure.
3300 * Currently each viewer shows just one sequence and structure (gapped and
3301 * trimmed), however this method is designed to support multiple sequences or
3302 * structures in viewers if wanted in future.
3308 private void loadRnaViewers(jarInputStreamProvider jprovider,
3309 JSeq[] jseqs, AlignmentPanel ap)
3312 * scan the sequences for references to viewers; create each one the first
3313 * time it is referenced, add Rna models to existing viewers
3315 for (JSeq jseq : jseqs)
3317 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3319 RnaViewer viewer = jseq.getRnaViewer(i);
3320 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3321 uniqueSetSuffix, ap);
3323 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3325 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3326 SequenceI seq = seqRefIds.get(jseq.getId());
3327 AlignmentAnnotation ann = this.annotationIds.get(ss
3328 .getAnnotationId());
3331 * add the structure to the Varna display (with session state copied
3332 * from the jar to a temporary file)
3334 boolean gapped = ss.isGapped();
3335 String rnaTitle = ss.getTitle();
3336 String sessionState = ss.getViewerState();
3337 String tempStateFile = copyJarEntry(jprovider, sessionState,
3339 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3340 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3342 appVarna.setInitialSelection(viewer.getSelectedRna());
3348 * Locate and return an already instantiated matching AppVarna, or create one
3352 * @param viewIdSuffix
3356 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3357 String viewIdSuffix, AlignmentPanel ap)
3360 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3361 * if load is repeated
3363 String postLoadId = viewer.getViewId() + viewIdSuffix;
3364 for (JInternalFrame frame : getAllFrames())
3366 if (frame instanceof AppVarna)
3368 AppVarna varna = (AppVarna) frame;
3369 if (postLoadId.equals(varna.getViewId()))
3371 // this viewer is already instantiated
3372 // could in future here add ap as another 'parent' of the
3373 // AppVarna window; currently just 1-to-many
3380 * viewer not found - make it
3382 RnaViewerModel model = new RnaViewerModel(postLoadId,
3383 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3384 viewer.getWidth(), viewer.getHeight(),
3385 viewer.getDividerLocation());
3386 AppVarna varna = new AppVarna(model, ap);
3392 * Load any saved trees
3400 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3401 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3403 // TODO result of automated refactoring - are all these parameters needed?
3406 for (int t = 0; t < jms.getTreeCount(); t++)
3409 Tree tree = jms.getTree(t);
3411 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3414 tp = af.ShowNewickTree(
3415 new jalview.io.NewickFile(tree.getNewick()),
3416 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3417 tree.getXpos(), tree.getYpos());
3418 if (tree.getId() != null)
3420 // perhaps bind the tree id to something ?
3425 // update local tree attributes ?
3426 // TODO: should check if tp has been manipulated by user - if so its
3427 // settings shouldn't be modified
3428 tp.setTitle(tree.getTitle());
3429 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3430 .getWidth(), tree.getHeight()));
3431 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3434 tp.treeCanvas.av = av; // af.viewport;
3435 tp.treeCanvas.ap = ap; // af.alignPanel;
3440 warn("There was a problem recovering stored Newick tree: \n"
3441 + tree.getNewick());
3445 tp.fitToWindow.setState(tree.getFitToWindow());
3446 tp.fitToWindow_actionPerformed(null);
3448 if (tree.getFontName() != null)
3450 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3451 .getFontStyle(), tree.getFontSize()));
3455 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3456 .getFontStyle(), tree.getFontSize()));
3459 tp.showPlaceholders(tree.getMarkUnlinked());
3460 tp.showBootstrap(tree.getShowBootstrap());
3461 tp.showDistances(tree.getShowDistances());
3463 tp.treeCanvas.threshold = tree.getThreshold();
3465 if (tree.getCurrentTree())
3467 af.viewport.setCurrentTree(tp.getTree());
3471 } catch (Exception ex)
3473 ex.printStackTrace();
3478 * Load and link any saved structure viewers.
3485 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3486 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3489 * Run through all PDB ids on the alignment, and collect mappings between
3490 * distinct view ids and all sequences referring to that view.
3492 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3494 for (int i = 0; i < jseqs.length; i++)
3496 if (jseqs[i].getPdbidsCount() > 0)
3498 Pdbids[] ids = jseqs[i].getPdbids();
3499 for (int p = 0; p < ids.length; p++)
3501 final int structureStateCount = ids[p].getStructureStateCount();
3502 for (int s = 0; s < structureStateCount; s++)
3504 // check to see if we haven't already created this structure view
3505 final StructureState structureState = ids[p]
3506 .getStructureState(s);
3507 String sviewid = (structureState.getViewId() == null) ? null
3508 : structureState.getViewId() + uniqueSetSuffix;
3509 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3510 // Originally : ids[p].getFile()
3511 // : TODO: verify external PDB file recovery still works in normal
3512 // jalview project load
3513 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3514 jpdb.setId(ids[p].getId());
3516 int x = structureState.getXpos();
3517 int y = structureState.getYpos();
3518 int width = structureState.getWidth();
3519 int height = structureState.getHeight();
3521 // Probably don't need to do this anymore...
3522 // Desktop.desktop.getComponentAt(x, y);
3523 // TODO: NOW: check that this recovers the PDB file correctly.
3524 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3525 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3527 if (sviewid == null)
3529 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3532 if (!structureViewers.containsKey(sviewid))
3534 structureViewers.put(sviewid,
3535 new StructureViewerModel(x, y, width, height, false,
3536 false, true, structureState.getViewId(),
3537 structureState.getType()));
3538 // Legacy pre-2.7 conversion JAL-823 :
3539 // do not assume any view has to be linked for colour by
3543 // assemble String[] { pdb files }, String[] { id for each
3544 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3545 // seqs_file 2}, boolean[] {
3546 // linkAlignPanel,superposeWithAlignpanel}} from hash
3547 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3548 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3549 | (structureState.hasAlignwithAlignPanel() ? structureState
3550 .getAlignwithAlignPanel() : false));
3553 * Default colour by linked panel to false if not specified (e.g.
3554 * for pre-2.7 projects)
3556 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3557 colourWithAlignPanel |= (structureState
3558 .hasColourwithAlignPanel() ? structureState
3559 .getColourwithAlignPanel() : false);
3560 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3563 * Default colour by viewer to true if not specified (e.g. for
3566 boolean colourByViewer = jmoldat.isColourByViewer();
3567 colourByViewer &= structureState.hasColourByJmol() ? structureState
3568 .getColourByJmol() : true;
3569 jmoldat.setColourByViewer(colourByViewer);
3571 if (jmoldat.getStateData().length() < structureState
3572 .getContent().length())
3575 jmoldat.setStateData(structureState.getContent());
3578 if (ids[p].getFile() != null)
3580 File mapkey = new File(ids[p].getFile());
3581 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3582 if (seqstrmaps == null)
3584 jmoldat.getFileData().put(
3586 seqstrmaps = jmoldat.new StructureData(pdbFile,
3589 if (!seqstrmaps.getSeqList().contains(seq))
3591 seqstrmaps.getSeqList().add(seq);
3597 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");
3604 // Instantiate the associated structure views
3605 for (Entry<String, StructureViewerModel> entry : structureViewers
3610 createOrLinkStructureViewer(entry, af, ap, jprovider);
3611 } catch (Exception e)
3613 System.err.println("Error loading structure viewer: "
3615 // failed - try the next one
3627 protected void createOrLinkStructureViewer(
3628 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3629 AlignmentPanel ap, jarInputStreamProvider jprovider)
3631 final StructureViewerModel stateData = viewerData.getValue();
3634 * Search for any viewer windows already open from other alignment views
3635 * that exactly match the stored structure state
3637 StructureViewerBase comp = findMatchingViewer(viewerData);
3641 linkStructureViewer(ap, comp, stateData);
3646 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3647 * "viewer_"+stateData.viewId
3649 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3651 createChimeraViewer(viewerData, af, jprovider);
3656 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3658 createJmolViewer(viewerData, af, jprovider);
3663 * Create a new Chimera viewer.
3669 protected void createChimeraViewer(
3670 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3671 jarInputStreamProvider jprovider)
3673 StructureViewerModel data = viewerData.getValue();
3674 String chimeraSessionFile = data.getStateData();
3677 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3679 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3680 * 'uniquified' sviewid used to reconstruct the viewer here
3682 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3683 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3686 Set<Entry<File, StructureData>> fileData = data.getFileData()
3688 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3689 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3690 for (Entry<File, StructureData> pdb : fileData)
3692 String filePath = pdb.getValue().getFilePath();
3693 String pdbId = pdb.getValue().getPdbId();
3694 // pdbs.add(new PDBEntry(filePath, pdbId));
3695 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3696 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3697 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3701 boolean colourByChimera = data.isColourByViewer();
3702 boolean colourBySequence = data.isColourWithAlignPanel();
3704 // TODO use StructureViewer as a factory here, see JAL-1761
3705 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3706 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3708 String newViewId = viewerData.getKey();
3710 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3711 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3712 colourBySequence, newViewId);
3713 cvf.setSize(data.getWidth(), data.getHeight());
3714 cvf.setLocation(data.getX(), data.getY());
3718 * Create a new Jmol window. First parse the Jmol state to translate filenames
3719 * loaded into the view, and record the order in which files are shown in the
3720 * Jmol view, so we can add the sequence mappings in same order.
3726 protected void createJmolViewer(
3727 final Entry<String, StructureViewerModel> viewerData,
3728 AlignFrame af, jarInputStreamProvider jprovider)
3730 final StructureViewerModel svattrib = viewerData.getValue();
3731 String state = svattrib.getStateData();
3734 * Pre-2.9: state element value is the Jmol state string
3736 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3739 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3741 state = readJarEntry(jprovider,
3742 getViewerJarEntryName(svattrib.getViewId()));
3745 List<String> pdbfilenames = new ArrayList<String>();
3746 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3747 List<String> pdbids = new ArrayList<String>();
3748 StringBuilder newFileLoc = new StringBuilder(64);
3749 int cp = 0, ncp, ecp;
3750 Map<File, StructureData> oldFiles = svattrib.getFileData();
3751 while ((ncp = state.indexOf("load ", cp)) > -1)
3755 // look for next filename in load statement
3756 newFileLoc.append(state.substring(cp,
3757 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3758 String oldfilenam = state.substring(ncp,
3759 ecp = state.indexOf("\"", ncp));
3760 // recover the new mapping data for this old filename
3761 // have to normalize filename - since Jmol and jalview do
3763 // translation differently.
3764 StructureData filedat = oldFiles.get(new File(oldfilenam));
3765 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3766 pdbfilenames.add(filedat.getFilePath());
3767 pdbids.add(filedat.getPdbId());
3768 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3769 newFileLoc.append("\"");
3770 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3771 // look for next file statement.
3772 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3776 // just append rest of state
3777 newFileLoc.append(state.substring(cp));
3781 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3782 newFileLoc = new StringBuilder(state);
3783 newFileLoc.append("; load append ");
3784 for (File id : oldFiles.keySet())
3786 // add this and any other pdb files that should be present in
3788 StructureData filedat = oldFiles.get(id);
3789 newFileLoc.append(filedat.getFilePath());
3790 pdbfilenames.add(filedat.getFilePath());
3791 pdbids.add(filedat.getPdbId());
3792 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3793 newFileLoc.append(" \"");
3794 newFileLoc.append(filedat.getFilePath());
3795 newFileLoc.append("\"");
3798 newFileLoc.append(";");
3801 if (newFileLoc.length() == 0)
3805 int histbug = newFileLoc.indexOf("history = ");
3809 * change "history = [true|false];" to "history = [1|0];"
3812 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3813 String val = (diff == -1) ? null : newFileLoc
3814 .substring(histbug, diff);
3815 if (val != null && val.length() >= 4)
3817 if (val.contains("e")) // eh? what can it be?
3819 if (val.trim().equals("true"))
3827 newFileLoc.replace(histbug, diff, val);
3832 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3834 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3835 final SequenceI[][] sq = seqmaps
3836 .toArray(new SequenceI[seqmaps.size()][]);
3837 final String fileloc = newFileLoc.toString();
3838 final String sviewid = viewerData.getKey();
3839 final AlignFrame alf = af;
3840 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3841 svattrib.getWidth(), svattrib.getHeight());
3844 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3849 JalviewStructureDisplayI sview = null;
3852 sview = new StructureViewer(alf.alignPanel
3853 .getStructureSelectionManager()).createView(
3854 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3855 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3856 addNewStructureViewer(sview);
3857 } catch (OutOfMemoryError ex)
3859 new OOMWarning("restoring structure view for PDB id " + id,
3860 (OutOfMemoryError) ex.getCause());
3861 if (sview != null && sview.isVisible())
3863 sview.closeViewer(false);
3864 sview.setVisible(false);
3870 } catch (InvocationTargetException ex)
3872 warn("Unexpected error when opening Jmol view.", ex);
3874 } catch (InterruptedException e)
3876 // e.printStackTrace();
3882 * Generates a name for the entry in the project jar file to hold state
3883 * information for a structure viewer
3888 protected String getViewerJarEntryName(String viewId)
3890 return VIEWER_PREFIX + viewId;
3894 * Returns any open frame that matches given structure viewer data. The match
3895 * is based on the unique viewId, or (for older project versions) the frame's
3901 protected StructureViewerBase findMatchingViewer(
3902 Entry<String, StructureViewerModel> viewerData)
3904 final String sviewid = viewerData.getKey();
3905 final StructureViewerModel svattrib = viewerData.getValue();
3906 StructureViewerBase comp = null;
3907 JInternalFrame[] frames = getAllFrames();
3908 for (JInternalFrame frame : frames)
3910 if (frame instanceof StructureViewerBase)
3913 * Post jalview 2.4 schema includes structure view id
3916 && ((StructureViewerBase) frame).getViewId()
3919 comp = (StructureViewerBase) frame;
3920 break; // break added in 2.9
3923 * Otherwise test for matching position and size of viewer frame
3925 else if (frame.getX() == svattrib.getX()
3926 && frame.getY() == svattrib.getY()
3927 && frame.getHeight() == svattrib.getHeight()
3928 && frame.getWidth() == svattrib.getWidth())
3930 comp = (StructureViewerBase) frame;
3931 // no break in faint hope of an exact match on viewId
3939 * Link an AlignmentPanel to an existing structure viewer.
3944 * @param useinViewerSuperpos
3945 * @param usetoColourbyseq
3946 * @param viewerColouring
3948 protected void linkStructureViewer(AlignmentPanel ap,
3949 StructureViewerBase viewer, StructureViewerModel stateData)
3951 // NOTE: if the jalview project is part of a shared session then
3952 // view synchronization should/could be done here.
3954 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
3955 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
3956 final boolean viewerColouring = stateData.isColourByViewer();
3957 Map<File, StructureData> oldFiles = stateData.getFileData();
3960 * Add mapping for sequences in this view to an already open viewer
3962 final AAStructureBindingModel binding = viewer.getBinding();
3963 for (File id : oldFiles.keySet())
3965 // add this and any other pdb files that should be present in the
3967 StructureData filedat = oldFiles.get(id);
3968 String pdbFile = filedat.getFilePath();
3969 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3970 binding.getSsm().setMapping(seq, null, pdbFile,
3971 jalview.io.AppletFormatAdapter.FILE);
3972 binding.addSequenceForStructFile(pdbFile, seq);
3974 // and add the AlignmentPanel's reference to the view panel
3975 viewer.addAlignmentPanel(ap);
3976 if (useinViewerSuperpos)
3978 viewer.useAlignmentPanelForSuperposition(ap);
3982 viewer.excludeAlignmentPanelForSuperposition(ap);
3984 if (usetoColourbyseq)
3986 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3990 viewer.excludeAlignmentPanelForColourbyseq(ap);
3995 * Get all frames within the Desktop.
3999 protected JInternalFrame[] getAllFrames()
4001 JInternalFrame[] frames = null;
4002 // TODO is this necessary - is it safe - risk of hanging?
4007 frames = Desktop.desktop.getAllFrames();
4008 } catch (ArrayIndexOutOfBoundsException e)
4010 // occasional No such child exceptions are thrown here...
4014 } catch (InterruptedException f)
4018 } while (frames == null);
4025 * - minimum version we are comparing against
4027 * - version of data being processsed.
4028 * @return true if version is development/null or evaluates to the same or
4029 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
4031 public static boolean isVersionStringLaterThan(String supported,
4034 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4035 || version.equalsIgnoreCase("Test")
4036 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4038 System.err.println("Assuming project file with "
4039 + (version == null ? "null" : version)
4040 + " is compatible with Jalview version " + supported);
4045 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
4047 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
4049 // convert b to decimal to catch bugfix releases within a series
4050 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
4051 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
4054 float supportedVersionToken = Float.parseFloat(curT);
4055 float myVersiontoken = Float.parseFloat(fileT);
4056 if (supportedVersionToken > myVersiontoken)
4058 // current version is newer than the version that wrote the file
4061 if (supportedVersionToken < myVersiontoken)
4063 // current version is older than the version that wrote the file
4066 } catch (NumberFormatException nfe)
4069 .println("** WARNING: Version comparison failed for tokens ("
4073 + ")\n** Current: '"
4074 + supported + "' and Version: '" + version + "'");
4077 if (currentV.hasMoreElements())
4079 // fileV has no minor version but identical series to current
4086 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4088 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4090 if (newStructureViewers != null)
4092 sview.getBinding().setFinishedLoadingFromArchive(false);
4093 newStructureViewers.add(sview);
4097 protected void setLoadingFinishedForNewStructureViewers()
4099 if (newStructureViewers != null)
4101 for (JalviewStructureDisplayI sview : newStructureViewers)
4103 sview.getBinding().setFinishedLoadingFromArchive(true);
4105 newStructureViewers.clear();
4106 newStructureViewers = null;
4110 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4111 List<SequenceI> hiddenSeqs, Alignment al,
4112 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4113 String viewId, List<JvAnnotRow> autoAlan)
4115 AlignFrame af = null;
4116 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4117 uniqueSeqSetId, viewId);
4119 af.setFileName(file, "Jalview");
4121 for (int i = 0; i < JSEQ.length; i++)
4123 af.viewport.setSequenceColour(af.viewport.getAlignment()
4124 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4127 af.viewport.setGatherViewsHere(view.getGatheredViews());
4129 if (view.getSequenceSetId() != null)
4131 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4133 af.viewport.setSequenceSetId(uniqueSeqSetId);
4136 // propagate shared settings to this new view
4137 af.viewport.setHistoryList(av.getHistoryList());
4138 af.viewport.setRedoList(av.getRedoList());
4142 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4144 // TODO: check if this method can be called repeatedly without
4145 // side-effects if alignpanel already registered.
4146 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4148 // apply Hidden regions to view.
4149 if (hiddenSeqs != null)
4151 for (int s = 0; s < JSEQ.length; s++)
4153 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
4155 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4158 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
4160 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
4163 // jalview.datamodel.SequenceI[] hseqs = new
4164 // jalview.datamodel.SequenceI[hiddenSeqs
4167 // for (int s = 0; s < hiddenSeqs.size(); s++)
4169 // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
4172 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4174 af.viewport.hideSequence(hseqs);
4177 // recover view properties and display parameters
4178 if (view.getViewName() != null)
4180 af.viewport.viewName = view.getViewName();
4181 af.setInitialTabVisible();
4183 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4186 af.viewport.setShowAnnotation(view.getShowAnnotation());
4187 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4189 af.viewport.setColourText(view.getShowColourText());
4191 af.viewport.setConservationSelected(view.getConservationSelected());
4192 af.viewport.setShowJVSuffix(view.getShowFullId());
4193 af.viewport.setRightAlignIds(view.getRightAlignIds());
4194 af.viewport.setFont(
4195 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4196 .getFontSize()), true);
4197 ViewStyleI vs = af.viewport.getViewStyle();
4198 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4199 af.viewport.setViewStyle(vs);
4200 // TODO: allow custom charWidth/Heights to be restored by updating them
4201 // after setting font - which means set above to false
4202 af.viewport.setRenderGaps(view.getRenderGaps());
4203 af.viewport.setWrapAlignment(view.getWrapAlignment());
4204 af.viewport.setShowAnnotation(view.getShowAnnotation());
4206 af.viewport.setShowBoxes(view.getShowBoxes());
4208 af.viewport.setShowText(view.getShowText());
4210 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4211 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4212 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4213 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4214 .isShowUnconserved() : false);
4215 af.viewport.setStartRes(view.getStartRes());
4216 af.viewport.setStartSeq(view.getStartSeq());
4217 af.alignPanel.updateLayout();
4218 ColourSchemeI cs = null;
4219 // apply colourschemes
4220 if (view.getBgColour() != null)
4222 if (view.getBgColour().startsWith("ucs"))
4224 cs = getUserColourScheme(jms, view.getBgColour());
4226 else if (view.getBgColour().startsWith("Annotation"))
4228 AnnotationColours viewAnnColour = view.getAnnotationColours();
4229 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4236 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4241 cs.setThreshold(view.getPidThreshold(), true);
4242 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4246 af.viewport.setGlobalColourScheme(cs);
4247 af.viewport.setColourAppliesToAllGroups(false);
4249 if (view.getConservationSelected() && cs != null)
4251 cs.setConservationInc(view.getConsThreshold());
4254 af.changeColour(cs);
4256 af.viewport.setColourAppliesToAllGroups(true);
4258 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4260 if (view.hasCentreColumnLabels())
4262 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4264 if (view.hasIgnoreGapsinConsensus())
4266 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4269 if (view.hasFollowHighlight())
4271 af.viewport.setFollowHighlight(view.getFollowHighlight());
4273 if (view.hasFollowSelection())
4275 af.viewport.followSelection = view.getFollowSelection();
4277 if (view.hasShowConsensusHistogram())
4279 af.viewport.setShowConsensusHistogram(view
4280 .getShowConsensusHistogram());
4284 af.viewport.setShowConsensusHistogram(true);
4286 if (view.hasShowSequenceLogo())
4288 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4292 af.viewport.setShowSequenceLogo(false);
4294 if (view.hasNormaliseSequenceLogo())
4296 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4298 if (view.hasShowDbRefTooltip())
4300 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4302 if (view.hasShowNPfeatureTooltip())
4304 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4306 if (view.hasShowGroupConsensus())
4308 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4312 af.viewport.setShowGroupConsensus(false);
4314 if (view.hasShowGroupConservation())
4316 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4320 af.viewport.setShowGroupConservation(false);
4323 // recover featre settings
4324 if (jms.getFeatureSettings() != null)
4326 FeaturesDisplayed fdi;
4327 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4328 String[] renderOrder = new String[jms.getFeatureSettings()
4329 .getSettingCount()];
4330 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4331 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4333 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4335 Setting setting = jms.getFeatureSettings().getSetting(fs);
4336 if (setting.hasMincolour())
4338 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4339 new Color(setting.getMincolour()), new Color(
4340 setting.getColour()), setting.getMin(),
4341 setting.getMax()) : new FeatureColour(new Color(
4342 setting.getMincolour()), new Color(setting.getColour()),
4344 if (setting.hasThreshold())
4346 gc.setThreshold(setting.getThreshold());
4347 int threshstate = setting.getThreshstate();
4348 // -1 = None, 0 = Below, 1 = Above threshold
4349 if (threshstate == 0)
4351 gc.setBelowThreshold(true);
4353 else if (threshstate == 1)
4355 gc.setAboveThreshold(true);
4358 gc.setAutoScaled(true); // default
4359 if (setting.hasAutoScale())
4361 gc.setAutoScaled(setting.getAutoScale());
4363 if (setting.hasColourByLabel())
4365 gc.setColourByLabel(setting.getColourByLabel());
4367 // and put in the feature colour table.
4368 featureColours.put(setting.getType(), gc);
4372 featureColours.put(setting.getType(), new FeatureColour(
4373 new Color(setting.getColour())));
4375 renderOrder[fs] = setting.getType();
4376 if (setting.hasOrder())
4378 featureOrder.put(setting.getType(), setting.getOrder());
4382 featureOrder.put(setting.getType(), new Float(fs
4383 / jms.getFeatureSettings().getSettingCount()));
4385 if (setting.getDisplay())
4387 fdi.setVisible(setting.getType());
4390 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4391 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4393 Group grp = jms.getFeatureSettings().getGroup(gs);
4394 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4396 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4397 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4398 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4399 FeatureRendererSettings frs = new FeatureRendererSettings(
4400 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4401 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4402 .transferSettings(frs);
4406 if (view.getHiddenColumnsCount() > 0)
4408 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4410 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4411 .getHiddenColumns(c).getEnd() // +1
4415 if (view.getCalcIdParam() != null)
4417 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4419 if (calcIdParam != null)
4421 if (recoverCalcIdParam(calcIdParam, af.viewport))
4426 warn("Couldn't recover parameters for "
4427 + calcIdParam.getCalcId());
4432 af.setMenusFromViewport(af.viewport);
4434 // TODO: we don't need to do this if the viewport is aready visible.
4436 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4437 * has a 'cdna/protein complement' view, in which case save it in order to
4438 * populate a SplitFrame once all views have been read in.
4440 String complementaryViewId = view.getComplementId();
4441 if (complementaryViewId == null)
4443 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4445 // recompute any autoannotation
4446 af.alignPanel.updateAnnotation(false, true);
4447 reorderAutoannotation(af, al, autoAlan);
4448 af.alignPanel.alignmentChanged();
4452 splitFrameCandidates.put(view, af);
4457 private ColourSchemeI constructAnnotationColour(
4458 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
4459 JalviewModelSequence jms, boolean checkGroupAnnColour)
4461 boolean propagateAnnColour = false;
4462 ColourSchemeI cs = null;
4463 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4464 if (checkGroupAnnColour && al.getGroups() != null
4465 && al.getGroups().size() > 0)
4467 // pre 2.8.1 behaviour
4468 // check to see if we should transfer annotation colours
4469 propagateAnnColour = true;
4470 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4472 if (sg.cs instanceof AnnotationColourGradient)
4474 propagateAnnColour = false;
4478 // int find annotation
4479 if (annAlignment.getAlignmentAnnotation() != null)
4481 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4483 if (annAlignment.getAlignmentAnnotation()[i].label
4484 .equals(viewAnnColour.getAnnotation()))
4486 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4488 annAlignment.getAlignmentAnnotation()[i]
4489 .setThreshold(new jalview.datamodel.GraphLine(
4490 viewAnnColour.getThreshold(), "Threshold",
4491 java.awt.Color.black)
4496 if (viewAnnColour.getColourScheme().equals("None"))
4498 cs = new AnnotationColourGradient(
4499 annAlignment.getAlignmentAnnotation()[i],
4500 new java.awt.Color(viewAnnColour.getMinColour()),
4501 new java.awt.Color(viewAnnColour.getMaxColour()),
4502 viewAnnColour.getAboveThreshold());
4504 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4506 cs = new AnnotationColourGradient(
4507 annAlignment.getAlignmentAnnotation()[i],
4508 getUserColourScheme(jms,
4509 viewAnnColour.getColourScheme()),
4510 viewAnnColour.getAboveThreshold());
4514 cs = new AnnotationColourGradient(
4515 annAlignment.getAlignmentAnnotation()[i],
4516 ColourSchemeProperty.getColour(al,
4517 viewAnnColour.getColourScheme()),
4518 viewAnnColour.getAboveThreshold());
4520 if (viewAnnColour.hasPerSequence())
4522 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4525 if (viewAnnColour.hasPredefinedColours())
4527 ((AnnotationColourGradient) cs)
4528 .setPredefinedColours(viewAnnColour
4529 .isPredefinedColours());
4531 if (propagateAnnColour && al.getGroups() != null)
4533 // Also use these settings for all the groups
4534 for (int g = 0; g < al.getGroups().size(); g++)
4536 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4544 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4545 * new AnnotationColourGradient(
4546 * annAlignment.getAlignmentAnnotation()[i], new
4547 * java.awt.Color(viewAnnColour. getMinColour()), new
4548 * java.awt.Color(viewAnnColour. getMaxColour()),
4549 * viewAnnColour.getAboveThreshold()); } else
4552 sg.cs = new AnnotationColourGradient(
4553 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4554 viewAnnColour.getAboveThreshold());
4555 if (cs instanceof AnnotationColourGradient)
4557 if (viewAnnColour.hasPerSequence())
4559 ((AnnotationColourGradient) cs)
4560 .setSeqAssociated(viewAnnColour.isPerSequence());
4562 if (viewAnnColour.hasPredefinedColours())
4564 ((AnnotationColourGradient) cs)
4565 .setPredefinedColours(viewAnnColour
4566 .isPredefinedColours());
4582 private void reorderAutoannotation(AlignFrame af, Alignment al,
4583 List<JvAnnotRow> autoAlan)
4585 // copy over visualization settings for autocalculated annotation in the
4587 if (al.getAlignmentAnnotation() != null)
4590 * Kludge for magic autoannotation names (see JAL-811)
4592 String[] magicNames = new String[] { "Consensus", "Quality",
4594 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4595 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4596 for (String nm : magicNames)
4598 visan.put(nm, nullAnnot);
4600 for (JvAnnotRow auan : autoAlan)
4602 visan.put(auan.template.label
4603 + (auan.template.getCalcId() == null ? "" : "\t"
4604 + auan.template.getCalcId()), auan);
4606 int hSize = al.getAlignmentAnnotation().length;
4607 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4608 // work through any autoCalculated annotation already on the view
4609 // removing it if it should be placed in a different location on the
4610 // annotation panel.
4611 List<String> remains = new ArrayList<String>(visan.keySet());
4612 for (int h = 0; h < hSize; h++)
4614 jalview.datamodel.AlignmentAnnotation jalan = al
4615 .getAlignmentAnnotation()[h];
4616 if (jalan.autoCalculated)
4619 JvAnnotRow valan = visan.get(k = jalan.label);
4620 if (jalan.getCalcId() != null)
4622 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4627 // delete the auto calculated row from the alignment
4628 al.deleteAnnotation(jalan, false);
4632 if (valan != nullAnnot)
4634 if (jalan != valan.template)
4636 // newly created autoannotation row instance
4637 // so keep a reference to the visible annotation row
4638 // and copy over all relevant attributes
4639 if (valan.template.graphHeight >= 0)
4642 jalan.graphHeight = valan.template.graphHeight;
4644 jalan.visible = valan.template.visible;
4646 reorder.add(new JvAnnotRow(valan.order, jalan));
4651 // Add any (possibly stale) autocalculated rows that were not appended to
4652 // the view during construction
4653 for (String other : remains)
4655 JvAnnotRow othera = visan.get(other);
4656 if (othera != nullAnnot && othera.template.getCalcId() != null
4657 && othera.template.getCalcId().length() > 0)
4659 reorder.add(othera);
4662 // now put the automatic annotation in its correct place
4663 int s = 0, srt[] = new int[reorder.size()];
4664 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4665 for (JvAnnotRow jvar : reorder)
4668 srt[s++] = jvar.order;
4671 jalview.util.QuickSort.sort(srt, rws);
4672 // and re-insert the annotation at its correct position
4673 for (JvAnnotRow jvar : rws)
4675 al.addAnnotation(jvar.template, jvar.order);
4677 af.alignPanel.adjustAnnotationHeight();
4681 Hashtable skipList = null;
4684 * TODO remove this method
4687 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4688 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4689 * throw new Error("Implementation Error. No skipList defined for this
4690 * Jalview2XML instance."); } return (AlignFrame)
4691 * skipList.get(view.getSequenceSetId()); }
4695 * Check if the Jalview view contained in object should be skipped or not.
4698 * @return true if view's sequenceSetId is a key in skipList
4700 private boolean skipViewport(JalviewModel object)
4702 if (skipList == null)
4707 if (skipList.containsKey(id = object.getJalviewModelSequence()
4708 .getViewport()[0].getSequenceSetId()))
4710 if (Cache.log != null && Cache.log.isDebugEnabled())
4712 Cache.log.debug("Skipping seuqence set id " + id);
4719 public void addToSkipList(AlignFrame af)
4721 if (skipList == null)
4723 skipList = new Hashtable();
4725 skipList.put(af.getViewport().getSequenceSetId(), af);
4728 public void clearSkipList()
4730 if (skipList != null)
4737 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4738 boolean ignoreUnrefed)
4740 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4741 Vector dseqs = null;
4744 // create a list of new dataset sequences
4745 dseqs = new Vector();
4747 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4749 Sequence vamsasSeq = vamsasSet.getSequence(i);
4750 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4752 // create a new dataset
4755 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4756 dseqs.copyInto(dsseqs);
4757 ds = new jalview.datamodel.Alignment(dsseqs);
4758 debug("Created new dataset " + vamsasSet.getDatasetId()
4759 + " for alignment " + System.identityHashCode(al));
4760 addDatasetRef(vamsasSet.getDatasetId(), ds);
4762 // set the dataset for the newly imported alignment.
4763 if (al.getDataset() == null && !ignoreUnrefed)
4772 * sequence definition to create/merge dataset sequence for
4776 * vector to add new dataset sequence to
4778 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4779 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4781 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4783 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4784 SequenceI dsq = null;
4785 if (sq != null && sq.getDatasetSequence() != null)
4787 dsq = sq.getDatasetSequence();
4789 if (sq == null && ignoreUnrefed)
4793 String sqid = vamsasSeq.getDsseqid();
4796 // need to create or add a new dataset sequence reference to this sequence
4799 dsq = seqRefIds.get(sqid);
4804 // make a new dataset sequence
4805 dsq = sq.createDatasetSequence();
4808 // make up a new dataset reference for this sequence
4809 sqid = seqHash(dsq);
4811 dsq.setVamsasId(uniqueSetSuffix + sqid);
4812 seqRefIds.put(sqid, dsq);
4817 dseqs.addElement(dsq);
4822 ds.addSequence(dsq);
4828 { // make this dataset sequence sq's dataset sequence
4829 sq.setDatasetSequence(dsq);
4830 // and update the current dataset alignment
4835 if (!dseqs.contains(dsq))
4842 if (ds.findIndex(dsq) < 0)
4844 ds.addSequence(dsq);
4851 // TODO: refactor this as a merge dataset sequence function
4852 // now check that sq (the dataset sequence) sequence really is the union of
4853 // all references to it
4854 // boolean pre = sq.getStart() < dsq.getStart();
4855 // boolean post = sq.getEnd() > dsq.getEnd();
4859 // StringBuffer sb = new StringBuffer();
4860 String newres = jalview.analysis.AlignSeq.extractGaps(
4861 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4862 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4863 && newres.length() > dsq.getLength())
4865 // Update with the longer sequence.
4869 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4870 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4871 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4872 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4874 dsq.setSequence(newres);
4876 // TODO: merges will never happen if we 'know' we have the real dataset
4877 // sequence - this should be detected when id==dssid
4879 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4880 // + (pre ? "prepended" : "") + " "
4881 // + (post ? "appended" : ""));
4887 * TODO use AlignmentI here and in related methods - needs
4888 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4890 Hashtable<String, Alignment> datasetIds = null;
4892 IdentityHashMap<Alignment, String> dataset2Ids = null;
4894 private Alignment getDatasetFor(String datasetId)
4896 if (datasetIds == null)
4898 datasetIds = new Hashtable<String, Alignment>();
4901 if (datasetIds.containsKey(datasetId))
4903 return datasetIds.get(datasetId);
4908 private void addDatasetRef(String datasetId, Alignment dataset)
4910 if (datasetIds == null)
4912 datasetIds = new Hashtable<String, Alignment>();
4914 datasetIds.put(datasetId, dataset);
4918 * make a new dataset ID for this jalview dataset alignment
4923 private String getDatasetIdRef(Alignment dataset)
4925 if (dataset.getDataset() != null)
4927 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4929 String datasetId = makeHashCode(dataset, null);
4930 if (datasetId == null)
4932 // make a new datasetId and record it
4933 if (dataset2Ids == null)
4935 dataset2Ids = new IdentityHashMap<Alignment, String>();
4939 datasetId = dataset2Ids.get(dataset);
4941 if (datasetId == null)
4943 datasetId = "ds" + dataset2Ids.size() + 1;
4944 dataset2Ids.put(dataset, datasetId);
4950 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4952 for (int d = 0; d < sequence.getDBRefCount(); d++)
4954 DBRef dr = sequence.getDBRef(d);
4955 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4956 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4957 .getVersion(), sequence.getDBRef(d).getAccessionId());
4958 if (dr.getMapping() != null)
4960 entry.setMap(addMapping(dr.getMapping()));
4962 datasetSequence.addDBRef(entry);
4966 private jalview.datamodel.Mapping addMapping(Mapping m)
4968 SequenceI dsto = null;
4969 // Mapping m = dr.getMapping();
4970 int fr[] = new int[m.getMapListFromCount() * 2];
4971 Enumeration f = m.enumerateMapListFrom();
4972 for (int _i = 0; f.hasMoreElements(); _i += 2)
4974 MapListFrom mf = (MapListFrom) f.nextElement();
4975 fr[_i] = mf.getStart();
4976 fr[_i + 1] = mf.getEnd();
4978 int fto[] = new int[m.getMapListToCount() * 2];
4979 f = m.enumerateMapListTo();
4980 for (int _i = 0; f.hasMoreElements(); _i += 2)
4982 MapListTo mf = (MapListTo) f.nextElement();
4983 fto[_i] = mf.getStart();
4984 fto[_i + 1] = mf.getEnd();
4986 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4987 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4988 if (m.getMappingChoice() != null)
4990 MappingChoice mc = m.getMappingChoice();
4991 if (mc.getDseqFor() != null)
4993 String dsfor = "" + mc.getDseqFor();
4994 if (seqRefIds.containsKey(dsfor))
4999 jmap.setTo(seqRefIds.get(dsfor));
5003 frefedSequence.add(new Object[] { dsfor, jmap });
5009 * local sequence definition
5011 Sequence ms = mc.getSequence();
5012 SequenceI djs = null;
5013 String sqid = ms.getDsseqid();
5014 if (sqid != null && sqid.length() > 0)
5017 * recover dataset sequence
5019 djs = seqRefIds.get(sqid);
5024 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5025 sqid = ((Object) ms).toString(); // make up a new hascode for
5026 // undefined dataset sequence hash
5027 // (unlikely to happen)
5033 * make a new dataset sequence and add it to refIds hash
5035 djs = new jalview.datamodel.Sequence(ms.getName(),
5037 djs.setStart(jmap.getMap().getToLowest());
5038 djs.setEnd(jmap.getMap().getToHighest());
5039 djs.setVamsasId(uniqueSetSuffix + sqid);
5041 seqRefIds.put(sqid, djs);
5044 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5053 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5054 boolean keepSeqRefs)
5057 JalviewModel jm = saveState(ap, null, null, null);
5062 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5066 uniqueSetSuffix = "";
5067 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5072 if (this.frefedSequence == null)
5074 frefedSequence = new Vector();
5077 viewportsAdded.clear();
5079 AlignFrame af = loadFromObject(jm, null, false, null);
5080 af.alignPanels.clear();
5081 af.closeMenuItem_actionPerformed(true);
5084 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5085 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5086 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5087 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5088 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5091 return af.alignPanel;
5095 * flag indicating if hashtables should be cleared on finalization TODO this
5096 * flag may not be necessary
5098 private final boolean _cleartables = true;
5100 private Hashtable jvids2vobj;
5105 * @see java.lang.Object#finalize()
5108 protected void finalize() throws Throwable
5110 // really make sure we have no buried refs left.
5115 this.seqRefIds = null;
5116 this.seqsToIds = null;
5120 private void warn(String msg)
5125 private void warn(String msg, Exception e)
5127 if (Cache.log != null)
5131 Cache.log.warn(msg, e);
5135 Cache.log.warn(msg);
5140 System.err.println("Warning: " + msg);
5143 e.printStackTrace();
5148 private void debug(String string)
5150 debug(string, null);
5153 private void debug(String msg, Exception e)
5155 if (Cache.log != null)
5159 Cache.log.debug(msg, e);
5163 Cache.log.debug(msg);
5168 System.err.println("Warning: " + msg);
5171 e.printStackTrace();
5177 * set the object to ID mapping tables used to write/recover objects and XML
5178 * ID strings for the jalview project. If external tables are provided then
5179 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5180 * object goes out of scope. - also populates the datasetIds hashtable with
5181 * alignment objects containing dataset sequences
5184 * Map from ID strings to jalview datamodel
5186 * Map from jalview datamodel to ID strings
5190 public void setObjectMappingTables(Hashtable vobj2jv,
5191 IdentityHashMap jv2vobj)
5193 this.jv2vobj = jv2vobj;
5194 this.vobj2jv = vobj2jv;
5195 Iterator ds = jv2vobj.keySet().iterator();
5197 while (ds.hasNext())
5199 Object jvobj = ds.next();
5200 id = jv2vobj.get(jvobj).toString();
5201 if (jvobj instanceof jalview.datamodel.Alignment)
5203 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5205 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5208 else if (jvobj instanceof jalview.datamodel.Sequence)
5210 // register sequence object so the XML parser can recover it.
5211 if (seqRefIds == null)
5213 seqRefIds = new HashMap<String, SequenceI>();
5215 if (seqsToIds == null)
5217 seqsToIds = new IdentityHashMap<SequenceI, String>();
5219 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5220 seqsToIds.put((SequenceI) jvobj, id);
5222 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5225 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5226 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5227 if (jvann.annotationId == null)
5229 jvann.annotationId = anid;
5231 if (!jvann.annotationId.equals(anid))
5233 // TODO verify that this is the correct behaviour
5234 this.warn("Overriding Annotation ID for " + anid
5235 + " from different id : " + jvann.annotationId);
5236 jvann.annotationId = anid;
5239 else if (jvobj instanceof String)
5241 if (jvids2vobj == null)
5243 jvids2vobj = new Hashtable();
5244 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5249 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5255 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5256 * objects created from the project archive. If string is null (default for
5257 * construction) then suffix will be set automatically.
5261 public void setUniqueSetSuffix(String string)
5263 uniqueSetSuffix = string;
5268 * uses skipList2 as the skipList for skipping views on sequence sets
5269 * associated with keys in the skipList
5273 public void setSkipList(Hashtable skipList2)
5275 skipList = skipList2;
5279 * Reads the jar entry of given name and returns its contents, or null if the
5280 * entry is not found.
5283 * @param jarEntryName
5286 protected String readJarEntry(jarInputStreamProvider jprovider,
5287 String jarEntryName)
5289 String result = null;
5290 BufferedReader in = null;
5295 * Reopen the jar input stream and traverse its entries to find a matching
5298 JarInputStream jin = jprovider.getJarInputStream();
5299 JarEntry entry = null;
5302 entry = jin.getNextJarEntry();
5303 } while (entry != null && !entry.getName().equals(jarEntryName));
5307 StringBuilder out = new StringBuilder(256);
5308 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5311 while ((data = in.readLine()) != null)
5315 result = out.toString();
5319 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5321 } catch (Exception ex)
5323 ex.printStackTrace();
5331 } catch (IOException e)
5342 * Returns an incrementing counter (0, 1, 2...)
5346 private synchronized int nextCounter()