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<Object[]> 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 = 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 Iterator<String> keys = sf[index].otherDetails.keySet()
768 while (keys.hasNext())
771 OtherData keyValue = new OtherData();
772 keyValue.setKey(key);
773 keyValue.setValue(sf[index].otherDetails.get(key).toString());
774 features.addOtherData(keyValue);
778 jseq.addFeatures(features);
783 if (jdatasq.getAllPDBEntries() != null)
785 Enumeration en = jdatasq.getAllPDBEntries().elements();
786 while (en.hasMoreElements())
788 Pdbids pdb = new Pdbids();
789 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
792 String pdbId = entry.getId();
794 pdb.setType(entry.getType());
797 * Store any structure views associated with this sequence. This
798 * section copes with duplicate entries in the project, so a dataset
799 * only view *should* be coped with sensibly.
801 // This must have been loaded, is it still visible?
802 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
803 String matchedFile = null;
804 for (int f = frames.length - 1; f > -1; f--)
806 if (frames[f] instanceof StructureViewerBase)
808 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
809 matchedFile = saveStructureState(ap, jds, pdb, entry,
810 viewIds, matchedFile, viewFrame);
812 * Only store each structure viewer's state once in the project
813 * jar. First time through only (storeDS==false)
815 String viewId = viewFrame.getViewId();
816 if (!storeDS && !viewIds.contains(viewId))
821 String viewerState = viewFrame.getStateInfo();
822 writeJarEntry(jout, getViewerJarEntryName(viewId),
823 viewerState.getBytes());
824 } catch (IOException e)
826 System.err.println("Error saving viewer state: "
833 if (matchedFile != null || entry.getFile() != null)
835 if (entry.getFile() != null)
838 matchedFile = entry.getFile();
840 pdb.setFile(matchedFile); // entry.getFile());
841 if (pdbfiles == null)
843 pdbfiles = new ArrayList<String>();
846 if (!pdbfiles.contains(pdbId))
849 copyFileToJar(jout, matchedFile, pdbId);
853 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
855 PdbentryItem item = new PdbentryItem();
856 Hashtable properties = entry.getProperty();
857 Enumeration en2 = properties.keys();
858 while (en2.hasMoreElements())
860 Property prop = new Property();
861 String key = en2.nextElement().toString();
863 prop.setValue(properties.get(key).toString());
864 item.addProperty(prop);
866 pdb.addPdbentryItem(item);
873 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
878 if (!storeDS && av.hasHiddenRows())
880 jal = av.getAlignment();
883 if (jal.getCodonFrames() != null)
885 List<AlignedCodonFrame> jac = jal.getCodonFrames();
886 for (AlignedCodonFrame acf : jac)
888 AlcodonFrame alc = new AlcodonFrame();
889 vamsasSet.addAlcodonFrame(alc);
890 if (acf.getProtMappings() != null
891 && acf.getProtMappings().length > 0)
893 SequenceI[] dnas = acf.getdnaSeqs();
894 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
895 for (int m = 0; m < pmaps.length; m++)
897 AlcodMap alcmap = new AlcodMap();
898 alcmap.setDnasq(seqHash(dnas[m]));
899 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
901 alc.addAlcodMap(alcmap);
906 // AlcodonFrame alc = new AlcodonFrame();
907 // vamsasSet.addAlcodonFrame(alc);
908 // for (int p = 0; p < acf.aaWidth; p++)
910 // Alcodon cmap = new Alcodon();
911 // if (acf.codons[p] != null)
913 // // Null codons indicate a gapped column in the translated peptide
915 // cmap.setPos1(acf.codons[p][0]);
916 // cmap.setPos2(acf.codons[p][1]);
917 // cmap.setPos3(acf.codons[p][2]);
919 // alc.addAlcodon(cmap);
921 // if (acf.getProtMappings() != null
922 // && acf.getProtMappings().length > 0)
924 // SequenceI[] dnas = acf.getdnaSeqs();
925 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
926 // for (int m = 0; m < pmaps.length; m++)
928 // AlcodMap alcmap = new AlcodMap();
929 // alcmap.setDnasq(seqHash(dnas[m]));
930 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
932 // alc.addAlcodMap(alcmap);
939 // /////////////////////////////////
940 if (!storeDS && av.currentTree != null)
942 // FIND ANY ASSOCIATED TREES
943 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
944 if (Desktop.desktop != null)
946 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
948 for (int t = 0; t < frames.length; t++)
950 if (frames[t] instanceof TreePanel)
952 TreePanel tp = (TreePanel) frames[t];
954 if (tp.treeCanvas.av.getAlignment() == jal)
956 Tree tree = new Tree();
957 tree.setTitle(tp.getTitle());
958 tree.setCurrentTree((av.currentTree == tp.getTree()));
959 tree.setNewick(tp.getTree().toString());
960 tree.setThreshold(tp.treeCanvas.threshold);
962 tree.setFitToWindow(tp.fitToWindow.getState());
963 tree.setFontName(tp.getTreeFont().getName());
964 tree.setFontSize(tp.getTreeFont().getSize());
965 tree.setFontStyle(tp.getTreeFont().getStyle());
966 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
968 tree.setShowBootstrap(tp.bootstrapMenu.getState());
969 tree.setShowDistances(tp.distanceMenu.getState());
971 tree.setHeight(tp.getHeight());
972 tree.setWidth(tp.getWidth());
973 tree.setXpos(tp.getX());
974 tree.setYpos(tp.getY());
975 tree.setId(makeHashCode(tp, null));
985 * store forward refs from an annotationRow to any groups
987 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
990 for (SequenceI sq : jal.getSequences())
992 // Store annotation on dataset sequences only
993 AlignmentAnnotation[] aa = sq.getAnnotation();
994 if (aa != null && aa.length > 0)
996 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1003 if (jal.getAlignmentAnnotation() != null)
1005 // Store the annotation shown on the alignment.
1006 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1007 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1012 if (jal.getGroups() != null)
1014 JGroup[] groups = new JGroup[jal.getGroups().size()];
1016 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1018 JGroup jGroup = new JGroup();
1019 groups[++i] = jGroup;
1021 jGroup.setStart(sg.getStartRes());
1022 jGroup.setEnd(sg.getEndRes());
1023 jGroup.setName(sg.getName());
1024 if (groupRefs.containsKey(sg))
1026 // group has references so set its ID field
1027 jGroup.setId(groupRefs.get(sg));
1031 if (sg.cs.conservationApplied())
1033 jGroup.setConsThreshold(sg.cs.getConservationInc());
1035 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1037 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1041 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1044 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1046 jGroup.setColour("AnnotationColourGradient");
1047 jGroup.setAnnotationColours(constructAnnotationColours(
1048 (jalview.schemes.AnnotationColourGradient) sg.cs,
1051 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1053 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1057 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1060 jGroup.setPidThreshold(sg.cs.getThreshold());
1063 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1064 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1065 jGroup.setDisplayText(sg.getDisplayText());
1066 jGroup.setColourText(sg.getColourText());
1067 jGroup.setTextCol1(sg.textColour.getRGB());
1068 jGroup.setTextCol2(sg.textColour2.getRGB());
1069 jGroup.setTextColThreshold(sg.thresholdTextColour);
1070 jGroup.setShowUnconserved(sg.getShowNonconserved());
1071 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1072 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1073 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1074 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1075 for (SequenceI seq : sg.getSequences())
1077 jGroup.addSeq(seqHash(seq));
1081 jms.setJGroup(groups);
1085 // /////////SAVE VIEWPORT
1086 Viewport view = new Viewport();
1087 view.setTitle(ap.alignFrame.getTitle());
1088 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1089 av.getSequenceSetId()));
1090 view.setId(av.getViewId());
1091 if (av.getCodingComplement() != null)
1093 view.setComplementId(av.getCodingComplement().getViewId());
1095 view.setViewName(av.viewName);
1096 view.setGatheredViews(av.isGatherViewsHere());
1098 Rectangle size = ap.av.getExplodedGeometry();
1099 Rectangle position = size;
1102 size = ap.alignFrame.getBounds();
1103 if (av.getCodingComplement() != null)
1105 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1113 view.setXpos(position.x);
1114 view.setYpos(position.y);
1116 view.setWidth(size.width);
1117 view.setHeight(size.height);
1119 view.setStartRes(av.startRes);
1120 view.setStartSeq(av.startSeq);
1122 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1124 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1127 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1129 AnnotationColours ac = constructAnnotationColours(
1130 (jalview.schemes.AnnotationColourGradient) av
1131 .getGlobalColourScheme(),
1134 view.setAnnotationColours(ac);
1135 view.setBgColour("AnnotationColourGradient");
1139 view.setBgColour(ColourSchemeProperty.getColourName(av
1140 .getGlobalColourScheme()));
1143 ColourSchemeI cs = av.getGlobalColourScheme();
1147 if (cs.conservationApplied())
1149 view.setConsThreshold(cs.getConservationInc());
1150 if (cs instanceof jalview.schemes.UserColourScheme)
1152 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1156 if (cs instanceof ResidueColourScheme)
1158 view.setPidThreshold(cs.getThreshold());
1162 view.setConservationSelected(av.getConservationSelected());
1163 view.setPidSelected(av.getAbovePIDThreshold());
1164 view.setFontName(av.font.getName());
1165 view.setFontSize(av.font.getSize());
1166 view.setFontStyle(av.font.getStyle());
1167 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1168 view.setRenderGaps(av.isRenderGaps());
1169 view.setShowAnnotation(av.isShowAnnotation());
1170 view.setShowBoxes(av.getShowBoxes());
1171 view.setShowColourText(av.getColourText());
1172 view.setShowFullId(av.getShowJVSuffix());
1173 view.setRightAlignIds(av.isRightAlignIds());
1174 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1175 view.setShowText(av.getShowText());
1176 view.setShowUnconserved(av.getShowUnconserved());
1177 view.setWrapAlignment(av.getWrapAlignment());
1178 view.setTextCol1(av.getTextColour().getRGB());
1179 view.setTextCol2(av.getTextColour2().getRGB());
1180 view.setTextColThreshold(av.getThresholdTextColour());
1181 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1182 view.setShowSequenceLogo(av.isShowSequenceLogo());
1183 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1184 view.setShowGroupConsensus(av.isShowGroupConsensus());
1185 view.setShowGroupConservation(av.isShowGroupConservation());
1186 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1187 view.setShowDbRefTooltip(av.isShowDBRefs());
1188 view.setFollowHighlight(av.isFollowHighlight());
1189 view.setFollowSelection(av.followSelection);
1190 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1191 if (av.getFeaturesDisplayed() != null)
1193 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1195 String[] renderOrder = ap.getSeqPanel().seqCanvas
1196 .getFeatureRenderer().getRenderOrder()
1197 .toArray(new String[0]);
1199 Vector<String> settingsAdded = new Vector<String>();
1200 if (renderOrder != null)
1202 for (String featureType : renderOrder)
1204 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1205 .getFeatureRenderer()
1206 .getFeatureStyle(featureType);
1207 Setting setting = new Setting();
1208 setting.setType(featureType);
1209 if (!fcol.isSimpleColour())
1211 setting.setColour(fcol.getMaxColour().getRGB());
1212 setting.setMincolour(fcol.getMinColour().getRGB());
1213 setting.setMin(fcol.getMin());
1214 setting.setMax(fcol.getMax());
1215 setting.setColourByLabel(fcol.isColourByLabel());
1216 setting.setAutoScale(fcol.isAutoScaled());
1217 setting.setThreshold(fcol.getThreshold());
1218 // -1 = No threshold, 0 = Below, 1 = Above
1219 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1220 : (fcol.isBelowThreshold() ? 0 : -1));
1224 setting.setColour(fcol.getColour().getRGB());
1227 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1229 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1230 .getOrder(featureType);
1233 setting.setOrder(rorder);
1235 fs.addSetting(setting);
1236 settingsAdded.addElement(featureType);
1240 // is groups actually supposed to be a map here ?
1241 Iterator<String> en = ap.getSeqPanel().seqCanvas
1242 .getFeatureRenderer()
1243 .getFeatureGroups().iterator();
1244 Vector<String> groupsAdded = new Vector<String>();
1245 while (en.hasNext())
1247 String grp = en.next();
1248 if (groupsAdded.contains(grp))
1252 Group g = new Group();
1254 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1255 .getFeatureRenderer().checkGroupVisibility(grp, false))
1258 groupsAdded.addElement(grp);
1260 jms.setFeatureSettings(fs);
1263 if (av.hasHiddenColumns())
1265 if (av.getColumnSelection() == null
1266 || av.getColumnSelection().getHiddenColumns() == null)
1268 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1272 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1275 int[] region = av.getColumnSelection().getHiddenColumns()
1277 HiddenColumns hc = new HiddenColumns();
1278 hc.setStart(region[0]);
1279 hc.setEnd(region[1]);
1280 view.addHiddenColumns(hc);
1284 if (calcIdSet.size() > 0)
1286 for (String calcId : calcIdSet)
1288 if (calcId.trim().length() > 0)
1290 CalcIdParam cidp = createCalcIdParam(calcId, av);
1291 // Some calcIds have no parameters.
1294 view.addCalcIdParam(cidp);
1300 jms.addViewport(view);
1302 object.setJalviewModelSequence(jms);
1303 object.getVamsasModel().addSequenceSet(vamsasSet);
1305 if (jout != null && fileName != null)
1307 // We may not want to write the object to disk,
1308 // eg we can copy the alignViewport to a new view object
1309 // using save and then load
1312 System.out.println("Writing jar entry " + fileName);
1313 JarEntry entry = new JarEntry(fileName);
1314 jout.putNextEntry(entry);
1315 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1317 Marshaller marshaller = new Marshaller(pout);
1318 marshaller.marshal(object);
1321 } catch (Exception ex)
1323 // TODO: raise error in GUI if marshalling failed.
1324 ex.printStackTrace();
1331 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1332 * for each viewer, with
1334 * <li>viewer geometry (position, size, split pane divider location)</li>
1335 * <li>index of the selected structure in the viewer (currently shows gapped
1337 * <li>the id of the annotation holding RNA secondary structure</li>
1338 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1340 * Varna viewer state is also written out (in native Varna XML) to separate
1341 * project jar entries. A separate entry is written for each RNA structure
1342 * displayed, with the naming convention
1344 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1352 * @param storeDataset
1354 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1355 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1356 boolean storeDataset)
1358 if (Desktop.desktop == null)
1362 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1363 for (int f = frames.length - 1; f > -1; f--)
1365 if (frames[f] instanceof AppVarna)
1367 AppVarna varna = (AppVarna) frames[f];
1369 * link the sequence to every viewer that is showing it and is linked to
1370 * its alignment panel
1372 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1374 String viewId = varna.getViewId();
1375 RnaViewer rna = new RnaViewer();
1376 rna.setViewId(viewId);
1377 rna.setTitle(varna.getTitle());
1378 rna.setXpos(varna.getX());
1379 rna.setYpos(varna.getY());
1380 rna.setWidth(varna.getWidth());
1381 rna.setHeight(varna.getHeight());
1382 rna.setDividerLocation(varna.getDividerLocation());
1383 rna.setSelectedRna(varna.getSelectedIndex());
1384 jseq.addRnaViewer(rna);
1387 * Store each Varna panel's state once in the project per sequence.
1388 * First time through only (storeDataset==false)
1390 // boolean storeSessions = false;
1391 // String sequenceViewId = viewId + seqsToIds.get(jds);
1392 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1394 // viewIds.add(sequenceViewId);
1395 // storeSessions = true;
1397 for (RnaModel model : varna.getModels())
1399 if (model.seq == jds)
1402 * VARNA saves each view (sequence or alignment secondary
1403 * structure, gapped or trimmed) as a separate XML file
1405 String jarEntryName = rnaSessions.get(model);
1406 if (jarEntryName == null)
1409 String varnaStateFile = varna.getStateInfo(model.rna);
1410 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1411 copyFileToJar(jout, varnaStateFile, jarEntryName);
1412 rnaSessions.put(model, jarEntryName);
1414 SecondaryStructure ss = new SecondaryStructure();
1415 String annotationId = varna.getAnnotation(jds).annotationId;
1416 ss.setAnnotationId(annotationId);
1417 ss.setViewerState(jarEntryName);
1418 ss.setGapped(model.gapped);
1419 ss.setTitle(model.title);
1420 rna.addSecondaryStructure(ss);
1429 * Copy the contents of a file to a new entry added to the output jar
1433 * @param jarEntryName
1435 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1436 String jarEntryName)
1438 DataInputStream dis = null;
1441 File file = new File(infilePath);
1442 if (file.exists() && jout != null)
1444 dis = new DataInputStream(new FileInputStream(file));
1445 byte[] data = new byte[(int) file.length()];
1446 dis.readFully(data);
1447 writeJarEntry(jout, jarEntryName, data);
1449 } catch (Exception ex)
1451 ex.printStackTrace();
1459 } catch (IOException e)
1468 * Write the data to a new entry of given name in the output jar file
1471 * @param jarEntryName
1473 * @throws IOException
1475 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1476 byte[] data) throws IOException
1480 System.out.println("Writing jar entry " + jarEntryName);
1481 jout.putNextEntry(new JarEntry(jarEntryName));
1482 DataOutputStream dout = new DataOutputStream(jout);
1483 dout.write(data, 0, data.length);
1490 * Save the state of a structure viewer
1495 * the archive XML element under which to save the state
1498 * @param matchedFile
1502 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1503 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1504 String matchedFile, StructureViewerBase viewFrame)
1506 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1509 * Look for any bindings for this viewer to the PDB file of interest
1510 * (including part matches excluding chain id)
1512 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1514 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1515 final String pdbId = pdbentry.getId();
1516 if (!pdbId.equals(entry.getId())
1517 && !(entry.getId().length() > 4 && entry.getId()
1518 .toLowerCase().startsWith(pdbId.toLowerCase())))
1521 * not interested in a binding to a different PDB entry here
1525 if (matchedFile == null)
1527 matchedFile = pdbentry.getFile();
1529 else if (!matchedFile.equals(pdbentry.getFile()))
1532 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1533 + pdbentry.getFile());
1537 // can get at it if the ID
1538 // match is ambiguous (e.g.
1541 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1543 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1544 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1546 StructureState state = new StructureState();
1547 state.setVisible(true);
1548 state.setXpos(viewFrame.getX());
1549 state.setYpos(viewFrame.getY());
1550 state.setWidth(viewFrame.getWidth());
1551 state.setHeight(viewFrame.getHeight());
1552 final String viewId = viewFrame.getViewId();
1553 state.setViewId(viewId);
1554 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1555 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1556 state.setColourByJmol(viewFrame.isColouredByViewer());
1557 state.setType(viewFrame.getViewerType().toString());
1558 pdb.addStructureState(state);
1565 private AnnotationColours constructAnnotationColours(
1566 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1567 JalviewModelSequence jms)
1569 AnnotationColours ac = new AnnotationColours();
1570 ac.setAboveThreshold(acg.getAboveThreshold());
1571 ac.setThreshold(acg.getAnnotationThreshold());
1572 ac.setAnnotation(acg.getAnnotation());
1573 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1575 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1580 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1584 ac.setMaxColour(acg.getMaxColour().getRGB());
1585 ac.setMinColour(acg.getMinColour().getRGB());
1586 ac.setPerSequence(acg.isSeqAssociated());
1587 ac.setPredefinedColours(acg.isPredefinedColours());
1591 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1592 IdentityHashMap<SequenceGroup, String> groupRefs,
1593 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1594 SequenceSet vamsasSet)
1597 for (int i = 0; i < aa.length; i++)
1599 Annotation an = new Annotation();
1601 AlignmentAnnotation annotation = aa[i];
1602 if (annotation.annotationId != null)
1604 annotationIds.put(annotation.annotationId, annotation);
1607 an.setId(annotation.annotationId);
1609 an.setVisible(annotation.visible);
1611 an.setDescription(annotation.description);
1613 if (annotation.sequenceRef != null)
1615 // 2.9 JAL-1781 xref on sequence id rather than name
1616 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1618 if (annotation.groupRef != null)
1620 String groupIdr = groupRefs.get(annotation.groupRef);
1621 if (groupIdr == null)
1623 // make a locally unique String
1625 annotation.groupRef,
1626 groupIdr = ("" + System.currentTimeMillis()
1627 + annotation.groupRef.getName() + groupRefs
1630 an.setGroupRef(groupIdr.toString());
1633 // store all visualization attributes for annotation
1634 an.setGraphHeight(annotation.graphHeight);
1635 an.setCentreColLabels(annotation.centreColLabels);
1636 an.setScaleColLabels(annotation.scaleColLabel);
1637 an.setShowAllColLabels(annotation.showAllColLabels);
1638 an.setBelowAlignment(annotation.belowAlignment);
1640 if (annotation.graph > 0)
1643 an.setGraphType(annotation.graph);
1644 an.setGraphGroup(annotation.graphGroup);
1645 if (annotation.getThreshold() != null)
1647 ThresholdLine line = new ThresholdLine();
1648 line.setLabel(annotation.getThreshold().label);
1649 line.setValue(annotation.getThreshold().value);
1650 line.setColour(annotation.getThreshold().colour.getRGB());
1651 an.setThresholdLine(line);
1659 an.setLabel(annotation.label);
1661 if (annotation == av.getAlignmentQualityAnnot()
1662 || annotation == av.getAlignmentConservationAnnotation()
1663 || annotation == av.getAlignmentConsensusAnnotation()
1664 || annotation.autoCalculated)
1666 // new way of indicating autocalculated annotation -
1667 an.setAutoCalculated(annotation.autoCalculated);
1669 if (annotation.hasScore())
1671 an.setScore(annotation.getScore());
1674 if (annotation.getCalcId() != null)
1676 calcIdSet.add(annotation.getCalcId());
1677 an.setCalcId(annotation.getCalcId());
1679 if (annotation.hasProperties())
1681 for (String pr : annotation.getProperties())
1683 Property prop = new Property();
1685 prop.setValue(annotation.getProperty(pr));
1686 an.addProperty(prop);
1690 AnnotationElement ae;
1691 if (annotation.annotations != null)
1693 an.setScoreOnly(false);
1694 for (int a = 0; a < annotation.annotations.length; a++)
1696 if ((annotation == null) || (annotation.annotations[a] == null))
1701 ae = new AnnotationElement();
1702 if (annotation.annotations[a].description != null)
1704 ae.setDescription(annotation.annotations[a].description);
1706 if (annotation.annotations[a].displayCharacter != null)
1708 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1711 if (!Float.isNaN(annotation.annotations[a].value))
1713 ae.setValue(annotation.annotations[a].value);
1717 if (annotation.annotations[a].secondaryStructure > ' ')
1719 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1723 if (annotation.annotations[a].colour != null
1724 && annotation.annotations[a].colour != java.awt.Color.black)
1726 ae.setColour(annotation.annotations[a].colour.getRGB());
1729 an.addAnnotationElement(ae);
1730 if (annotation.autoCalculated)
1732 // only write one non-null entry into the annotation row -
1733 // sufficient to get the visualization attributes necessary to
1741 an.setScoreOnly(true);
1743 if (!storeDS || (storeDS && !annotation.autoCalculated))
1745 // skip autocalculated annotation - these are only provided for
1747 vamsasSet.addAnnotation(an);
1753 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1755 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1756 if (settings != null)
1758 CalcIdParam vCalcIdParam = new CalcIdParam();
1759 vCalcIdParam.setCalcId(calcId);
1760 vCalcIdParam.addServiceURL(settings.getServiceURI());
1761 // generic URI allowing a third party to resolve another instance of the
1762 // service used for this calculation
1763 for (String urls : settings.getServiceURLs())
1765 vCalcIdParam.addServiceURL(urls);
1767 vCalcIdParam.setVersion("1.0");
1768 if (settings.getPreset() != null)
1770 WsParamSetI setting = settings.getPreset();
1771 vCalcIdParam.setName(setting.getName());
1772 vCalcIdParam.setDescription(setting.getDescription());
1776 vCalcIdParam.setName("");
1777 vCalcIdParam.setDescription("Last used parameters");
1779 // need to be able to recover 1) settings 2) user-defined presets or
1780 // recreate settings from preset 3) predefined settings provided by
1781 // service - or settings that can be transferred (or discarded)
1782 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1784 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1785 // todo - decide if updateImmediately is needed for any projects.
1787 return vCalcIdParam;
1792 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1795 if (calcIdParam.getVersion().equals("1.0"))
1797 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1798 .getPreferredServiceFor(calcIdParam.getServiceURL());
1799 if (service != null)
1801 WsParamSetI parmSet = null;
1804 parmSet = service.getParamStore().parseServiceParameterFile(
1805 calcIdParam.getName(), calcIdParam.getDescription(),
1806 calcIdParam.getServiceURL(),
1807 calcIdParam.getParameters().replace("|\\n|", "\n"));
1808 } catch (IOException x)
1810 warn("Couldn't parse parameter data for "
1811 + calcIdParam.getCalcId(), x);
1814 List<ArgumentI> argList = null;
1815 if (calcIdParam.getName().length() > 0)
1817 parmSet = service.getParamStore()
1818 .getPreset(calcIdParam.getName());
1819 if (parmSet != null)
1821 // TODO : check we have a good match with settings in AACon -
1822 // otherwise we'll need to create a new preset
1827 argList = parmSet.getArguments();
1830 AAConSettings settings = new AAConSettings(
1831 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1832 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1833 calcIdParam.isNeedsUpdate());
1838 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1842 throw new Error(MessageManager.formatMessage(
1843 "error.unsupported_version_calcIdparam",
1844 new Object[] { calcIdParam.toString() }));
1848 * External mapping between jalview objects and objects yielding a valid and
1849 * unique object ID string. This is null for normal Jalview project IO, but
1850 * non-null when a jalview project is being read or written as part of a
1853 IdentityHashMap jv2vobj = null;
1856 * Construct a unique ID for jvobj using either existing bindings or if none
1857 * exist, the result of the hashcode call for the object.
1860 * jalview data object
1861 * @return unique ID for referring to jvobj
1863 private String makeHashCode(Object jvobj, String altCode)
1865 if (jv2vobj != null)
1867 Object id = jv2vobj.get(jvobj);
1870 return id.toString();
1872 // check string ID mappings
1873 if (jvids2vobj != null && jvobj instanceof String)
1875 id = jvids2vobj.get(jvobj);
1879 return id.toString();
1881 // give up and warn that something has gone wrong
1882 warn("Cannot find ID for object in external mapping : " + jvobj);
1888 * return local jalview object mapped to ID, if it exists
1892 * @return null or object bound to idcode
1894 private Object retrieveExistingObj(String idcode)
1896 if (idcode != null && vobj2jv != null)
1898 return vobj2jv.get(idcode);
1904 * binding from ID strings from external mapping table to jalview data model
1907 private Hashtable vobj2jv;
1909 private Sequence createVamsasSequence(String id, SequenceI jds)
1911 return createVamsasSequence(true, id, jds, null);
1914 private Sequence createVamsasSequence(boolean recurse, String id,
1915 SequenceI jds, SequenceI parentseq)
1917 Sequence vamsasSeq = new Sequence();
1918 vamsasSeq.setId(id);
1919 vamsasSeq.setName(jds.getName());
1920 vamsasSeq.setSequence(jds.getSequenceAsString());
1921 vamsasSeq.setDescription(jds.getDescription());
1922 jalview.datamodel.DBRefEntry[] dbrefs = null;
1923 if (jds.getDatasetSequence() != null)
1925 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1926 if (jds.getDatasetSequence().getDBRefs() != null)
1928 dbrefs = jds.getDatasetSequence().getDBRefs();
1933 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1934 // dataset sequences only
1935 dbrefs = jds.getDBRefs();
1939 for (int d = 0; d < dbrefs.length; d++)
1941 DBRef dbref = new DBRef();
1942 dbref.setSource(dbrefs[d].getSource());
1943 dbref.setVersion(dbrefs[d].getVersion());
1944 dbref.setAccessionId(dbrefs[d].getAccessionId());
1945 if (dbrefs[d].hasMap())
1947 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1949 dbref.setMapping(mp);
1951 vamsasSeq.addDBRef(dbref);
1957 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1958 SequenceI parentseq, SequenceI jds, boolean recurse)
1961 if (jmp.getMap() != null)
1965 jalview.util.MapList mlst = jmp.getMap();
1966 List<int[]> r = mlst.getFromRanges();
1967 for (int[] range : r)
1969 MapListFrom mfrom = new MapListFrom();
1970 mfrom.setStart(range[0]);
1971 mfrom.setEnd(range[1]);
1972 mp.addMapListFrom(mfrom);
1974 r = mlst.getToRanges();
1975 for (int[] range : r)
1977 MapListTo mto = new MapListTo();
1978 mto.setStart(range[0]);
1979 mto.setEnd(range[1]);
1980 mp.addMapListTo(mto);
1982 mp.setMapFromUnit(mlst.getFromRatio());
1983 mp.setMapToUnit(mlst.getToRatio());
1984 if (jmp.getTo() != null)
1986 MappingChoice mpc = new MappingChoice();
1988 && (parentseq != jmp.getTo() || parentseq
1989 .getDatasetSequence() != jmp.getTo()))
1991 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1997 SequenceI ps = null;
1998 if (parentseq != jmp.getTo()
1999 && parentseq.getDatasetSequence() != jmp.getTo())
2001 // chaining dbref rather than a handshaking one
2002 jmpid = seqHash(ps = jmp.getTo());
2006 jmpid = seqHash(ps = parentseq);
2008 mpc.setDseqFor(jmpid);
2009 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2011 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2012 seqRefIds.put(mpc.getDseqFor(), ps);
2016 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2019 mp.setMappingChoice(mpc);
2025 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2026 List<UserColourScheme> userColours, JalviewModelSequence jms)
2029 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2030 boolean newucs = false;
2031 if (!userColours.contains(ucs))
2033 userColours.add(ucs);
2036 id = "ucs" + userColours.indexOf(ucs);
2039 // actually create the scheme's entry in the XML model
2040 java.awt.Color[] colours = ucs.getColours();
2041 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2042 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2044 for (int i = 0; i < colours.length; i++)
2046 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2047 col.setName(ResidueProperties.aa[i]);
2048 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2049 jbucs.addColour(col);
2051 if (ucs.getLowerCaseColours() != null)
2053 colours = ucs.getLowerCaseColours();
2054 for (int i = 0; i < colours.length; i++)
2056 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2057 col.setName(ResidueProperties.aa[i].toLowerCase());
2058 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2059 jbucs.addColour(col);
2064 uc.setUserColourScheme(jbucs);
2065 jms.addUserColours(uc);
2071 jalview.schemes.UserColourScheme getUserColourScheme(
2072 JalviewModelSequence jms, String id)
2074 UserColours[] uc = jms.getUserColours();
2075 UserColours colours = null;
2077 for (int i = 0; i < uc.length; i++)
2079 if (uc[i].getId().equals(id))
2087 java.awt.Color[] newColours = new java.awt.Color[24];
2089 for (int i = 0; i < 24; i++)
2091 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2092 .getUserColourScheme().getColour(i).getRGB(), 16));
2095 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2098 if (colours.getUserColourScheme().getColourCount() > 24)
2100 newColours = new java.awt.Color[23];
2101 for (int i = 0; i < 23; i++)
2103 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2104 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2106 ucs.setLowerCaseColours(newColours);
2113 * contains last error message (if any) encountered by XML loader.
2115 String errorMessage = null;
2118 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2119 * exceptions are raised during project XML parsing
2121 public boolean attemptversion1parse = true;
2124 * Load a jalview project archive from a jar file
2127 * - HTTP URL or filename
2129 public AlignFrame loadJalviewAlign(final String file)
2132 jalview.gui.AlignFrame af = null;
2136 // create list to store references for any new Jmol viewers created
2137 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2138 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2139 // Workaround is to make sure caller implements the JarInputStreamProvider
2141 // so we can re-open the jar input stream for each entry.
2143 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2144 af = loadJalviewAlign(jprovider);
2146 } catch (MalformedURLException e)
2148 errorMessage = "Invalid URL format for '" + file + "'";
2154 SwingUtilities.invokeAndWait(new Runnable()
2159 setLoadingFinishedForNewStructureViewers();
2162 } catch (Exception x)
2164 System.err.println("Error loading alignment: " + x.getMessage());
2170 private jarInputStreamProvider createjarInputStreamProvider(
2171 final String file) throws MalformedURLException
2174 errorMessage = null;
2175 uniqueSetSuffix = null;
2177 viewportsAdded.clear();
2178 frefedSequence = null;
2180 if (file.startsWith("http://"))
2182 url = new URL(file);
2184 final URL _url = url;
2185 return new jarInputStreamProvider()
2189 public JarInputStream getJarInputStream() throws IOException
2193 return new JarInputStream(_url.openStream());
2197 return new JarInputStream(new FileInputStream(file));
2202 public String getFilename()
2210 * Recover jalview session from a jalview project archive. Caller may
2211 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2212 * themselves. Any null fields will be initialised with default values,
2213 * non-null fields are left alone.
2218 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2220 errorMessage = null;
2221 if (uniqueSetSuffix == null)
2223 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2225 if (seqRefIds == null)
2227 seqRefIds = new HashMap<String, SequenceI>();
2229 if (frefedSequence == null)
2231 frefedSequence = new Vector<Object[]>();
2234 AlignFrame af = null, _af = null;
2235 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2236 final String file = jprovider.getFilename();
2239 JarInputStream jin = null;
2240 JarEntry jarentry = null;
2245 jin = jprovider.getJarInputStream();
2246 for (int i = 0; i < entryCount; i++)
2248 jarentry = jin.getNextJarEntry();
2251 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2253 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2254 JalviewModel object = new JalviewModel();
2256 Unmarshaller unmar = new Unmarshaller(object);
2257 unmar.setValidation(false);
2258 object = (JalviewModel) unmar.unmarshal(in);
2259 if (true) // !skipViewport(object))
2261 _af = loadFromObject(object, file, true, jprovider);
2262 if (object.getJalviewModelSequence().getViewportCount() > 0)
2265 if (af.viewport.isGatherViewsHere())
2267 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2273 else if (jarentry != null)
2275 // Some other file here.
2278 } while (jarentry != null);
2279 resolveFrefedSequences();
2280 } catch (IOException ex)
2282 ex.printStackTrace();
2283 errorMessage = "Couldn't locate Jalview XML file : " + file;
2284 System.err.println("Exception whilst loading jalview XML file : "
2286 } catch (Exception ex)
2288 System.err.println("Parsing as Jalview Version 2 file failed.");
2289 ex.printStackTrace(System.err);
2290 if (attemptversion1parse)
2292 // Is Version 1 Jar file?
2295 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2296 } catch (Exception ex2)
2298 System.err.println("Exception whilst loading as jalviewXMLV1:");
2299 ex2.printStackTrace();
2303 if (Desktop.instance != null)
2305 Desktop.instance.stopLoading();
2309 System.out.println("Successfully loaded archive file");
2312 ex.printStackTrace();
2314 System.err.println("Exception whilst loading jalview XML file : "
2316 } catch (OutOfMemoryError e)
2318 // Don't use the OOM Window here
2319 errorMessage = "Out of memory loading jalview XML file";
2320 System.err.println("Out of memory whilst loading jalview XML file");
2321 e.printStackTrace();
2324 if (Desktop.instance != null)
2326 Desktop.instance.stopLoading();
2330 * Regather multiple views (with the same sequence set id) to the frame (if
2331 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2332 * views instead of separate frames. Note this doesn't restore a state where
2333 * some expanded views in turn have tabbed views - the last "first tab" read
2334 * in will play the role of gatherer for all.
2336 for (AlignFrame fr : gatherToThisFrame.values())
2338 Desktop.instance.gatherViews(fr);
2341 restoreSplitFrames();
2343 if (errorMessage != null)
2351 * Try to reconstruct and display SplitFrame windows, where each contains
2352 * complementary dna and protein alignments. Done by pairing up AlignFrame
2353 * objects (created earlier) which have complementary viewport ids associated.
2355 protected void restoreSplitFrames()
2357 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2358 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2359 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2362 * Identify the DNA alignments
2364 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2367 AlignFrame af = candidate.getValue();
2368 if (af.getViewport().getAlignment().isNucleotide())
2370 dna.put(candidate.getKey().getId(), af);
2375 * Try to match up the protein complements
2377 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2380 AlignFrame af = candidate.getValue();
2381 if (!af.getViewport().getAlignment().isNucleotide())
2383 String complementId = candidate.getKey().getComplementId();
2384 // only non-null complements should be in the Map
2385 if (complementId != null && dna.containsKey(complementId))
2387 final AlignFrame dnaFrame = dna.get(complementId);
2388 SplitFrame sf = createSplitFrame(dnaFrame, af);
2389 addedToSplitFrames.add(dnaFrame);
2390 addedToSplitFrames.add(af);
2391 if (af.viewport.isGatherViewsHere())
2400 * Open any that we failed to pair up (which shouldn't happen!) as
2401 * standalone AlignFrame's.
2403 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2406 AlignFrame af = candidate.getValue();
2407 if (!addedToSplitFrames.contains(af))
2409 Viewport view = candidate.getKey();
2410 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2412 System.err.println("Failed to restore view " + view.getTitle()
2413 + " to split frame");
2418 * Gather back into tabbed views as flagged.
2420 for (SplitFrame sf : gatherTo)
2422 Desktop.instance.gatherViews(sf);
2425 splitFrameCandidates.clear();
2429 * Construct and display one SplitFrame holding DNA and protein alignments.
2432 * @param proteinFrame
2435 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2436 AlignFrame proteinFrame)
2438 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2439 String title = MessageManager.getString("label.linked_view_title");
2440 int width = (int) dnaFrame.getBounds().getWidth();
2441 int height = (int) (dnaFrame.getBounds().getHeight()
2442 + proteinFrame.getBounds().getHeight() + 50);
2445 * SplitFrame location is saved to both enclosed frames
2447 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2448 Desktop.addInternalFrame(splitFrame, title, width, height);
2451 * And compute cDNA consensus (couldn't do earlier with consensus as
2452 * mappings were not yet present)
2454 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2460 * check errorMessage for a valid error message and raise an error box in the
2461 * GUI or write the current errorMessage to stderr and then clear the error
2464 protected void reportErrors()
2466 reportErrors(false);
2469 protected void reportErrors(final boolean saving)
2471 if (errorMessage != null)
2473 final String finalErrorMessage = errorMessage;
2476 javax.swing.SwingUtilities.invokeLater(new Runnable()
2481 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2482 finalErrorMessage, "Error "
2483 + (saving ? "saving" : "loading")
2484 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2490 System.err.println("Problem loading Jalview file: " + errorMessage);
2493 errorMessage = null;
2496 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2499 * when set, local views will be updated from view stored in JalviewXML
2500 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2501 * sync if this is set to true.
2503 private final boolean updateLocalViews = false;
2506 * Returns the path to a temporary file holding the PDB file for the given PDB
2507 * id. The first time of asking, searches for a file of that name in the
2508 * Jalview project jar, and copies it to a new temporary file. Any repeat
2509 * requests just return the path to the file previously created.
2515 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2517 if (alreadyLoadedPDB.containsKey(pdbId))
2519 return alreadyLoadedPDB.get(pdbId).toString();
2522 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2523 if (tempFile != null)
2525 alreadyLoadedPDB.put(pdbId, tempFile);
2531 * Copies the jar entry of given name to a new temporary file and returns the
2532 * path to the file, or null if the entry is not found.
2535 * @param jarEntryName
2537 * a prefix for the temporary file name, must be at least three
2541 protected String copyJarEntry(jarInputStreamProvider jprovider,
2542 String jarEntryName, String prefix)
2544 BufferedReader in = null;
2545 PrintWriter out = null;
2549 JarInputStream jin = jprovider.getJarInputStream();
2551 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2552 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2553 * FileInputStream(jprovider)); }
2556 JarEntry entry = null;
2559 entry = jin.getNextJarEntry();
2560 } while (entry != null && !entry.getName().equals(jarEntryName));
2563 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2564 File outFile = File.createTempFile(prefix, ".tmp");
2565 outFile.deleteOnExit();
2566 out = new PrintWriter(new FileOutputStream(outFile));
2569 while ((data = in.readLine()) != null)
2574 String t = outFile.getAbsolutePath();
2579 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2581 } catch (Exception ex)
2583 ex.printStackTrace();
2591 } catch (IOException e)
2605 private class JvAnnotRow
2607 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2614 * persisted version of annotation row from which to take vis properties
2616 public jalview.datamodel.AlignmentAnnotation template;
2619 * original position of the annotation row in the alignment
2625 * Load alignment frame from jalview XML DOM object
2630 * filename source string
2631 * @param loadTreesAndStructures
2632 * when false only create Viewport
2634 * data source provider
2635 * @return alignment frame created from view stored in DOM
2637 AlignFrame loadFromObject(JalviewModel object, String file,
2638 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2640 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2641 Sequence[] vamsasSeq = vamsasSet.getSequence();
2643 JalviewModelSequence jms = object.getJalviewModelSequence();
2645 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2648 // ////////////////////////////////
2651 List<SequenceI> hiddenSeqs = null;
2652 jalview.datamodel.Sequence jseq;
2654 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2656 boolean multipleView = false;
2658 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2659 int vi = 0; // counter in vamsasSeq array
2660 for (int i = 0; i < jseqs.length; i++)
2662 String seqId = jseqs[i].getId();
2664 if (seqRefIds.get(seqId) != null)
2666 tmpseqs.add(seqRefIds.get(seqId));
2667 multipleView = true;
2671 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2672 vamsasSeq[vi].getSequence());
2673 jseq.setDescription(vamsasSeq[vi].getDescription());
2674 jseq.setStart(jseqs[i].getStart());
2675 jseq.setEnd(jseqs[i].getEnd());
2676 jseq.setVamsasId(uniqueSetSuffix + seqId);
2677 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2682 if (jseqs[i].getHidden())
2684 if (hiddenSeqs == null)
2686 hiddenSeqs = new ArrayList<SequenceI>();
2689 hiddenSeqs.add(seqRefIds.get(seqId));
2695 // Create the alignment object from the sequence set
2696 // ///////////////////////////////
2697 SequenceI[] orderedSeqs = tmpseqs
2698 .toArray(new SequenceI[tmpseqs.size()]);
2700 Alignment al = new Alignment(orderedSeqs);
2702 // / Add the alignment properties
2703 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2705 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2706 al.setProperty(ssp.getKey(), ssp.getValue());
2710 // SequenceFeatures are added to the DatasetSequence,
2711 // so we must create or recover the dataset before loading features
2712 // ///////////////////////////////
2713 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2715 // older jalview projects do not have a dataset id.
2716 al.setDataset(null);
2720 // recover dataset - passing on flag indicating if this a 'viewless'
2721 // sequence set (a.k.a. a stored dataset for the project)
2722 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2723 .getViewportCount() == 0);
2725 // ///////////////////////////////
2727 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2730 // load sequence features, database references and any associated PDB
2731 // structures for the alignment
2732 for (int i = 0; i < vamsasSeq.length; i++)
2734 if (jseqs[i].getFeaturesCount() > 0)
2736 Features[] features = jseqs[i].getFeatures();
2737 for (int f = 0; f < features.length; f++)
2739 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2740 features[f].getType(), features[f].getDescription(),
2741 features[f].getStatus(), features[f].getBegin(),
2742 features[f].getEnd(), features[f].getFeatureGroup());
2744 sf.setScore(features[f].getScore());
2745 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2747 OtherData keyValue = features[f].getOtherData(od);
2748 if (keyValue.getKey().startsWith("LINK"))
2750 sf.addLink(keyValue.getValue());
2754 sf.setValue(keyValue.getKey(), keyValue.getValue());
2759 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2762 if (vamsasSeq[i].getDBRefCount() > 0)
2764 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2766 if (jseqs[i].getPdbidsCount() > 0)
2768 Pdbids[] ids = jseqs[i].getPdbids();
2769 for (int p = 0; p < ids.length; p++)
2771 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2772 entry.setId(ids[p].getId());
2773 if (ids[p].getType() != null)
2775 if (ids[p].getType().equalsIgnoreCase("PDB"))
2777 entry.setType(PDBEntry.Type.PDB);
2781 entry.setType(PDBEntry.Type.FILE);
2784 if (ids[p].getFile() != null)
2786 if (!pdbloaded.containsKey(ids[p].getFile()))
2788 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2792 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2795 StructureSelectionManager.getStructureSelectionManager(
2796 Desktop.instance).registerPDBEntry(entry);
2797 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2801 } // end !multipleview
2803 // ///////////////////////////////
2804 // LOAD SEQUENCE MAPPINGS
2806 if (vamsasSet.getAlcodonFrameCount() > 0)
2808 // TODO Potentially this should only be done once for all views of an
2810 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2811 for (int i = 0; i < alc.length; i++)
2813 AlignedCodonFrame cf = new AlignedCodonFrame();
2814 if (alc[i].getAlcodMapCount() > 0)
2816 AlcodMap[] maps = alc[i].getAlcodMap();
2817 for (int m = 0; m < maps.length; m++)
2819 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2821 jalview.datamodel.Mapping mapping = null;
2822 // attach to dna sequence reference.
2823 if (maps[m].getMapping() != null)
2825 mapping = addMapping(maps[m].getMapping());
2827 if (dnaseq != null && mapping.getTo() != null)
2829 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2834 frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
2839 al.addCodonFrame(cf);
2843 // ////////////////////////////////
2845 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2848 * store any annotations which forward reference a group's ID
2850 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2852 if (vamsasSet.getAnnotationCount() > 0)
2854 Annotation[] an = vamsasSet.getAnnotation();
2856 for (int i = 0; i < an.length; i++)
2858 Annotation annotation = an[i];
2861 * test if annotation is automatically calculated for this view only
2863 boolean autoForView = false;
2864 if (annotation.getLabel().equals("Quality")
2865 || annotation.getLabel().equals("Conservation")
2866 || annotation.getLabel().equals("Consensus"))
2868 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2870 if (!annotation.hasAutoCalculated())
2872 annotation.setAutoCalculated(true);
2876 || (annotation.hasAutoCalculated() && annotation
2877 .isAutoCalculated()))
2879 // remove ID - we don't recover annotation from other views for
2880 // view-specific annotation
2881 annotation.setId(null);
2884 // set visiblity for other annotation in this view
2885 String annotationId = annotation.getId();
2886 if (annotationId != null && annotationIds.containsKey(annotationId))
2888 AlignmentAnnotation jda = annotationIds.get(annotationId);
2889 // in principle Visible should always be true for annotation displayed
2890 // in multiple views
2891 if (annotation.hasVisible())
2893 jda.visible = annotation.getVisible();
2896 al.addAnnotation(jda);
2900 // Construct new annotation from model.
2901 AnnotationElement[] ae = annotation.getAnnotationElement();
2902 jalview.datamodel.Annotation[] anot = null;
2903 java.awt.Color firstColour = null;
2905 if (!annotation.getScoreOnly())
2907 anot = new jalview.datamodel.Annotation[al.getWidth()];
2908 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2910 anpos = ae[aa].getPosition();
2912 if (anpos >= anot.length)
2917 anot[anpos] = new jalview.datamodel.Annotation(
2919 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2920 (ae[aa].getSecondaryStructure() == null || ae[aa]
2921 .getSecondaryStructure().length() == 0) ? ' '
2922 : ae[aa].getSecondaryStructure().charAt(0),
2926 // JBPNote: Consider verifying dataflow for IO of secondary
2927 // structure annotation read from Stockholm files
2928 // this was added to try to ensure that
2929 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2931 // anot[ae[aa].getPosition()].displayCharacter = "";
2933 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2934 if (firstColour == null)
2936 firstColour = anot[anpos].colour;
2940 jalview.datamodel.AlignmentAnnotation jaa = null;
2942 if (annotation.getGraph())
2944 float llim = 0, hlim = 0;
2945 // if (autoForView || an[i].isAutoCalculated()) {
2948 jaa = new jalview.datamodel.AlignmentAnnotation(
2949 annotation.getLabel(), annotation.getDescription(), anot,
2950 llim, hlim, annotation.getGraphType());
2952 jaa.graphGroup = annotation.getGraphGroup();
2953 jaa._linecolour = firstColour;
2954 if (annotation.getThresholdLine() != null)
2956 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
2957 .getThresholdLine().getValue(), annotation
2958 .getThresholdLine().getLabel(), new java.awt.Color(
2959 annotation.getThresholdLine().getColour())));
2962 if (autoForView || annotation.isAutoCalculated())
2964 // Hardwire the symbol display line to ensure that labels for
2965 // histograms are displayed
2971 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2972 an[i].getDescription(), anot);
2973 jaa._linecolour = firstColour;
2975 // register new annotation
2976 if (an[i].getId() != null)
2978 annotationIds.put(an[i].getId(), jaa);
2979 jaa.annotationId = an[i].getId();
2981 // recover sequence association
2982 String sequenceRef = an[i].getSequenceRef();
2983 if (sequenceRef != null)
2985 // from 2.9 sequenceRef is to sequence id (JAL-1781)
2986 SequenceI sequence = seqRefIds.get(sequenceRef);
2987 if (sequence == null)
2989 // in pre-2.9 projects sequence ref is to sequence name
2990 sequence = al.findName(sequenceRef);
2992 if (sequence != null)
2994 jaa.createSequenceMapping(sequence, 1, true);
2995 sequence.addAlignmentAnnotation(jaa);
2998 // and make a note of any group association
2999 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3001 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3002 .get(an[i].getGroupRef());
3005 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3006 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3011 if (an[i].hasScore())
3013 jaa.setScore(an[i].getScore());
3015 if (an[i].hasVisible())
3017 jaa.visible = an[i].getVisible();
3020 if (an[i].hasCentreColLabels())
3022 jaa.centreColLabels = an[i].getCentreColLabels();
3025 if (an[i].hasScaleColLabels())
3027 jaa.scaleColLabel = an[i].getScaleColLabels();
3029 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3031 // newer files have an 'autoCalculated' flag and store calculation
3032 // state in viewport properties
3033 jaa.autoCalculated = true; // means annotation will be marked for
3034 // update at end of load.
3036 if (an[i].hasGraphHeight())
3038 jaa.graphHeight = an[i].getGraphHeight();
3040 if (an[i].hasBelowAlignment())
3042 jaa.belowAlignment = an[i].isBelowAlignment();
3044 jaa.setCalcId(an[i].getCalcId());
3045 if (an[i].getPropertyCount() > 0)
3047 for (jalview.schemabinding.version2.Property prop : an[i]
3050 jaa.setProperty(prop.getName(), prop.getValue());
3053 if (jaa.autoCalculated)
3055 autoAlan.add(new JvAnnotRow(i, jaa));
3058 // if (!autoForView)
3060 // add autocalculated group annotation and any user created annotation
3062 al.addAnnotation(jaa);
3066 // ///////////////////////
3068 // Create alignment markup and styles for this view
3069 if (jms.getJGroupCount() > 0)
3071 JGroup[] groups = jms.getJGroup();
3072 boolean addAnnotSchemeGroup = false;
3073 for (int i = 0; i < groups.length; i++)
3075 JGroup jGroup = groups[i];
3076 ColourSchemeI cs = null;
3077 if (jGroup.getColour() != null)
3079 if (jGroup.getColour().startsWith("ucs"))
3081 cs = getUserColourScheme(jms, jGroup.getColour());
3083 else if (jGroup.getColour().equals("AnnotationColourGradient")
3084 && jGroup.getAnnotationColours() != null)
3086 addAnnotSchemeGroup = true;
3091 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3096 cs.setThreshold(jGroup.getPidThreshold(), true);
3100 Vector<SequenceI> seqs = new Vector<SequenceI>();
3102 for (int s = 0; s < jGroup.getSeqCount(); s++)
3104 String seqId = jGroup.getSeq(s) + "";
3105 SequenceI ts = seqRefIds.get(seqId);
3109 seqs.addElement(ts);
3113 if (seqs.size() < 1)
3118 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3119 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3120 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3122 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3124 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3125 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3126 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3127 .isShowUnconserved() : false);
3128 sg.thresholdTextColour = jGroup.getTextColThreshold();
3129 if (jGroup.hasShowConsensusHistogram())
3131 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3134 if (jGroup.hasShowSequenceLogo())
3136 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3138 if (jGroup.hasNormaliseSequenceLogo())
3140 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3142 if (jGroup.hasIgnoreGapsinConsensus())
3144 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3146 if (jGroup.getConsThreshold() != 0)
3148 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3149 "All", ResidueProperties.propHash, 3,
3150 sg.getSequences(null), 0, sg.getWidth() - 1);
3152 c.verdict(false, 25);
3153 sg.cs.setConservation(c);
3156 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3158 // re-instate unique group/annotation row reference
3159 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3163 for (AlignmentAnnotation jaa : jaal)
3166 if (jaa.autoCalculated)
3168 // match up and try to set group autocalc alignment row for this
3170 if (jaa.label.startsWith("Consensus for "))
3172 sg.setConsensus(jaa);
3174 // match up and try to set group autocalc alignment row for this
3176 if (jaa.label.startsWith("Conservation for "))
3178 sg.setConservationRow(jaa);
3185 if (addAnnotSchemeGroup)
3187 // reconstruct the annotation colourscheme
3188 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3189 null, al, jms, false);
3195 // only dataset in this model, so just return.
3198 // ///////////////////////////////
3201 // If we just load in the same jar file again, the sequenceSetId
3202 // will be the same, and we end up with multiple references
3203 // to the same sequenceSet. We must modify this id on load
3204 // so that each load of the file gives a unique id
3205 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3206 String viewId = (view.getId() == null ? null : view.getId()
3208 AlignFrame af = null;
3209 AlignViewport av = null;
3210 // now check to see if we really need to create a new viewport.
3211 if (multipleView && viewportsAdded.size() == 0)
3213 // We recovered an alignment for which a viewport already exists.
3214 // TODO: fix up any settings necessary for overlaying stored state onto
3215 // state recovered from another document. (may not be necessary).
3216 // we may need a binding from a viewport in memory to one recovered from
3218 // and then recover its containing af to allow the settings to be applied.
3219 // TODO: fix for vamsas demo
3221 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3223 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3224 if (seqsetobj != null)
3226 if (seqsetobj instanceof String)
3228 uniqueSeqSetId = (String) seqsetobj;
3230 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3236 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3242 * indicate that annotation colours are applied across all groups (pre
3243 * Jalview 2.8.1 behaviour)
3245 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3246 "2.8.1", object.getVersion());
3248 AlignmentPanel ap = null;
3249 boolean isnewview = true;
3252 // Check to see if this alignment already has a view id == viewId
3253 jalview.gui.AlignmentPanel views[] = Desktop
3254 .getAlignmentPanels(uniqueSeqSetId);
3255 if (views != null && views.length > 0)
3257 for (int v = 0; v < views.length; v++)
3259 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3261 // recover the existing alignpanel, alignframe, viewport
3262 af = views[v].alignFrame;
3265 // TODO: could even skip resetting view settings if we don't want to
3266 // change the local settings from other jalview processes
3275 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3276 uniqueSeqSetId, viewId, autoAlan);
3282 * Load any trees, PDB structures and viewers
3284 * Not done if flag is false (when this method is used for New View)
3286 if (loadTreesAndStructures)
3288 loadTrees(jms, view, af, av, ap);
3289 loadPDBStructures(jprovider, jseqs, af, ap);
3290 loadRnaViewers(jprovider, jseqs, ap);
3292 // and finally return.
3297 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3298 * panel is restored from separate jar entries, two (gapped and trimmed) per
3299 * sequence and secondary structure.
3301 * Currently each viewer shows just one sequence and structure (gapped and
3302 * trimmed), however this method is designed to support multiple sequences or
3303 * structures in viewers if wanted in future.
3309 private void loadRnaViewers(jarInputStreamProvider jprovider,
3310 JSeq[] jseqs, AlignmentPanel ap)
3313 * scan the sequences for references to viewers; create each one the first
3314 * time it is referenced, add Rna models to existing viewers
3316 for (JSeq jseq : jseqs)
3318 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3320 RnaViewer viewer = jseq.getRnaViewer(i);
3321 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3322 uniqueSetSuffix, ap);
3324 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3326 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3327 SequenceI seq = seqRefIds.get(jseq.getId());
3328 AlignmentAnnotation ann = this.annotationIds.get(ss
3329 .getAnnotationId());
3332 * add the structure to the Varna display (with session state copied
3333 * from the jar to a temporary file)
3335 boolean gapped = ss.isGapped();
3336 String rnaTitle = ss.getTitle();
3337 String sessionState = ss.getViewerState();
3338 String tempStateFile = copyJarEntry(jprovider, sessionState,
3340 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3341 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3343 appVarna.setInitialSelection(viewer.getSelectedRna());
3349 * Locate and return an already instantiated matching AppVarna, or create one
3353 * @param viewIdSuffix
3357 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3358 String viewIdSuffix, AlignmentPanel ap)
3361 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3362 * if load is repeated
3364 String postLoadId = viewer.getViewId() + viewIdSuffix;
3365 for (JInternalFrame frame : getAllFrames())
3367 if (frame instanceof AppVarna)
3369 AppVarna varna = (AppVarna) frame;
3370 if (postLoadId.equals(varna.getViewId()))
3372 // this viewer is already instantiated
3373 // could in future here add ap as another 'parent' of the
3374 // AppVarna window; currently just 1-to-many
3381 * viewer not found - make it
3383 RnaViewerModel model = new RnaViewerModel(postLoadId,
3384 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3385 viewer.getWidth(), viewer.getHeight(),
3386 viewer.getDividerLocation());
3387 AppVarna varna = new AppVarna(model, ap);
3393 * Load any saved trees
3401 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3402 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3404 // TODO result of automated refactoring - are all these parameters needed?
3407 for (int t = 0; t < jms.getTreeCount(); t++)
3410 Tree tree = jms.getTree(t);
3412 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3415 tp = af.ShowNewickTree(
3416 new jalview.io.NewickFile(tree.getNewick()),
3417 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3418 tree.getXpos(), tree.getYpos());
3419 if (tree.getId() != null)
3421 // perhaps bind the tree id to something ?
3426 // update local tree attributes ?
3427 // TODO: should check if tp has been manipulated by user - if so its
3428 // settings shouldn't be modified
3429 tp.setTitle(tree.getTitle());
3430 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3431 .getWidth(), tree.getHeight()));
3432 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3435 tp.treeCanvas.av = av; // af.viewport;
3436 tp.treeCanvas.ap = ap; // af.alignPanel;
3441 warn("There was a problem recovering stored Newick tree: \n"
3442 + tree.getNewick());
3446 tp.fitToWindow.setState(tree.getFitToWindow());
3447 tp.fitToWindow_actionPerformed(null);
3449 if (tree.getFontName() != null)
3451 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3452 .getFontStyle(), tree.getFontSize()));
3456 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3457 .getFontStyle(), tree.getFontSize()));
3460 tp.showPlaceholders(tree.getMarkUnlinked());
3461 tp.showBootstrap(tree.getShowBootstrap());
3462 tp.showDistances(tree.getShowDistances());
3464 tp.treeCanvas.threshold = tree.getThreshold();
3466 if (tree.getCurrentTree())
3468 af.viewport.setCurrentTree(tp.getTree());
3472 } catch (Exception ex)
3474 ex.printStackTrace();
3479 * Load and link any saved structure viewers.
3486 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3487 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3490 * Run through all PDB ids on the alignment, and collect mappings between
3491 * distinct view ids and all sequences referring to that view.
3493 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3495 for (int i = 0; i < jseqs.length; i++)
3497 if (jseqs[i].getPdbidsCount() > 0)
3499 Pdbids[] ids = jseqs[i].getPdbids();
3500 for (int p = 0; p < ids.length; p++)
3502 final int structureStateCount = ids[p].getStructureStateCount();
3503 for (int s = 0; s < structureStateCount; s++)
3505 // check to see if we haven't already created this structure view
3506 final StructureState structureState = ids[p]
3507 .getStructureState(s);
3508 String sviewid = (structureState.getViewId() == null) ? null
3509 : structureState.getViewId() + uniqueSetSuffix;
3510 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3511 // Originally : ids[p].getFile()
3512 // : TODO: verify external PDB file recovery still works in normal
3513 // jalview project load
3514 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3515 jpdb.setId(ids[p].getId());
3517 int x = structureState.getXpos();
3518 int y = structureState.getYpos();
3519 int width = structureState.getWidth();
3520 int height = structureState.getHeight();
3522 // Probably don't need to do this anymore...
3523 // Desktop.desktop.getComponentAt(x, y);
3524 // TODO: NOW: check that this recovers the PDB file correctly.
3525 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3526 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3528 if (sviewid == null)
3530 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3533 if (!structureViewers.containsKey(sviewid))
3535 structureViewers.put(sviewid,
3536 new StructureViewerModel(x, y, width, height, false,
3537 false, true, structureState.getViewId(),
3538 structureState.getType()));
3539 // Legacy pre-2.7 conversion JAL-823 :
3540 // do not assume any view has to be linked for colour by
3544 // assemble String[] { pdb files }, String[] { id for each
3545 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3546 // seqs_file 2}, boolean[] {
3547 // linkAlignPanel,superposeWithAlignpanel}} from hash
3548 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3549 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3550 | (structureState.hasAlignwithAlignPanel() ? structureState
3551 .getAlignwithAlignPanel() : false));
3554 * Default colour by linked panel to false if not specified (e.g.
3555 * for pre-2.7 projects)
3557 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3558 colourWithAlignPanel |= (structureState
3559 .hasColourwithAlignPanel() ? structureState
3560 .getColourwithAlignPanel() : false);
3561 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3564 * Default colour by viewer to true if not specified (e.g. for
3567 boolean colourByViewer = jmoldat.isColourByViewer();
3568 colourByViewer &= structureState.hasColourByJmol() ? structureState
3569 .getColourByJmol() : true;
3570 jmoldat.setColourByViewer(colourByViewer);
3572 if (jmoldat.getStateData().length() < structureState
3573 .getContent().length())
3576 jmoldat.setStateData(structureState.getContent());
3579 if (ids[p].getFile() != null)
3581 File mapkey = new File(ids[p].getFile());
3582 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3583 if (seqstrmaps == null)
3585 jmoldat.getFileData().put(
3587 seqstrmaps = jmoldat.new StructureData(pdbFile,
3590 if (!seqstrmaps.getSeqList().contains(seq))
3592 seqstrmaps.getSeqList().add(seq);
3598 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");
3605 // Instantiate the associated structure views
3606 for (Entry<String, StructureViewerModel> entry : structureViewers
3611 createOrLinkStructureViewer(entry, af, ap, jprovider);
3612 } catch (Exception e)
3614 System.err.println("Error loading structure viewer: "
3616 // failed - try the next one
3628 protected void createOrLinkStructureViewer(
3629 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3630 AlignmentPanel ap, jarInputStreamProvider jprovider)
3632 final StructureViewerModel stateData = viewerData.getValue();
3635 * Search for any viewer windows already open from other alignment views
3636 * that exactly match the stored structure state
3638 StructureViewerBase comp = findMatchingViewer(viewerData);
3642 linkStructureViewer(ap, comp, stateData);
3647 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3648 * "viewer_"+stateData.viewId
3650 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3652 createChimeraViewer(viewerData, af, jprovider);
3657 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3659 createJmolViewer(viewerData, af, jprovider);
3664 * Create a new Chimera viewer.
3670 protected void createChimeraViewer(
3671 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3672 jarInputStreamProvider jprovider)
3674 StructureViewerModel data = viewerData.getValue();
3675 String chimeraSessionFile = data.getStateData();
3678 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3680 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3681 * 'uniquified' sviewid used to reconstruct the viewer here
3683 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3684 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3687 Set<Entry<File, StructureData>> fileData = data.getFileData()
3689 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3690 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3691 for (Entry<File, StructureData> pdb : fileData)
3693 String filePath = pdb.getValue().getFilePath();
3694 String pdbId = pdb.getValue().getPdbId();
3695 // pdbs.add(new PDBEntry(filePath, pdbId));
3696 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3697 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3698 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3702 boolean colourByChimera = data.isColourByViewer();
3703 boolean colourBySequence = data.isColourWithAlignPanel();
3705 // TODO use StructureViewer as a factory here, see JAL-1761
3706 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3707 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3709 String newViewId = viewerData.getKey();
3711 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3712 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3713 colourBySequence, newViewId);
3714 cvf.setSize(data.getWidth(), data.getHeight());
3715 cvf.setLocation(data.getX(), data.getY());
3719 * Create a new Jmol window. First parse the Jmol state to translate filenames
3720 * loaded into the view, and record the order in which files are shown in the
3721 * Jmol view, so we can add the sequence mappings in same order.
3727 protected void createJmolViewer(
3728 final Entry<String, StructureViewerModel> viewerData,
3729 AlignFrame af, jarInputStreamProvider jprovider)
3731 final StructureViewerModel svattrib = viewerData.getValue();
3732 String state = svattrib.getStateData();
3735 * Pre-2.9: state element value is the Jmol state string
3737 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3740 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3742 state = readJarEntry(jprovider,
3743 getViewerJarEntryName(svattrib.getViewId()));
3746 List<String> pdbfilenames = new ArrayList<String>();
3747 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3748 List<String> pdbids = new ArrayList<String>();
3749 StringBuilder newFileLoc = new StringBuilder(64);
3750 int cp = 0, ncp, ecp;
3751 Map<File, StructureData> oldFiles = svattrib.getFileData();
3752 while ((ncp = state.indexOf("load ", cp)) > -1)
3756 // look for next filename in load statement
3757 newFileLoc.append(state.substring(cp,
3758 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3759 String oldfilenam = state.substring(ncp,
3760 ecp = state.indexOf("\"", ncp));
3761 // recover the new mapping data for this old filename
3762 // have to normalize filename - since Jmol and jalview do
3764 // translation differently.
3765 StructureData filedat = oldFiles.get(new File(oldfilenam));
3766 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3767 pdbfilenames.add(filedat.getFilePath());
3768 pdbids.add(filedat.getPdbId());
3769 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3770 newFileLoc.append("\"");
3771 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3772 // look for next file statement.
3773 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3777 // just append rest of state
3778 newFileLoc.append(state.substring(cp));
3782 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3783 newFileLoc = new StringBuilder(state);
3784 newFileLoc.append("; load append ");
3785 for (File id : oldFiles.keySet())
3787 // add this and any other pdb files that should be present in
3789 StructureData filedat = oldFiles.get(id);
3790 newFileLoc.append(filedat.getFilePath());
3791 pdbfilenames.add(filedat.getFilePath());
3792 pdbids.add(filedat.getPdbId());
3793 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3794 newFileLoc.append(" \"");
3795 newFileLoc.append(filedat.getFilePath());
3796 newFileLoc.append("\"");
3799 newFileLoc.append(";");
3802 if (newFileLoc.length() == 0)
3806 int histbug = newFileLoc.indexOf("history = ");
3810 * change "history = [true|false];" to "history = [1|0];"
3813 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3814 String val = (diff == -1) ? null : newFileLoc
3815 .substring(histbug, diff);
3816 if (val != null && val.length() >= 4)
3818 if (val.contains("e")) // eh? what can it be?
3820 if (val.trim().equals("true"))
3828 newFileLoc.replace(histbug, diff, val);
3833 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3835 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3836 final SequenceI[][] sq = seqmaps
3837 .toArray(new SequenceI[seqmaps.size()][]);
3838 final String fileloc = newFileLoc.toString();
3839 final String sviewid = viewerData.getKey();
3840 final AlignFrame alf = af;
3841 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3842 svattrib.getWidth(), svattrib.getHeight());
3845 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3850 JalviewStructureDisplayI sview = null;
3853 sview = new StructureViewer(alf.alignPanel
3854 .getStructureSelectionManager()).createView(
3855 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3856 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3857 addNewStructureViewer(sview);
3858 } catch (OutOfMemoryError ex)
3860 new OOMWarning("restoring structure view for PDB id " + id,
3861 (OutOfMemoryError) ex.getCause());
3862 if (sview != null && sview.isVisible())
3864 sview.closeViewer(false);
3865 sview.setVisible(false);
3871 } catch (InvocationTargetException ex)
3873 warn("Unexpected error when opening Jmol view.", ex);
3875 } catch (InterruptedException e)
3877 // e.printStackTrace();
3883 * Generates a name for the entry in the project jar file to hold state
3884 * information for a structure viewer
3889 protected String getViewerJarEntryName(String viewId)
3891 return VIEWER_PREFIX + viewId;
3895 * Returns any open frame that matches given structure viewer data. The match
3896 * is based on the unique viewId, or (for older project versions) the frame's
3902 protected StructureViewerBase findMatchingViewer(
3903 Entry<String, StructureViewerModel> viewerData)
3905 final String sviewid = viewerData.getKey();
3906 final StructureViewerModel svattrib = viewerData.getValue();
3907 StructureViewerBase comp = null;
3908 JInternalFrame[] frames = getAllFrames();
3909 for (JInternalFrame frame : frames)
3911 if (frame instanceof StructureViewerBase)
3914 * Post jalview 2.4 schema includes structure view id
3917 && ((StructureViewerBase) frame).getViewId()
3920 comp = (StructureViewerBase) frame;
3921 break; // break added in 2.9
3924 * Otherwise test for matching position and size of viewer frame
3926 else if (frame.getX() == svattrib.getX()
3927 && frame.getY() == svattrib.getY()
3928 && frame.getHeight() == svattrib.getHeight()
3929 && frame.getWidth() == svattrib.getWidth())
3931 comp = (StructureViewerBase) frame;
3932 // no break in faint hope of an exact match on viewId
3940 * Link an AlignmentPanel to an existing structure viewer.
3945 * @param useinViewerSuperpos
3946 * @param usetoColourbyseq
3947 * @param viewerColouring
3949 protected void linkStructureViewer(AlignmentPanel ap,
3950 StructureViewerBase viewer, StructureViewerModel stateData)
3952 // NOTE: if the jalview project is part of a shared session then
3953 // view synchronization should/could be done here.
3955 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
3956 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
3957 final boolean viewerColouring = stateData.isColourByViewer();
3958 Map<File, StructureData> oldFiles = stateData.getFileData();
3961 * Add mapping for sequences in this view to an already open viewer
3963 final AAStructureBindingModel binding = viewer.getBinding();
3964 for (File id : oldFiles.keySet())
3966 // add this and any other pdb files that should be present in the
3968 StructureData filedat = oldFiles.get(id);
3969 String pdbFile = filedat.getFilePath();
3970 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3971 binding.getSsm().setMapping(seq, null, pdbFile,
3972 jalview.io.AppletFormatAdapter.FILE);
3973 binding.addSequenceForStructFile(pdbFile, seq);
3975 // and add the AlignmentPanel's reference to the view panel
3976 viewer.addAlignmentPanel(ap);
3977 if (useinViewerSuperpos)
3979 viewer.useAlignmentPanelForSuperposition(ap);
3983 viewer.excludeAlignmentPanelForSuperposition(ap);
3985 if (usetoColourbyseq)
3987 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3991 viewer.excludeAlignmentPanelForColourbyseq(ap);
3996 * Get all frames within the Desktop.
4000 protected JInternalFrame[] getAllFrames()
4002 JInternalFrame[] frames = null;
4003 // TODO is this necessary - is it safe - risk of hanging?
4008 frames = Desktop.desktop.getAllFrames();
4009 } catch (ArrayIndexOutOfBoundsException e)
4011 // occasional No such child exceptions are thrown here...
4015 } catch (InterruptedException f)
4019 } while (frames == null);
4026 * - minimum version we are comparing against
4028 * - version of data being processsed.
4029 * @return true if version is development/null or evaluates to the same or
4030 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
4032 public static boolean isVersionStringLaterThan(String supported,
4035 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4036 || version.equalsIgnoreCase("Test")
4037 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4039 System.err.println("Assuming project file with "
4040 + (version == null ? "null" : version)
4041 + " is compatible with Jalview version " + supported);
4046 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
4048 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
4050 // convert b to decimal to catch bugfix releases within a series
4051 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
4052 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
4055 float supportedVersionToken = Float.parseFloat(curT);
4056 float myVersiontoken = Float.parseFloat(fileT);
4057 if (supportedVersionToken > myVersiontoken)
4059 // current version is newer than the version that wrote the file
4062 if (supportedVersionToken < myVersiontoken)
4064 // current version is older than the version that wrote the file
4067 } catch (NumberFormatException nfe)
4070 .println("** WARNING: Version comparison failed for tokens ("
4074 + ")\n** Current: '"
4075 + supported + "' and Version: '" + version + "'");
4078 if (currentV.hasMoreElements())
4080 // fileV has no minor version but identical series to current
4087 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4089 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4091 if (newStructureViewers != null)
4093 sview.getBinding().setFinishedLoadingFromArchive(false);
4094 newStructureViewers.add(sview);
4098 protected void setLoadingFinishedForNewStructureViewers()
4100 if (newStructureViewers != null)
4102 for (JalviewStructureDisplayI sview : newStructureViewers)
4104 sview.getBinding().setFinishedLoadingFromArchive(true);
4106 newStructureViewers.clear();
4107 newStructureViewers = null;
4111 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4112 List<SequenceI> hiddenSeqs, Alignment al,
4113 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4114 String viewId, List<JvAnnotRow> autoAlan)
4116 AlignFrame af = null;
4117 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4118 uniqueSeqSetId, viewId);
4120 af.setFileName(file, "Jalview");
4122 for (int i = 0; i < JSEQ.length; i++)
4124 af.viewport.setSequenceColour(af.viewport.getAlignment()
4125 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4128 af.viewport.setGatherViewsHere(view.getGatheredViews());
4130 if (view.getSequenceSetId() != null)
4132 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4134 af.viewport.setSequenceSetId(uniqueSeqSetId);
4137 // propagate shared settings to this new view
4138 af.viewport.setHistoryList(av.getHistoryList());
4139 af.viewport.setRedoList(av.getRedoList());
4143 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4145 // TODO: check if this method can be called repeatedly without
4146 // side-effects if alignpanel already registered.
4147 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4149 // apply Hidden regions to view.
4150 if (hiddenSeqs != null)
4152 for (int s = 0; s < JSEQ.length; s++)
4154 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
4156 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4159 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
4161 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
4164 // jalview.datamodel.SequenceI[] hseqs = new
4165 // jalview.datamodel.SequenceI[hiddenSeqs
4168 // for (int s = 0; s < hiddenSeqs.size(); s++)
4170 // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
4173 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4175 af.viewport.hideSequence(hseqs);
4178 // recover view properties and display parameters
4179 if (view.getViewName() != null)
4181 af.viewport.viewName = view.getViewName();
4182 af.setInitialTabVisible();
4184 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4187 af.viewport.setShowAnnotation(view.getShowAnnotation());
4188 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4190 af.viewport.setColourText(view.getShowColourText());
4192 af.viewport.setConservationSelected(view.getConservationSelected());
4193 af.viewport.setShowJVSuffix(view.getShowFullId());
4194 af.viewport.setRightAlignIds(view.getRightAlignIds());
4195 af.viewport.setFont(
4196 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4197 .getFontSize()), true);
4198 ViewStyleI vs = af.viewport.getViewStyle();
4199 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4200 af.viewport.setViewStyle(vs);
4201 // TODO: allow custom charWidth/Heights to be restored by updating them
4202 // after setting font - which means set above to false
4203 af.viewport.setRenderGaps(view.getRenderGaps());
4204 af.viewport.setWrapAlignment(view.getWrapAlignment());
4205 af.viewport.setShowAnnotation(view.getShowAnnotation());
4207 af.viewport.setShowBoxes(view.getShowBoxes());
4209 af.viewport.setShowText(view.getShowText());
4211 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4212 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4213 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4214 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4215 .isShowUnconserved() : false);
4216 af.viewport.setStartRes(view.getStartRes());
4217 af.viewport.setStartSeq(view.getStartSeq());
4218 af.alignPanel.updateLayout();
4219 ColourSchemeI cs = null;
4220 // apply colourschemes
4221 if (view.getBgColour() != null)
4223 if (view.getBgColour().startsWith("ucs"))
4225 cs = getUserColourScheme(jms, view.getBgColour());
4227 else if (view.getBgColour().startsWith("Annotation"))
4229 AnnotationColours viewAnnColour = view.getAnnotationColours();
4230 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4237 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4242 cs.setThreshold(view.getPidThreshold(), true);
4243 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4247 af.viewport.setGlobalColourScheme(cs);
4248 af.viewport.setColourAppliesToAllGroups(false);
4250 if (view.getConservationSelected() && cs != null)
4252 cs.setConservationInc(view.getConsThreshold());
4255 af.changeColour(cs);
4257 af.viewport.setColourAppliesToAllGroups(true);
4259 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4261 if (view.hasCentreColumnLabels())
4263 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4265 if (view.hasIgnoreGapsinConsensus())
4267 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4270 if (view.hasFollowHighlight())
4272 af.viewport.setFollowHighlight(view.getFollowHighlight());
4274 if (view.hasFollowSelection())
4276 af.viewport.followSelection = view.getFollowSelection();
4278 if (view.hasShowConsensusHistogram())
4280 af.viewport.setShowConsensusHistogram(view
4281 .getShowConsensusHistogram());
4285 af.viewport.setShowConsensusHistogram(true);
4287 if (view.hasShowSequenceLogo())
4289 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4293 af.viewport.setShowSequenceLogo(false);
4295 if (view.hasNormaliseSequenceLogo())
4297 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4299 if (view.hasShowDbRefTooltip())
4301 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4303 if (view.hasShowNPfeatureTooltip())
4305 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4307 if (view.hasShowGroupConsensus())
4309 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4313 af.viewport.setShowGroupConsensus(false);
4315 if (view.hasShowGroupConservation())
4317 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4321 af.viewport.setShowGroupConservation(false);
4324 // recover featre settings
4325 if (jms.getFeatureSettings() != null)
4327 FeaturesDisplayed fdi;
4328 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4329 String[] renderOrder = new String[jms.getFeatureSettings()
4330 .getSettingCount()];
4331 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4332 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4334 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4336 Setting setting = jms.getFeatureSettings().getSetting(fs);
4337 if (setting.hasMincolour())
4339 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4340 new Color(setting.getMincolour()), new Color(
4341 setting.getColour()), setting.getMin(),
4342 setting.getMax()) : new FeatureColour(new Color(
4343 setting.getMincolour()), new Color(setting.getColour()),
4345 if (setting.hasThreshold())
4347 gc.setThreshold(setting.getThreshold());
4348 int threshstate = setting.getThreshstate();
4349 // -1 = None, 0 = Below, 1 = Above threshold
4350 if (threshstate == 0)
4352 gc.setBelowThreshold(true);
4354 else if (threshstate == 1)
4356 gc.setAboveThreshold(true);
4359 gc.setAutoScaled(true); // default
4360 if (setting.hasAutoScale())
4362 gc.setAutoScaled(setting.getAutoScale());
4364 if (setting.hasColourByLabel())
4366 gc.setColourByLabel(setting.getColourByLabel());
4368 // and put in the feature colour table.
4369 featureColours.put(setting.getType(), gc);
4373 featureColours.put(setting.getType(), new FeatureColour(
4374 new Color(setting.getColour())));
4376 renderOrder[fs] = setting.getType();
4377 if (setting.hasOrder())
4379 featureOrder.put(setting.getType(), setting.getOrder());
4383 featureOrder.put(setting.getType(), new Float(fs
4384 / jms.getFeatureSettings().getSettingCount()));
4386 if (setting.getDisplay())
4388 fdi.setVisible(setting.getType());
4391 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4392 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4394 Group grp = jms.getFeatureSettings().getGroup(gs);
4395 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4397 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4398 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4399 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4400 FeatureRendererSettings frs = new FeatureRendererSettings(
4401 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4402 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4403 .transferSettings(frs);
4407 if (view.getHiddenColumnsCount() > 0)
4409 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4411 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4412 .getHiddenColumns(c).getEnd() // +1
4416 if (view.getCalcIdParam() != null)
4418 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4420 if (calcIdParam != null)
4422 if (recoverCalcIdParam(calcIdParam, af.viewport))
4427 warn("Couldn't recover parameters for "
4428 + calcIdParam.getCalcId());
4433 af.setMenusFromViewport(af.viewport);
4435 // TODO: we don't need to do this if the viewport is aready visible.
4437 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4438 * has a 'cdna/protein complement' view, in which case save it in order to
4439 * populate a SplitFrame once all views have been read in.
4441 String complementaryViewId = view.getComplementId();
4442 if (complementaryViewId == null)
4444 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4446 // recompute any autoannotation
4447 af.alignPanel.updateAnnotation(false, true);
4448 reorderAutoannotation(af, al, autoAlan);
4449 af.alignPanel.alignmentChanged();
4453 splitFrameCandidates.put(view, af);
4458 private ColourSchemeI constructAnnotationColour(
4459 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
4460 JalviewModelSequence jms, boolean checkGroupAnnColour)
4462 boolean propagateAnnColour = false;
4463 ColourSchemeI cs = null;
4464 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4465 if (checkGroupAnnColour && al.getGroups() != null
4466 && al.getGroups().size() > 0)
4468 // pre 2.8.1 behaviour
4469 // check to see if we should transfer annotation colours
4470 propagateAnnColour = true;
4471 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4473 if (sg.cs instanceof AnnotationColourGradient)
4475 propagateAnnColour = false;
4479 // int find annotation
4480 if (annAlignment.getAlignmentAnnotation() != null)
4482 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4484 if (annAlignment.getAlignmentAnnotation()[i].label
4485 .equals(viewAnnColour.getAnnotation()))
4487 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4489 annAlignment.getAlignmentAnnotation()[i]
4490 .setThreshold(new jalview.datamodel.GraphLine(
4491 viewAnnColour.getThreshold(), "Threshold",
4492 java.awt.Color.black)
4497 if (viewAnnColour.getColourScheme().equals("None"))
4499 cs = new AnnotationColourGradient(
4500 annAlignment.getAlignmentAnnotation()[i],
4501 new java.awt.Color(viewAnnColour.getMinColour()),
4502 new java.awt.Color(viewAnnColour.getMaxColour()),
4503 viewAnnColour.getAboveThreshold());
4505 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4507 cs = new AnnotationColourGradient(
4508 annAlignment.getAlignmentAnnotation()[i],
4509 getUserColourScheme(jms,
4510 viewAnnColour.getColourScheme()),
4511 viewAnnColour.getAboveThreshold());
4515 cs = new AnnotationColourGradient(
4516 annAlignment.getAlignmentAnnotation()[i],
4517 ColourSchemeProperty.getColour(al,
4518 viewAnnColour.getColourScheme()),
4519 viewAnnColour.getAboveThreshold());
4521 if (viewAnnColour.hasPerSequence())
4523 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4526 if (viewAnnColour.hasPredefinedColours())
4528 ((AnnotationColourGradient) cs)
4529 .setPredefinedColours(viewAnnColour
4530 .isPredefinedColours());
4532 if (propagateAnnColour && al.getGroups() != null)
4534 // Also use these settings for all the groups
4535 for (int g = 0; g < al.getGroups().size(); g++)
4537 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4545 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4546 * new AnnotationColourGradient(
4547 * annAlignment.getAlignmentAnnotation()[i], new
4548 * java.awt.Color(viewAnnColour. getMinColour()), new
4549 * java.awt.Color(viewAnnColour. getMaxColour()),
4550 * viewAnnColour.getAboveThreshold()); } else
4553 sg.cs = new AnnotationColourGradient(
4554 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4555 viewAnnColour.getAboveThreshold());
4556 if (cs instanceof AnnotationColourGradient)
4558 if (viewAnnColour.hasPerSequence())
4560 ((AnnotationColourGradient) cs)
4561 .setSeqAssociated(viewAnnColour.isPerSequence());
4563 if (viewAnnColour.hasPredefinedColours())
4565 ((AnnotationColourGradient) cs)
4566 .setPredefinedColours(viewAnnColour
4567 .isPredefinedColours());
4583 private void reorderAutoannotation(AlignFrame af, Alignment al,
4584 List<JvAnnotRow> autoAlan)
4586 // copy over visualization settings for autocalculated annotation in the
4588 if (al.getAlignmentAnnotation() != null)
4591 * Kludge for magic autoannotation names (see JAL-811)
4593 String[] magicNames = new String[] { "Consensus", "Quality",
4595 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4596 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4597 for (String nm : magicNames)
4599 visan.put(nm, nullAnnot);
4601 for (JvAnnotRow auan : autoAlan)
4603 visan.put(auan.template.label
4604 + (auan.template.getCalcId() == null ? "" : "\t"
4605 + auan.template.getCalcId()), auan);
4607 int hSize = al.getAlignmentAnnotation().length;
4608 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4609 // work through any autoCalculated annotation already on the view
4610 // removing it if it should be placed in a different location on the
4611 // annotation panel.
4612 List<String> remains = new ArrayList<String>(visan.keySet());
4613 for (int h = 0; h < hSize; h++)
4615 jalview.datamodel.AlignmentAnnotation jalan = al
4616 .getAlignmentAnnotation()[h];
4617 if (jalan.autoCalculated)
4620 JvAnnotRow valan = visan.get(k = jalan.label);
4621 if (jalan.getCalcId() != null)
4623 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4628 // delete the auto calculated row from the alignment
4629 al.deleteAnnotation(jalan, false);
4633 if (valan != nullAnnot)
4635 if (jalan != valan.template)
4637 // newly created autoannotation row instance
4638 // so keep a reference to the visible annotation row
4639 // and copy over all relevant attributes
4640 if (valan.template.graphHeight >= 0)
4643 jalan.graphHeight = valan.template.graphHeight;
4645 jalan.visible = valan.template.visible;
4647 reorder.add(new JvAnnotRow(valan.order, jalan));
4652 // Add any (possibly stale) autocalculated rows that were not appended to
4653 // the view during construction
4654 for (String other : remains)
4656 JvAnnotRow othera = visan.get(other);
4657 if (othera != nullAnnot && othera.template.getCalcId() != null
4658 && othera.template.getCalcId().length() > 0)
4660 reorder.add(othera);
4663 // now put the automatic annotation in its correct place
4664 int s = 0, srt[] = new int[reorder.size()];
4665 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4666 for (JvAnnotRow jvar : reorder)
4669 srt[s++] = jvar.order;
4672 jalview.util.QuickSort.sort(srt, rws);
4673 // and re-insert the annotation at its correct position
4674 for (JvAnnotRow jvar : rws)
4676 al.addAnnotation(jvar.template, jvar.order);
4678 af.alignPanel.adjustAnnotationHeight();
4682 Hashtable skipList = null;
4685 * TODO remove this method
4688 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4689 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4690 * throw new Error("Implementation Error. No skipList defined for this
4691 * Jalview2XML instance."); } return (AlignFrame)
4692 * skipList.get(view.getSequenceSetId()); }
4696 * Check if the Jalview view contained in object should be skipped or not.
4699 * @return true if view's sequenceSetId is a key in skipList
4701 private boolean skipViewport(JalviewModel object)
4703 if (skipList == null)
4708 if (skipList.containsKey(id = object.getJalviewModelSequence()
4709 .getViewport()[0].getSequenceSetId()))
4711 if (Cache.log != null && Cache.log.isDebugEnabled())
4713 Cache.log.debug("Skipping seuqence set id " + id);
4720 public void addToSkipList(AlignFrame af)
4722 if (skipList == null)
4724 skipList = new Hashtable();
4726 skipList.put(af.getViewport().getSequenceSetId(), af);
4729 public void clearSkipList()
4731 if (skipList != null)
4738 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4739 boolean ignoreUnrefed)
4741 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4742 Vector dseqs = null;
4745 // create a list of new dataset sequences
4746 dseqs = new Vector();
4748 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4750 Sequence vamsasSeq = vamsasSet.getSequence(i);
4751 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4753 // create a new dataset
4756 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4757 dseqs.copyInto(dsseqs);
4758 ds = new jalview.datamodel.Alignment(dsseqs);
4759 debug("Created new dataset " + vamsasSet.getDatasetId()
4760 + " for alignment " + System.identityHashCode(al));
4761 addDatasetRef(vamsasSet.getDatasetId(), ds);
4763 // set the dataset for the newly imported alignment.
4764 if (al.getDataset() == null && !ignoreUnrefed)
4773 * sequence definition to create/merge dataset sequence for
4777 * vector to add new dataset sequence to
4779 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4780 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4782 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4784 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4785 SequenceI dsq = null;
4786 if (sq != null && sq.getDatasetSequence() != null)
4788 dsq = sq.getDatasetSequence();
4790 if (sq == null && ignoreUnrefed)
4794 String sqid = vamsasSeq.getDsseqid();
4797 // need to create or add a new dataset sequence reference to this sequence
4800 dsq = seqRefIds.get(sqid);
4805 // make a new dataset sequence
4806 dsq = sq.createDatasetSequence();
4809 // make up a new dataset reference for this sequence
4810 sqid = seqHash(dsq);
4812 dsq.setVamsasId(uniqueSetSuffix + sqid);
4813 seqRefIds.put(sqid, dsq);
4818 dseqs.addElement(dsq);
4823 ds.addSequence(dsq);
4829 { // make this dataset sequence sq's dataset sequence
4830 sq.setDatasetSequence(dsq);
4831 // and update the current dataset alignment
4836 if (!dseqs.contains(dsq))
4843 if (ds.findIndex(dsq) < 0)
4845 ds.addSequence(dsq);
4852 // TODO: refactor this as a merge dataset sequence function
4853 // now check that sq (the dataset sequence) sequence really is the union of
4854 // all references to it
4855 // boolean pre = sq.getStart() < dsq.getStart();
4856 // boolean post = sq.getEnd() > dsq.getEnd();
4860 // StringBuffer sb = new StringBuffer();
4861 String newres = jalview.analysis.AlignSeq.extractGaps(
4862 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4863 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4864 && newres.length() > dsq.getLength())
4866 // Update with the longer sequence.
4870 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4871 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4872 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4873 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4875 dsq.setSequence(newres);
4877 // TODO: merges will never happen if we 'know' we have the real dataset
4878 // sequence - this should be detected when id==dssid
4880 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4881 // + (pre ? "prepended" : "") + " "
4882 // + (post ? "appended" : ""));
4888 * TODO use AlignmentI here and in related methods - needs
4889 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4891 Hashtable<String, Alignment> datasetIds = null;
4893 IdentityHashMap<Alignment, String> dataset2Ids = null;
4895 private Alignment getDatasetFor(String datasetId)
4897 if (datasetIds == null)
4899 datasetIds = new Hashtable<String, Alignment>();
4902 if (datasetIds.containsKey(datasetId))
4904 return datasetIds.get(datasetId);
4909 private void addDatasetRef(String datasetId, Alignment dataset)
4911 if (datasetIds == null)
4913 datasetIds = new Hashtable<String, Alignment>();
4915 datasetIds.put(datasetId, dataset);
4919 * make a new dataset ID for this jalview dataset alignment
4924 private String getDatasetIdRef(Alignment dataset)
4926 if (dataset.getDataset() != null)
4928 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4930 String datasetId = makeHashCode(dataset, null);
4931 if (datasetId == null)
4933 // make a new datasetId and record it
4934 if (dataset2Ids == null)
4936 dataset2Ids = new IdentityHashMap<Alignment, String>();
4940 datasetId = dataset2Ids.get(dataset);
4942 if (datasetId == null)
4944 datasetId = "ds" + dataset2Ids.size() + 1;
4945 dataset2Ids.put(dataset, datasetId);
4951 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4953 for (int d = 0; d < sequence.getDBRefCount(); d++)
4955 DBRef dr = sequence.getDBRef(d);
4956 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4957 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4958 .getVersion(), sequence.getDBRef(d).getAccessionId());
4959 if (dr.getMapping() != null)
4961 entry.setMap(addMapping(dr.getMapping()));
4963 datasetSequence.addDBRef(entry);
4967 private jalview.datamodel.Mapping addMapping(Mapping m)
4969 SequenceI dsto = null;
4970 // Mapping m = dr.getMapping();
4971 int fr[] = new int[m.getMapListFromCount() * 2];
4972 Enumeration f = m.enumerateMapListFrom();
4973 for (int _i = 0; f.hasMoreElements(); _i += 2)
4975 MapListFrom mf = (MapListFrom) f.nextElement();
4976 fr[_i] = mf.getStart();
4977 fr[_i + 1] = mf.getEnd();
4979 int fto[] = new int[m.getMapListToCount() * 2];
4980 f = m.enumerateMapListTo();
4981 for (int _i = 0; f.hasMoreElements(); _i += 2)
4983 MapListTo mf = (MapListTo) f.nextElement();
4984 fto[_i] = mf.getStart();
4985 fto[_i + 1] = mf.getEnd();
4987 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4988 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4989 if (m.getMappingChoice() != null)
4991 MappingChoice mc = m.getMappingChoice();
4992 if (mc.getDseqFor() != null)
4994 String dsfor = "" + mc.getDseqFor();
4995 if (seqRefIds.containsKey(dsfor))
5000 jmap.setTo(seqRefIds.get(dsfor));
5004 frefedSequence.add(new Object[] { dsfor, jmap });
5010 * local sequence definition
5012 Sequence ms = mc.getSequence();
5013 SequenceI djs = null;
5014 String sqid = ms.getDsseqid();
5015 if (sqid != null && sqid.length() > 0)
5018 * recover dataset sequence
5020 djs = seqRefIds.get(sqid);
5025 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5026 sqid = ((Object) ms).toString(); // make up a new hascode for
5027 // undefined dataset sequence hash
5028 // (unlikely to happen)
5034 * make a new dataset sequence and add it to refIds hash
5036 djs = new jalview.datamodel.Sequence(ms.getName(),
5038 djs.setStart(jmap.getMap().getToLowest());
5039 djs.setEnd(jmap.getMap().getToHighest());
5040 djs.setVamsasId(uniqueSetSuffix + sqid);
5042 seqRefIds.put(sqid, djs);
5045 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5054 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5055 boolean keepSeqRefs)
5058 JalviewModel jm = saveState(ap, null, null, null);
5063 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5067 uniqueSetSuffix = "";
5068 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5073 if (this.frefedSequence == null)
5075 frefedSequence = new Vector();
5078 viewportsAdded.clear();
5080 AlignFrame af = loadFromObject(jm, null, false, null);
5081 af.alignPanels.clear();
5082 af.closeMenuItem_actionPerformed(true);
5085 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5086 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5087 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5088 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5089 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5092 return af.alignPanel;
5096 * flag indicating if hashtables should be cleared on finalization TODO this
5097 * flag may not be necessary
5099 private final boolean _cleartables = true;
5101 private Hashtable jvids2vobj;
5106 * @see java.lang.Object#finalize()
5109 protected void finalize() throws Throwable
5111 // really make sure we have no buried refs left.
5116 this.seqRefIds = null;
5117 this.seqsToIds = null;
5121 private void warn(String msg)
5126 private void warn(String msg, Exception e)
5128 if (Cache.log != null)
5132 Cache.log.warn(msg, e);
5136 Cache.log.warn(msg);
5141 System.err.println("Warning: " + msg);
5144 e.printStackTrace();
5149 private void debug(String string)
5151 debug(string, null);
5154 private void debug(String msg, Exception e)
5156 if (Cache.log != null)
5160 Cache.log.debug(msg, e);
5164 Cache.log.debug(msg);
5169 System.err.println("Warning: " + msg);
5172 e.printStackTrace();
5178 * set the object to ID mapping tables used to write/recover objects and XML
5179 * ID strings for the jalview project. If external tables are provided then
5180 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5181 * object goes out of scope. - also populates the datasetIds hashtable with
5182 * alignment objects containing dataset sequences
5185 * Map from ID strings to jalview datamodel
5187 * Map from jalview datamodel to ID strings
5191 public void setObjectMappingTables(Hashtable vobj2jv,
5192 IdentityHashMap jv2vobj)
5194 this.jv2vobj = jv2vobj;
5195 this.vobj2jv = vobj2jv;
5196 Iterator ds = jv2vobj.keySet().iterator();
5198 while (ds.hasNext())
5200 Object jvobj = ds.next();
5201 id = jv2vobj.get(jvobj).toString();
5202 if (jvobj instanceof jalview.datamodel.Alignment)
5204 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5206 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5209 else if (jvobj instanceof jalview.datamodel.Sequence)
5211 // register sequence object so the XML parser can recover it.
5212 if (seqRefIds == null)
5214 seqRefIds = new HashMap<String, SequenceI>();
5216 if (seqsToIds == null)
5218 seqsToIds = new IdentityHashMap<SequenceI, String>();
5220 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5221 seqsToIds.put((SequenceI) jvobj, id);
5223 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5226 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5227 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5228 if (jvann.annotationId == null)
5230 jvann.annotationId = anid;
5232 if (!jvann.annotationId.equals(anid))
5234 // TODO verify that this is the correct behaviour
5235 this.warn("Overriding Annotation ID for " + anid
5236 + " from different id : " + jvann.annotationId);
5237 jvann.annotationId = anid;
5240 else if (jvobj instanceof String)
5242 if (jvids2vobj == null)
5244 jvids2vobj = new Hashtable();
5245 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5250 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5256 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5257 * objects created from the project archive. If string is null (default for
5258 * construction) then suffix will be set automatically.
5262 public void setUniqueSetSuffix(String string)
5264 uniqueSetSuffix = string;
5269 * uses skipList2 as the skipList for skipping views on sequence sets
5270 * associated with keys in the skipList
5274 public void setSkipList(Hashtable skipList2)
5276 skipList = skipList2;
5280 * Reads the jar entry of given name and returns its contents, or null if the
5281 * entry is not found.
5284 * @param jarEntryName
5287 protected String readJarEntry(jarInputStreamProvider jprovider,
5288 String jarEntryName)
5290 String result = null;
5291 BufferedReader in = null;
5296 * Reopen the jar input stream and traverse its entries to find a matching
5299 JarInputStream jin = jprovider.getJarInputStream();
5300 JarEntry entry = null;
5303 entry = jin.getNextJarEntry();
5304 } while (entry != null && !entry.getName().equals(jarEntryName));
5308 StringBuilder out = new StringBuilder(256);
5309 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5312 while ((data = in.readLine()) != null)
5316 result = out.toString();
5320 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5322 } catch (Exception ex)
5324 ex.printStackTrace();
5332 } catch (IOException e)
5343 * Returns an incrementing counter (0, 1, 2...)
5347 private synchronized int nextCounter()