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.Colour;
74 import jalview.schemes.ColourSchemeI;
75 import jalview.schemes.ColourSchemeProperty;
76 import jalview.schemes.FeatureColour;
77 import jalview.schemes.ResidueColourScheme;
78 import jalview.schemes.ResidueProperties;
79 import jalview.schemes.UserColourScheme;
80 import jalview.structure.StructureSelectionManager;
81 import jalview.structures.models.AAStructureBindingModel;
82 import jalview.util.MessageManager;
83 import jalview.util.Platform;
84 import jalview.util.jarInputStreamProvider;
85 import jalview.viewmodel.AlignmentViewport;
86 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
87 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
88 import jalview.ws.jws2.Jws2Discoverer;
89 import jalview.ws.jws2.dm.AAConSettings;
90 import jalview.ws.jws2.jabaws2.Jws2Instance;
91 import jalview.ws.params.ArgumentI;
92 import jalview.ws.params.AutoCalcSetting;
93 import jalview.ws.params.WsParamSetI;
95 import java.awt.Color;
96 import java.awt.Rectangle;
97 import java.io.BufferedReader;
98 import java.io.DataInputStream;
99 import java.io.DataOutputStream;
101 import java.io.FileInputStream;
102 import java.io.FileOutputStream;
103 import java.io.IOException;
104 import java.io.InputStreamReader;
105 import java.io.OutputStreamWriter;
106 import java.io.PrintWriter;
107 import java.lang.reflect.InvocationTargetException;
108 import java.net.MalformedURLException;
110 import java.util.ArrayList;
111 import java.util.Enumeration;
112 import java.util.HashMap;
113 import java.util.HashSet;
114 import java.util.Hashtable;
115 import java.util.IdentityHashMap;
116 import java.util.Iterator;
117 import java.util.LinkedHashMap;
118 import java.util.List;
119 import java.util.Map;
120 import java.util.Map.Entry;
121 import java.util.Set;
122 import java.util.StringTokenizer;
123 import java.util.Vector;
124 import java.util.jar.JarEntry;
125 import java.util.jar.JarInputStream;
126 import java.util.jar.JarOutputStream;
128 import javax.swing.JInternalFrame;
129 import javax.swing.JOptionPane;
130 import javax.swing.SwingUtilities;
132 import org.exolab.castor.xml.Marshaller;
133 import org.exolab.castor.xml.Unmarshaller;
136 * Write out the current jalview desktop state as a Jalview XML stream.
138 * Note: the vamsas objects referred to here are primitive versions of the
139 * VAMSAS project schema elements - they are not the same and most likely never
143 * @version $Revision: 1.134 $
145 public class Jalview2XML
147 private static final String VIEWER_PREFIX = "viewer_";
149 private static final String RNA_PREFIX = "rna_";
151 private static final String UTF_8 = "UTF-8";
153 // use this with nextCounter() to make unique names for entities
154 private int counter = 0;
157 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
158 * of sequence objects are created.
160 IdentityHashMap<SequenceI, String> seqsToIds = null;
163 * jalview XML Sequence ID to jalview sequence object reference (both dataset
164 * and alignment sequences. Populated as XML reps of sequence objects are
167 Map<String, SequenceI> seqRefIds = null;
169 Vector<Object[]> frefedSequence = null;
171 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
174 * Map of reconstructed AlignFrame objects that appear to have come from
175 * SplitFrame objects (have a dna/protein complement view).
177 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
180 * Map from displayed rna structure models to their saved session state jar
183 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
186 * create/return unique hash string for sq
189 * @return new or existing unique string for sq
191 String seqHash(SequenceI sq)
193 if (seqsToIds == null)
197 if (seqsToIds.containsKey(sq))
199 return seqsToIds.get(sq);
203 // create sequential key
204 String key = "sq" + (seqsToIds.size() + 1);
205 key = makeHashCode(sq, key); // check we don't have an external reference
207 seqsToIds.put(sq, key);
216 if (seqRefIds != null)
220 if (seqsToIds != null)
230 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
231 // seqRefIds = new Hashtable();
232 // seqsToIds = new IdentityHashMap();
238 if (seqsToIds == null)
240 seqsToIds = new IdentityHashMap<SequenceI, String>();
242 if (seqRefIds == null)
244 seqRefIds = new HashMap<String, SequenceI>();
252 public Jalview2XML(boolean raiseGUI)
254 this.raiseGUI = raiseGUI;
257 public void resolveFrefedSequences()
259 if (frefedSequence.size() > 0)
261 int r = 0, rSize = frefedSequence.size();
264 Object[] ref = frefedSequence.elementAt(r);
267 String sref = (String) ref[0];
268 if (seqRefIds.containsKey(sref))
270 if (ref[1] instanceof jalview.datamodel.Mapping)
272 SequenceI seq = seqRefIds.get(sref);
273 while (seq.getDatasetSequence() != null)
275 seq = seq.getDatasetSequence();
277 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
281 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
283 SequenceI seq = seqRefIds.get(sref);
284 while (seq.getDatasetSequence() != null)
286 seq = seq.getDatasetSequence();
289 && ref[2] instanceof jalview.datamodel.Mapping)
291 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
292 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
293 seq, mp.getTo(), mp.getMap());
298 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
299 + ref[2].getClass() + " type objects.");
305 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
306 + ref[1].getClass() + " type objects.");
309 frefedSequence.remove(r);
315 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
317 + " with objecttype "
318 + ref[1].getClass());
325 frefedSequence.remove(r);
333 * This maintains a map of viewports, the key being the seqSetId. Important to
334 * set historyItem and redoList for multiple views
336 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
338 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
340 String uniqueSetSuffix = "";
343 * List of pdbfiles added to Jar
345 List<String> pdbfiles = null;
347 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
348 public void saveState(File statefile)
350 FileOutputStream fos = null;
353 fos = new FileOutputStream(statefile);
354 JarOutputStream jout = new JarOutputStream(fos);
357 } catch (Exception e)
359 // TODO: inform user of the problem - they need to know if their data was
361 if (errorMessage == null)
363 errorMessage = "Couldn't write Jalview Archive to output file '"
364 + statefile + "' - See console error log for details";
368 errorMessage += "(output file was '" + statefile + "')";
378 } catch (IOException e)
388 * Writes a jalview project archive to the given Jar output stream.
392 public void saveState(JarOutputStream jout)
394 AlignFrame[] frames = Desktop.getAlignFrames();
401 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
404 * ensure cached data is clear before starting
406 // todo tidy up seqRefIds, seqsToIds initialisation / reset
408 splitFrameCandidates.clear();
413 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
414 // //////////////////////////////////////////////////
416 List<String> shortNames = new ArrayList<String>();
417 List<String> viewIds = new ArrayList<String>();
420 for (int i = frames.length - 1; i > -1; i--)
422 AlignFrame af = frames[i];
426 .containsKey(af.getViewport().getSequenceSetId()))
431 String shortName = makeFilename(af, shortNames);
433 int ap, apSize = af.alignPanels.size();
435 for (ap = 0; ap < apSize; ap++)
437 AlignmentPanel apanel = af.alignPanels.get(ap);
438 String fileName = apSize == 1 ? shortName : ap + shortName;
439 if (!fileName.endsWith(".xml"))
441 fileName = fileName + ".xml";
444 saveState(apanel, fileName, jout, viewIds);
446 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
448 if (!dsses.containsKey(dssid))
450 dsses.put(dssid, af);
455 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
461 } catch (Exception foo)
466 } catch (Exception ex)
468 // TODO: inform user of the problem - they need to know if their data was
470 if (errorMessage == null)
472 errorMessage = "Couldn't write Jalview Archive - see error output for details";
474 ex.printStackTrace();
479 * Generates a distinct file name, based on the title of the AlignFrame, by
480 * appending _n for increasing n until an unused name is generated. The new
481 * name (without its extension) is added to the list.
485 * @return the generated name, with .xml extension
487 protected String makeFilename(AlignFrame af, List<String> namesUsed)
489 String shortName = af.getTitle();
491 if (shortName.indexOf(File.separatorChar) > -1)
493 shortName = shortName.substring(shortName
494 .lastIndexOf(File.separatorChar) + 1);
499 while (namesUsed.contains(shortName))
501 if (shortName.endsWith("_" + (count - 1)))
503 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
506 shortName = shortName.concat("_" + count);
510 namesUsed.add(shortName);
512 if (!shortName.endsWith(".xml"))
514 shortName = shortName + ".xml";
519 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
520 public boolean saveAlignment(AlignFrame af, String jarFile,
526 int apSize = af.alignPanels.size();
527 FileOutputStream fos = new FileOutputStream(jarFile);
528 JarOutputStream jout = new JarOutputStream(fos);
529 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
530 List<String> viewIds = new ArrayList<String>();
532 for (AlignmentPanel apanel : af.alignPanels)
534 String jfileName = apSize == 1 ? fileName : fileName + ap;
536 if (!jfileName.endsWith(".xml"))
538 jfileName = jfileName + ".xml";
540 saveState(apanel, jfileName, jout, viewIds);
541 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
543 if (!dsses.containsKey(dssid))
545 dsses.put(dssid, af);
548 writeDatasetFor(dsses, fileName, jout);
552 } catch (Exception foo)
558 } catch (Exception ex)
560 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
561 ex.printStackTrace();
566 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
567 String fileName, JarOutputStream jout)
570 for (String dssids : dsses.keySet())
572 AlignFrame _af = dsses.get(dssids);
573 String jfileName = fileName + " Dataset for " + _af.getTitle();
574 if (!jfileName.endsWith(".xml"))
576 jfileName = jfileName + ".xml";
578 saveState(_af.alignPanel, jfileName, true, jout, null);
583 * create a JalviewModel from an alignment view and marshall it to a
587 * panel to create jalview model for
589 * name of alignment panel written to output stream
596 public JalviewModel saveState(AlignmentPanel ap, String fileName,
597 JarOutputStream jout, List<String> viewIds)
599 return saveState(ap, fileName, false, jout, viewIds);
603 * create a JalviewModel from an alignment view and marshall it to a
607 * panel to create jalview model for
609 * name of alignment panel written to output stream
611 * when true, only write the dataset for the alignment, not the data
612 * associated with the view.
618 public JalviewModel saveState(AlignmentPanel ap, String fileName,
619 boolean storeDS, JarOutputStream jout, List<String> viewIds)
623 viewIds = new ArrayList<String>();
628 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
630 AlignViewport av = ap.av;
632 JalviewModel object = new JalviewModel();
633 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
635 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
636 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
637 "Development Build"));
639 jalview.datamodel.AlignmentI jal = av.getAlignment();
641 if (av.hasHiddenRows())
643 jal = jal.getHiddenSequences().getFullAlignment();
646 SequenceSet vamsasSet = new SequenceSet();
648 JalviewModelSequence jms = new JalviewModelSequence();
650 vamsasSet.setGapChar(jal.getGapCharacter() + "");
652 if (jal.getDataset() != null)
654 // dataset id is the dataset's hashcode
655 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
658 // switch jal and the dataset
659 jal = jal.getDataset();
662 if (jal.getProperties() != null)
664 Enumeration en = jal.getProperties().keys();
665 while (en.hasMoreElements())
667 String key = en.nextElement().toString();
668 SequenceSetProperties ssp = new SequenceSetProperties();
670 ssp.setValue(jal.getProperties().get(key).toString());
671 vamsasSet.addSequenceSetProperties(ssp);
676 Set<String> calcIdSet = new HashSet<String>();
679 for (int i = 0; i < jal.getHeight(); i++)
681 final SequenceI jds = jal.getSequenceAt(i);
682 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
683 : jds.getDatasetSequence();
684 String id = seqHash(jds);
686 if (seqRefIds.get(id) != null)
688 // This happens for two reasons: 1. multiple views are being serialised.
689 // 2. the hashCode has collided with another sequence's code. This DOES
690 // HAPPEN! (PF00072.15.stk does this)
691 // JBPNote: Uncomment to debug writing out of files that do not read
692 // back in due to ArrayOutOfBoundExceptions.
693 // System.err.println("vamsasSeq backref: "+id+"");
694 // System.err.println(jds.getName()+"
695 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
696 // System.err.println("Hashcode: "+seqHash(jds));
697 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
698 // System.err.println(rsq.getName()+"
699 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
700 // System.err.println("Hashcode: "+seqHash(rsq));
704 vamsasSeq = createVamsasSequence(id, jds);
705 vamsasSet.addSequence(vamsasSeq);
706 seqRefIds.put(id, jds);
710 jseq.setStart(jds.getStart());
711 jseq.setEnd(jds.getEnd());
712 jseq.setColour(av.getSequenceColour(jds).getRGB());
714 jseq.setId(id); // jseq id should be a string not a number
717 // Store any sequences this sequence represents
718 if (av.hasHiddenRows())
720 jseq.setHidden(av.getAlignment().getHiddenSequences()
723 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
725 jalview.datamodel.SequenceI[] reps = av
726 .getRepresentedSequences(jal.getSequenceAt(i))
727 .getSequencesInOrder(jal);
729 for (int h = 0; h < reps.length; h++)
731 if (reps[h] != jal.getSequenceAt(i))
733 jseq.addHiddenSequences(jal.findIndex(reps[h]));
740 if (jds.getSequenceFeatures() != null)
742 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
744 while (index < sf.length)
746 Features features = new Features();
748 features.setBegin(sf[index].getBegin());
749 features.setEnd(sf[index].getEnd());
750 features.setDescription(sf[index].getDescription());
751 features.setType(sf[index].getType());
752 features.setFeatureGroup(sf[index].getFeatureGroup());
753 features.setScore(sf[index].getScore());
754 if (sf[index].links != null)
756 for (int l = 0; l < sf[index].links.size(); l++)
758 OtherData keyValue = new OtherData();
759 keyValue.setKey("LINK_" + l);
760 keyValue.setValue(sf[index].links.elementAt(l).toString());
761 features.addOtherData(keyValue);
764 if (sf[index].otherDetails != null)
767 Iterator<String> keys = sf[index].otherDetails.keySet()
769 while (keys.hasNext())
772 OtherData keyValue = new OtherData();
773 keyValue.setKey(key);
774 keyValue.setValue(sf[index].otherDetails.get(key).toString());
775 features.addOtherData(keyValue);
779 jseq.addFeatures(features);
784 if (jdatasq.getAllPDBEntries() != null)
786 Enumeration en = jdatasq.getAllPDBEntries().elements();
787 while (en.hasMoreElements())
789 Pdbids pdb = new Pdbids();
790 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
793 String pdbId = entry.getId();
795 pdb.setType(entry.getType());
798 * Store any structure views associated with this sequence. This
799 * section copes with duplicate entries in the project, so a dataset
800 * only view *should* be coped with sensibly.
802 // This must have been loaded, is it still visible?
803 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
804 String matchedFile = null;
805 for (int f = frames.length - 1; f > -1; f--)
807 if (frames[f] instanceof StructureViewerBase)
809 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
810 matchedFile = saveStructureState(ap, jds, pdb, entry,
811 viewIds, matchedFile, viewFrame);
813 * Only store each structure viewer's state once in the project
814 * jar. First time through only (storeDS==false)
816 String viewId = viewFrame.getViewId();
817 if (!storeDS && !viewIds.contains(viewId))
822 String viewerState = viewFrame.getStateInfo();
823 writeJarEntry(jout, getViewerJarEntryName(viewId),
824 viewerState.getBytes());
825 } catch (IOException e)
827 System.err.println("Error saving viewer state: "
834 if (matchedFile != null || entry.getFile() != null)
836 if (entry.getFile() != null)
839 matchedFile = entry.getFile();
841 pdb.setFile(matchedFile); // entry.getFile());
842 if (pdbfiles == null)
844 pdbfiles = new ArrayList<String>();
847 if (!pdbfiles.contains(pdbId))
850 copyFileToJar(jout, matchedFile, pdbId);
854 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
856 PdbentryItem item = new PdbentryItem();
857 Hashtable properties = entry.getProperty();
858 Enumeration en2 = properties.keys();
859 while (en2.hasMoreElements())
861 Property prop = new Property();
862 String key = en2.nextElement().toString();
864 prop.setValue(properties.get(key).toString());
865 item.addProperty(prop);
867 pdb.addPdbentryItem(item);
874 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
879 if (!storeDS && av.hasHiddenRows())
881 jal = av.getAlignment();
884 if (jal.getCodonFrames() != null)
886 List<AlignedCodonFrame> jac = jal.getCodonFrames();
887 for (AlignedCodonFrame acf : jac)
889 AlcodonFrame alc = new AlcodonFrame();
890 vamsasSet.addAlcodonFrame(alc);
891 if (acf.getProtMappings() != null
892 && acf.getProtMappings().length > 0)
894 SequenceI[] dnas = acf.getdnaSeqs();
895 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
896 for (int m = 0; m < pmaps.length; m++)
898 AlcodMap alcmap = new AlcodMap();
899 alcmap.setDnasq(seqHash(dnas[m]));
900 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
902 alc.addAlcodMap(alcmap);
907 // AlcodonFrame alc = new AlcodonFrame();
908 // vamsasSet.addAlcodonFrame(alc);
909 // for (int p = 0; p < acf.aaWidth; p++)
911 // Alcodon cmap = new Alcodon();
912 // if (acf.codons[p] != null)
914 // // Null codons indicate a gapped column in the translated peptide
916 // cmap.setPos1(acf.codons[p][0]);
917 // cmap.setPos2(acf.codons[p][1]);
918 // cmap.setPos3(acf.codons[p][2]);
920 // alc.addAlcodon(cmap);
922 // if (acf.getProtMappings() != null
923 // && acf.getProtMappings().length > 0)
925 // SequenceI[] dnas = acf.getdnaSeqs();
926 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
927 // for (int m = 0; m < pmaps.length; m++)
929 // AlcodMap alcmap = new AlcodMap();
930 // alcmap.setDnasq(seqHash(dnas[m]));
931 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
933 // alc.addAlcodMap(alcmap);
940 // /////////////////////////////////
941 if (!storeDS && av.currentTree != null)
943 // FIND ANY ASSOCIATED TREES
944 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
945 if (Desktop.desktop != null)
947 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
949 for (int t = 0; t < frames.length; t++)
951 if (frames[t] instanceof TreePanel)
953 TreePanel tp = (TreePanel) frames[t];
955 if (tp.treeCanvas.av.getAlignment() == jal)
957 Tree tree = new Tree();
958 tree.setTitle(tp.getTitle());
959 tree.setCurrentTree((av.currentTree == tp.getTree()));
960 tree.setNewick(tp.getTree().toString());
961 tree.setThreshold(tp.treeCanvas.threshold);
963 tree.setFitToWindow(tp.fitToWindow.getState());
964 tree.setFontName(tp.getTreeFont().getName());
965 tree.setFontSize(tp.getTreeFont().getSize());
966 tree.setFontStyle(tp.getTreeFont().getStyle());
967 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
969 tree.setShowBootstrap(tp.bootstrapMenu.getState());
970 tree.setShowDistances(tp.distanceMenu.getState());
972 tree.setHeight(tp.getHeight());
973 tree.setWidth(tp.getWidth());
974 tree.setXpos(tp.getX());
975 tree.setYpos(tp.getY());
976 tree.setId(makeHashCode(tp, null));
986 * store forward refs from an annotationRow to any groups
988 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
991 for (SequenceI sq : jal.getSequences())
993 // Store annotation on dataset sequences only
994 AlignmentAnnotation[] aa = sq.getAnnotation();
995 if (aa != null && aa.length > 0)
997 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1004 if (jal.getAlignmentAnnotation() != null)
1006 // Store the annotation shown on the alignment.
1007 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1008 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1013 if (jal.getGroups() != null)
1015 JGroup[] groups = new JGroup[jal.getGroups().size()];
1017 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1019 JGroup jGroup = new JGroup();
1020 groups[++i] = jGroup;
1022 jGroup.setStart(sg.getStartRes());
1023 jGroup.setEnd(sg.getEndRes());
1024 jGroup.setName(sg.getName());
1025 if (groupRefs.containsKey(sg))
1027 // group has references so set its ID field
1028 jGroup.setId(groupRefs.get(sg));
1032 if (sg.cs.conservationApplied())
1034 jGroup.setConsThreshold(sg.cs.getConservationInc());
1036 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1038 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1042 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1045 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1047 jGroup.setColour("AnnotationColourGradient");
1048 jGroup.setAnnotationColours(constructAnnotationColours(
1049 (jalview.schemes.AnnotationColourGradient) sg.cs,
1052 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1054 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1058 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1061 jGroup.setPidThreshold(sg.cs.getThreshold());
1064 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1065 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1066 jGroup.setDisplayText(sg.getDisplayText());
1067 jGroup.setColourText(sg.getColourText());
1068 jGroup.setTextCol1(sg.textColour.getRGB());
1069 jGroup.setTextCol2(sg.textColour2.getRGB());
1070 jGroup.setTextColThreshold(sg.thresholdTextColour);
1071 jGroup.setShowUnconserved(sg.getShowNonconserved());
1072 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1073 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1074 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1075 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1076 for (SequenceI seq : sg.getSequences())
1078 jGroup.addSeq(seqHash(seq));
1082 jms.setJGroup(groups);
1086 // /////////SAVE VIEWPORT
1087 Viewport view = new Viewport();
1088 view.setTitle(ap.alignFrame.getTitle());
1089 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1090 av.getSequenceSetId()));
1091 view.setId(av.getViewId());
1092 if (av.getCodingComplement() != null)
1094 view.setComplementId(av.getCodingComplement().getViewId());
1096 view.setViewName(av.viewName);
1097 view.setGatheredViews(av.isGatherViewsHere());
1099 Rectangle size = ap.av.getExplodedGeometry();
1100 Rectangle position = size;
1103 size = ap.alignFrame.getBounds();
1104 if (av.getCodingComplement() != null)
1106 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1114 view.setXpos(position.x);
1115 view.setYpos(position.y);
1117 view.setWidth(size.width);
1118 view.setHeight(size.height);
1120 view.setStartRes(av.startRes);
1121 view.setStartSeq(av.startSeq);
1123 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1125 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1128 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1130 AnnotationColours ac = constructAnnotationColours(
1131 (jalview.schemes.AnnotationColourGradient) av
1132 .getGlobalColourScheme(),
1135 view.setAnnotationColours(ac);
1136 view.setBgColour("AnnotationColourGradient");
1140 view.setBgColour(ColourSchemeProperty.getColourName(av
1141 .getGlobalColourScheme()));
1144 ColourSchemeI cs = av.getGlobalColourScheme();
1148 if (cs.conservationApplied())
1150 view.setConsThreshold(cs.getConservationInc());
1151 if (cs instanceof jalview.schemes.UserColourScheme)
1153 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1157 if (cs instanceof ResidueColourScheme)
1159 view.setPidThreshold(cs.getThreshold());
1163 view.setConservationSelected(av.getConservationSelected());
1164 view.setPidSelected(av.getAbovePIDThreshold());
1165 view.setFontName(av.font.getName());
1166 view.setFontSize(av.font.getSize());
1167 view.setFontStyle(av.font.getStyle());
1168 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1169 view.setRenderGaps(av.isRenderGaps());
1170 view.setShowAnnotation(av.isShowAnnotation());
1171 view.setShowBoxes(av.getShowBoxes());
1172 view.setShowColourText(av.getColourText());
1173 view.setShowFullId(av.getShowJVSuffix());
1174 view.setRightAlignIds(av.isRightAlignIds());
1175 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1176 view.setShowText(av.getShowText());
1177 view.setShowUnconserved(av.getShowUnconserved());
1178 view.setWrapAlignment(av.getWrapAlignment());
1179 view.setTextCol1(av.getTextColour().getRGB());
1180 view.setTextCol2(av.getTextColour2().getRGB());
1181 view.setTextColThreshold(av.getThresholdTextColour());
1182 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1183 view.setShowSequenceLogo(av.isShowSequenceLogo());
1184 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1185 view.setShowGroupConsensus(av.isShowGroupConsensus());
1186 view.setShowGroupConservation(av.isShowGroupConservation());
1187 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1188 view.setShowDbRefTooltip(av.isShowDBRefs());
1189 view.setFollowHighlight(av.isFollowHighlight());
1190 view.setFollowSelection(av.followSelection);
1191 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1192 if (av.getFeaturesDisplayed() != null)
1194 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1196 String[] renderOrder = ap.getSeqPanel().seqCanvas
1197 .getFeatureRenderer().getRenderOrder()
1198 .toArray(new String[0]);
1200 Vector<String> settingsAdded = new Vector<String>();
1201 if (renderOrder != null)
1203 for (int ro = 0; ro < renderOrder.length; ro++)
1205 FeatureColourI gstyle = ap.getSeqPanel().seqCanvas
1206 .getFeatureRenderer()
1207 .getFeatureStyle(renderOrder[ro]);
1208 Setting setting = new Setting();
1209 setting.setType(renderOrder[ro]);
1210 if (!gstyle.isSimpleColour())
1212 setting.setColour(gstyle.getMaxColour().getRGB());
1213 setting.setMincolour(gstyle.getMinColour().getRGB());
1214 setting.setMin(gstyle.getMin());
1215 setting.setMax(gstyle.getMax());
1216 setting.setColourByLabel(gstyle.isColourByLabel());
1217 setting.setAutoScale(gstyle.isAutoScaled());
1218 setting.setThreshold(gstyle.getThreshold());
1219 // -1 = No threshold, 0 = Below, 1 = Above
1220 setting.setThreshstate(gstyle.isAboveThreshold() ? 1
1221 : (gstyle.isBelowThreshold() ? 0 : -1));
1225 setting.setColour(gstyle.getColour().getRGB());
1228 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1230 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1231 .getOrder(renderOrder[ro]);
1234 setting.setOrder(rorder);
1236 fs.addSetting(setting);
1237 settingsAdded.addElement(renderOrder[ro]);
1241 // is groups actually supposed to be a map here ?
1242 Iterator<String> en = ap.getSeqPanel().seqCanvas
1243 .getFeatureRenderer()
1244 .getFeatureGroups().iterator();
1245 Vector<String> groupsAdded = new Vector<String>();
1246 while (en.hasNext())
1248 String grp = en.next().toString();
1249 if (groupsAdded.contains(grp))
1253 Group g = new Group();
1255 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1256 .getFeatureRenderer().checkGroupVisibility(grp, false))
1259 groupsAdded.addElement(grp);
1261 jms.setFeatureSettings(fs);
1264 if (av.hasHiddenColumns())
1266 if (av.getColumnSelection() == null
1267 || av.getColumnSelection().getHiddenColumns() == null)
1269 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1273 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1276 int[] region = av.getColumnSelection().getHiddenColumns()
1278 HiddenColumns hc = new HiddenColumns();
1279 hc.setStart(region[0]);
1280 hc.setEnd(region[1]);
1281 view.addHiddenColumns(hc);
1285 if (calcIdSet.size() > 0)
1287 for (String calcId : calcIdSet)
1289 if (calcId.trim().length() > 0)
1291 CalcIdParam cidp = createCalcIdParam(calcId, av);
1292 // Some calcIds have no parameters.
1295 view.addCalcIdParam(cidp);
1301 jms.addViewport(view);
1303 object.setJalviewModelSequence(jms);
1304 object.getVamsasModel().addSequenceSet(vamsasSet);
1306 if (jout != null && fileName != null)
1308 // We may not want to write the object to disk,
1309 // eg we can copy the alignViewport to a new view object
1310 // using save and then load
1313 System.out.println("Writing jar entry " + fileName);
1314 JarEntry entry = new JarEntry(fileName);
1315 jout.putNextEntry(entry);
1316 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1318 Marshaller marshaller = new Marshaller(pout);
1319 marshaller.marshal(object);
1322 } catch (Exception ex)
1324 // TODO: raise error in GUI if marshalling failed.
1325 ex.printStackTrace();
1332 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1333 * for each viewer, with
1335 * <li>viewer geometry (position, size, split pane divider location)</li>
1336 * <li>index of the selected structure in the viewer (currently shows gapped
1338 * <li>the id of the annotation holding RNA secondary structure</li>
1339 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1341 * Varna viewer state is also written out (in native Varna XML) to separate
1342 * project jar entries. A separate entry is written for each RNA structure
1343 * displayed, with the naming convention
1345 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1353 * @param storeDataset
1355 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1356 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1357 boolean storeDataset)
1359 if (Desktop.desktop == null)
1363 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1364 for (int f = frames.length - 1; f > -1; f--)
1366 if (frames[f] instanceof AppVarna)
1368 AppVarna varna = (AppVarna) frames[f];
1370 * link the sequence to every viewer that is showing it and is linked to
1371 * its alignment panel
1373 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1375 String viewId = varna.getViewId();
1376 RnaViewer rna = new RnaViewer();
1377 rna.setViewId(viewId);
1378 rna.setTitle(varna.getTitle());
1379 rna.setXpos(varna.getX());
1380 rna.setYpos(varna.getY());
1381 rna.setWidth(varna.getWidth());
1382 rna.setHeight(varna.getHeight());
1383 rna.setDividerLocation(varna.getDividerLocation());
1384 rna.setSelectedRna(varna.getSelectedIndex());
1385 jseq.addRnaViewer(rna);
1388 * Store each Varna panel's state once in the project per sequence.
1389 * First time through only (storeDataset==false)
1391 // boolean storeSessions = false;
1392 // String sequenceViewId = viewId + seqsToIds.get(jds);
1393 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1395 // viewIds.add(sequenceViewId);
1396 // storeSessions = true;
1398 for (RnaModel model : varna.getModels())
1400 if (model.seq == jds)
1403 * VARNA saves each view (sequence or alignment secondary
1404 * structure, gapped or trimmed) as a separate XML file
1406 String jarEntryName = rnaSessions.get(model);
1407 if (jarEntryName == null)
1410 String varnaStateFile = varna.getStateInfo(model.rna);
1411 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1412 copyFileToJar(jout, varnaStateFile, jarEntryName);
1413 rnaSessions.put(model, jarEntryName);
1415 SecondaryStructure ss = new SecondaryStructure();
1416 String annotationId = varna.getAnnotation(jds).annotationId;
1417 ss.setAnnotationId(annotationId);
1418 ss.setViewerState(jarEntryName);
1419 ss.setGapped(model.gapped);
1420 ss.setTitle(model.title);
1421 rna.addSecondaryStructure(ss);
1430 * Copy the contents of a file to a new entry added to the output jar
1434 * @param jarEntryName
1436 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1437 String jarEntryName)
1439 DataInputStream dis = null;
1442 File file = new File(infilePath);
1443 if (file.exists() && jout != null)
1445 dis = new DataInputStream(new FileInputStream(file));
1446 byte[] data = new byte[(int) file.length()];
1447 dis.readFully(data);
1448 writeJarEntry(jout, jarEntryName, data);
1450 } catch (Exception ex)
1452 ex.printStackTrace();
1460 } catch (IOException e)
1469 * Write the data to a new entry of given name in the output jar file
1472 * @param jarEntryName
1474 * @throws IOException
1476 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1477 byte[] data) throws IOException
1481 System.out.println("Writing jar entry " + jarEntryName);
1482 jout.putNextEntry(new JarEntry(jarEntryName));
1483 DataOutputStream dout = new DataOutputStream(jout);
1484 dout.write(data, 0, data.length);
1491 * Save the state of a structure viewer
1496 * the archive XML element under which to save the state
1499 * @param matchedFile
1503 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1504 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1505 String matchedFile, StructureViewerBase viewFrame)
1507 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1510 * Look for any bindings for this viewer to the PDB file of interest
1511 * (including part matches excluding chain id)
1513 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1515 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1516 final String pdbId = pdbentry.getId();
1517 if (!pdbId.equals(entry.getId())
1518 && !(entry.getId().length() > 4 && entry.getId()
1519 .toLowerCase().startsWith(pdbId.toLowerCase())))
1522 * not interested in a binding to a different PDB entry here
1526 if (matchedFile == null)
1528 matchedFile = pdbentry.getFile();
1530 else if (!matchedFile.equals(pdbentry.getFile()))
1533 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1534 + pdbentry.getFile());
1538 // can get at it if the ID
1539 // match is ambiguous (e.g.
1542 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1544 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1545 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1547 StructureState state = new StructureState();
1548 state.setVisible(true);
1549 state.setXpos(viewFrame.getX());
1550 state.setYpos(viewFrame.getY());
1551 state.setWidth(viewFrame.getWidth());
1552 state.setHeight(viewFrame.getHeight());
1553 final String viewId = viewFrame.getViewId();
1554 state.setViewId(viewId);
1555 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1556 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1557 state.setColourByJmol(viewFrame.isColouredByViewer());
1558 state.setType(viewFrame.getViewerType().toString());
1559 pdb.addStructureState(state);
1566 private AnnotationColours constructAnnotationColours(
1567 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1568 JalviewModelSequence jms)
1570 AnnotationColours ac = new AnnotationColours();
1571 ac.setAboveThreshold(acg.getAboveThreshold());
1572 ac.setThreshold(acg.getAnnotationThreshold());
1573 ac.setAnnotation(acg.getAnnotation());
1574 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1576 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1581 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1585 ac.setMaxColour(acg.getMaxColour().getRGB());
1586 ac.setMinColour(acg.getMinColour().getRGB());
1587 ac.setPerSequence(acg.isSeqAssociated());
1588 ac.setPredefinedColours(acg.isPredefinedColours());
1592 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1593 IdentityHashMap<SequenceGroup, String> groupRefs,
1594 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1595 SequenceSet vamsasSet)
1598 for (int i = 0; i < aa.length; i++)
1600 Annotation an = new Annotation();
1602 AlignmentAnnotation annotation = aa[i];
1603 if (annotation.annotationId != null)
1605 annotationIds.put(annotation.annotationId, annotation);
1608 an.setId(annotation.annotationId);
1610 an.setVisible(annotation.visible);
1612 an.setDescription(annotation.description);
1614 if (annotation.sequenceRef != null)
1616 // 2.9 JAL-1781 xref on sequence id rather than name
1617 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1619 if (annotation.groupRef != null)
1621 String groupIdr = groupRefs.get(annotation.groupRef);
1622 if (groupIdr == null)
1624 // make a locally unique String
1626 annotation.groupRef,
1627 groupIdr = ("" + System.currentTimeMillis()
1628 + annotation.groupRef.getName() + groupRefs
1631 an.setGroupRef(groupIdr.toString());
1634 // store all visualization attributes for annotation
1635 an.setGraphHeight(annotation.graphHeight);
1636 an.setCentreColLabels(annotation.centreColLabels);
1637 an.setScaleColLabels(annotation.scaleColLabel);
1638 an.setShowAllColLabels(annotation.showAllColLabels);
1639 an.setBelowAlignment(annotation.belowAlignment);
1641 if (annotation.graph > 0)
1644 an.setGraphType(annotation.graph);
1645 an.setGraphGroup(annotation.graphGroup);
1646 if (annotation.getThreshold() != null)
1648 ThresholdLine line = new ThresholdLine();
1649 line.setLabel(annotation.getThreshold().label);
1650 line.setValue(annotation.getThreshold().value);
1651 line.setColour(annotation.getThreshold().colour.getRGB());
1652 an.setThresholdLine(line);
1660 an.setLabel(annotation.label);
1662 if (annotation == av.getAlignmentQualityAnnot()
1663 || annotation == av.getAlignmentConservationAnnotation()
1664 || annotation == av.getAlignmentConsensusAnnotation()
1665 || annotation.autoCalculated)
1667 // new way of indicating autocalculated annotation -
1668 an.setAutoCalculated(annotation.autoCalculated);
1670 if (annotation.hasScore())
1672 an.setScore(annotation.getScore());
1675 if (annotation.getCalcId() != null)
1677 calcIdSet.add(annotation.getCalcId());
1678 an.setCalcId(annotation.getCalcId());
1680 if (annotation.hasProperties())
1682 for (String pr : annotation.getProperties())
1684 Property prop = new Property();
1686 prop.setValue(annotation.getProperty(pr));
1687 an.addProperty(prop);
1691 AnnotationElement ae;
1692 if (annotation.annotations != null)
1694 an.setScoreOnly(false);
1695 for (int a = 0; a < annotation.annotations.length; a++)
1697 if ((annotation == null) || (annotation.annotations[a] == null))
1702 ae = new AnnotationElement();
1703 if (annotation.annotations[a].description != null)
1705 ae.setDescription(annotation.annotations[a].description);
1707 if (annotation.annotations[a].displayCharacter != null)
1709 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1712 if (!Float.isNaN(annotation.annotations[a].value))
1714 ae.setValue(annotation.annotations[a].value);
1718 if (annotation.annotations[a].secondaryStructure > ' ')
1720 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1724 if (annotation.annotations[a].colour != null
1725 && annotation.annotations[a].colour != java.awt.Color.black)
1727 ae.setColour(annotation.annotations[a].colour.getRGB());
1730 an.addAnnotationElement(ae);
1731 if (annotation.autoCalculated)
1733 // only write one non-null entry into the annotation row -
1734 // sufficient to get the visualization attributes necessary to
1742 an.setScoreOnly(true);
1744 if (!storeDS || (storeDS && !annotation.autoCalculated))
1746 // skip autocalculated annotation - these are only provided for
1748 vamsasSet.addAnnotation(an);
1754 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1756 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1757 if (settings != null)
1759 CalcIdParam vCalcIdParam = new CalcIdParam();
1760 vCalcIdParam.setCalcId(calcId);
1761 vCalcIdParam.addServiceURL(settings.getServiceURI());
1762 // generic URI allowing a third party to resolve another instance of the
1763 // service used for this calculation
1764 for (String urls : settings.getServiceURLs())
1766 vCalcIdParam.addServiceURL(urls);
1768 vCalcIdParam.setVersion("1.0");
1769 if (settings.getPreset() != null)
1771 WsParamSetI setting = settings.getPreset();
1772 vCalcIdParam.setName(setting.getName());
1773 vCalcIdParam.setDescription(setting.getDescription());
1777 vCalcIdParam.setName("");
1778 vCalcIdParam.setDescription("Last used parameters");
1780 // need to be able to recover 1) settings 2) user-defined presets or
1781 // recreate settings from preset 3) predefined settings provided by
1782 // service - or settings that can be transferred (or discarded)
1783 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1785 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1786 // todo - decide if updateImmediately is needed for any projects.
1788 return vCalcIdParam;
1793 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1796 if (calcIdParam.getVersion().equals("1.0"))
1798 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1799 .getPreferredServiceFor(calcIdParam.getServiceURL());
1800 if (service != null)
1802 WsParamSetI parmSet = null;
1805 parmSet = service.getParamStore().parseServiceParameterFile(
1806 calcIdParam.getName(), calcIdParam.getDescription(),
1807 calcIdParam.getServiceURL(),
1808 calcIdParam.getParameters().replace("|\\n|", "\n"));
1809 } catch (IOException x)
1811 warn("Couldn't parse parameter data for "
1812 + calcIdParam.getCalcId(), x);
1815 List<ArgumentI> argList = null;
1816 if (calcIdParam.getName().length() > 0)
1818 parmSet = service.getParamStore()
1819 .getPreset(calcIdParam.getName());
1820 if (parmSet != null)
1822 // TODO : check we have a good match with settings in AACon -
1823 // otherwise we'll need to create a new preset
1828 argList = parmSet.getArguments();
1831 AAConSettings settings = new AAConSettings(
1832 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1833 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1834 calcIdParam.isNeedsUpdate());
1839 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1843 throw new Error(MessageManager.formatMessage(
1844 "error.unsupported_version_calcIdparam",
1845 new Object[] { calcIdParam.toString() }));
1849 * External mapping between jalview objects and objects yielding a valid and
1850 * unique object ID string. This is null for normal Jalview project IO, but
1851 * non-null when a jalview project is being read or written as part of a
1854 IdentityHashMap jv2vobj = null;
1857 * Construct a unique ID for jvobj using either existing bindings or if none
1858 * exist, the result of the hashcode call for the object.
1861 * jalview data object
1862 * @return unique ID for referring to jvobj
1864 private String makeHashCode(Object jvobj, String altCode)
1866 if (jv2vobj != null)
1868 Object id = jv2vobj.get(jvobj);
1871 return id.toString();
1873 // check string ID mappings
1874 if (jvids2vobj != null && jvobj instanceof String)
1876 id = jvids2vobj.get(jvobj);
1880 return id.toString();
1882 // give up and warn that something has gone wrong
1883 warn("Cannot find ID for object in external mapping : " + jvobj);
1889 * return local jalview object mapped to ID, if it exists
1893 * @return null or object bound to idcode
1895 private Object retrieveExistingObj(String idcode)
1897 if (idcode != null && vobj2jv != null)
1899 return vobj2jv.get(idcode);
1905 * binding from ID strings from external mapping table to jalview data model
1908 private Hashtable vobj2jv;
1910 private Sequence createVamsasSequence(String id, SequenceI jds)
1912 return createVamsasSequence(true, id, jds, null);
1915 private Sequence createVamsasSequence(boolean recurse, String id,
1916 SequenceI jds, SequenceI parentseq)
1918 Sequence vamsasSeq = new Sequence();
1919 vamsasSeq.setId(id);
1920 vamsasSeq.setName(jds.getName());
1921 vamsasSeq.setSequence(jds.getSequenceAsString());
1922 vamsasSeq.setDescription(jds.getDescription());
1923 jalview.datamodel.DBRefEntry[] dbrefs = null;
1924 if (jds.getDatasetSequence() != null)
1926 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1927 if (jds.getDatasetSequence().getDBRefs() != null)
1929 dbrefs = jds.getDatasetSequence().getDBRefs();
1934 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1935 // dataset sequences only
1936 dbrefs = jds.getDBRefs();
1940 for (int d = 0; d < dbrefs.length; d++)
1942 DBRef dbref = new DBRef();
1943 dbref.setSource(dbrefs[d].getSource());
1944 dbref.setVersion(dbrefs[d].getVersion());
1945 dbref.setAccessionId(dbrefs[d].getAccessionId());
1946 if (dbrefs[d].hasMap())
1948 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1950 dbref.setMapping(mp);
1952 vamsasSeq.addDBRef(dbref);
1958 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1959 SequenceI parentseq, SequenceI jds, boolean recurse)
1962 if (jmp.getMap() != null)
1966 jalview.util.MapList mlst = jmp.getMap();
1967 List<int[]> r = mlst.getFromRanges();
1968 for (int[] range : r)
1970 MapListFrom mfrom = new MapListFrom();
1971 mfrom.setStart(range[0]);
1972 mfrom.setEnd(range[1]);
1973 mp.addMapListFrom(mfrom);
1975 r = mlst.getToRanges();
1976 for (int[] range : r)
1978 MapListTo mto = new MapListTo();
1979 mto.setStart(range[0]);
1980 mto.setEnd(range[1]);
1981 mp.addMapListTo(mto);
1983 mp.setMapFromUnit(mlst.getFromRatio());
1984 mp.setMapToUnit(mlst.getToRatio());
1985 if (jmp.getTo() != null)
1987 MappingChoice mpc = new MappingChoice();
1989 && (parentseq != jmp.getTo() || parentseq
1990 .getDatasetSequence() != jmp.getTo()))
1992 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1998 SequenceI ps = null;
1999 if (parentseq != jmp.getTo()
2000 && parentseq.getDatasetSequence() != jmp.getTo())
2002 // chaining dbref rather than a handshaking one
2003 jmpid = seqHash(ps = jmp.getTo());
2007 jmpid = seqHash(ps = parentseq);
2009 mpc.setDseqFor(jmpid);
2010 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2012 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2013 seqRefIds.put(mpc.getDseqFor(), ps);
2017 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2020 mp.setMappingChoice(mpc);
2026 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2027 List<UserColourScheme> userColours, JalviewModelSequence jms)
2030 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2031 boolean newucs = false;
2032 if (!userColours.contains(ucs))
2034 userColours.add(ucs);
2037 id = "ucs" + userColours.indexOf(ucs);
2040 // actually create the scheme's entry in the XML model
2041 java.awt.Color[] colours = ucs.getColours();
2042 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2043 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2045 for (int i = 0; i < colours.length; i++)
2047 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2048 col.setName(ResidueProperties.aa[i]);
2049 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2050 jbucs.addColour(col);
2052 if (ucs.getLowerCaseColours() != null)
2054 colours = ucs.getLowerCaseColours();
2055 for (int i = 0; i < colours.length; i++)
2057 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2058 col.setName(ResidueProperties.aa[i].toLowerCase());
2059 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2060 jbucs.addColour(col);
2065 uc.setUserColourScheme(jbucs);
2066 jms.addUserColours(uc);
2072 jalview.schemes.UserColourScheme getUserColourScheme(
2073 JalviewModelSequence jms, String id)
2075 UserColours[] uc = jms.getUserColours();
2076 UserColours colours = null;
2078 for (int i = 0; i < uc.length; i++)
2080 if (uc[i].getId().equals(id))
2088 java.awt.Color[] newColours = new java.awt.Color[24];
2090 for (int i = 0; i < 24; i++)
2092 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2093 .getUserColourScheme().getColour(i).getRGB(), 16));
2096 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2099 if (colours.getUserColourScheme().getColourCount() > 24)
2101 newColours = new java.awt.Color[23];
2102 for (int i = 0; i < 23; i++)
2104 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2105 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2107 ucs.setLowerCaseColours(newColours);
2114 * contains last error message (if any) encountered by XML loader.
2116 String errorMessage = null;
2119 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2120 * exceptions are raised during project XML parsing
2122 public boolean attemptversion1parse = true;
2125 * Load a jalview project archive from a jar file
2128 * - HTTP URL or filename
2130 public AlignFrame loadJalviewAlign(final String file)
2133 jalview.gui.AlignFrame af = null;
2137 // create list to store references for any new Jmol viewers created
2138 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2139 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2140 // Workaround is to make sure caller implements the JarInputStreamProvider
2142 // so we can re-open the jar input stream for each entry.
2144 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2145 af = loadJalviewAlign(jprovider);
2147 } catch (MalformedURLException e)
2149 errorMessage = "Invalid URL format for '" + file + "'";
2155 SwingUtilities.invokeAndWait(new Runnable()
2160 setLoadingFinishedForNewStructureViewers();
2163 } catch (Exception x)
2165 System.err.println("Error loading alignment: " + x.getMessage());
2171 private jarInputStreamProvider createjarInputStreamProvider(
2172 final String file) throws MalformedURLException
2175 errorMessage = null;
2176 uniqueSetSuffix = null;
2178 viewportsAdded.clear();
2179 frefedSequence = null;
2181 if (file.startsWith("http://"))
2183 url = new URL(file);
2185 final URL _url = url;
2186 return new jarInputStreamProvider()
2190 public JarInputStream getJarInputStream() throws IOException
2194 return new JarInputStream(_url.openStream());
2198 return new JarInputStream(new FileInputStream(file));
2203 public String getFilename()
2211 * Recover jalview session from a jalview project archive. Caller may
2212 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2213 * themselves. Any null fields will be initialised with default values,
2214 * non-null fields are left alone.
2219 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2221 errorMessage = null;
2222 if (uniqueSetSuffix == null)
2224 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2226 if (seqRefIds == null)
2228 seqRefIds = new HashMap<String, SequenceI>();
2230 if (frefedSequence == null)
2232 frefedSequence = new Vector<Object[]>();
2235 AlignFrame af = null, _af = null;
2236 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2237 final String file = jprovider.getFilename();
2240 JarInputStream jin = null;
2241 JarEntry jarentry = null;
2246 jin = jprovider.getJarInputStream();
2247 for (int i = 0; i < entryCount; i++)
2249 jarentry = jin.getNextJarEntry();
2252 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2254 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2255 JalviewModel object = new JalviewModel();
2257 Unmarshaller unmar = new Unmarshaller(object);
2258 unmar.setValidation(false);
2259 object = (JalviewModel) unmar.unmarshal(in);
2260 if (true) // !skipViewport(object))
2262 _af = loadFromObject(object, file, true, jprovider);
2263 if (object.getJalviewModelSequence().getViewportCount() > 0)
2266 if (af.viewport.isGatherViewsHere())
2268 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2274 else if (jarentry != null)
2276 // Some other file here.
2279 } while (jarentry != null);
2280 resolveFrefedSequences();
2281 } catch (IOException ex)
2283 ex.printStackTrace();
2284 errorMessage = "Couldn't locate Jalview XML file : " + file;
2285 System.err.println("Exception whilst loading jalview XML file : "
2287 } catch (Exception ex)
2289 System.err.println("Parsing as Jalview Version 2 file failed.");
2290 ex.printStackTrace(System.err);
2291 if (attemptversion1parse)
2293 // Is Version 1 Jar file?
2296 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2297 } catch (Exception ex2)
2299 System.err.println("Exception whilst loading as jalviewXMLV1:");
2300 ex2.printStackTrace();
2304 if (Desktop.instance != null)
2306 Desktop.instance.stopLoading();
2310 System.out.println("Successfully loaded archive file");
2313 ex.printStackTrace();
2315 System.err.println("Exception whilst loading jalview XML file : "
2317 } catch (OutOfMemoryError e)
2319 // Don't use the OOM Window here
2320 errorMessage = "Out of memory loading jalview XML file";
2321 System.err.println("Out of memory whilst loading jalview XML file");
2322 e.printStackTrace();
2325 if (Desktop.instance != null)
2327 Desktop.instance.stopLoading();
2331 * Regather multiple views (with the same sequence set id) to the frame (if
2332 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2333 * views instead of separate frames. Note this doesn't restore a state where
2334 * some expanded views in turn have tabbed views - the last "first tab" read
2335 * in will play the role of gatherer for all.
2337 for (AlignFrame fr : gatherToThisFrame.values())
2339 Desktop.instance.gatherViews(fr);
2342 restoreSplitFrames();
2344 if (errorMessage != null)
2352 * Try to reconstruct and display SplitFrame windows, where each contains
2353 * complementary dna and protein alignments. Done by pairing up AlignFrame
2354 * objects (created earlier) which have complementary viewport ids associated.
2356 protected void restoreSplitFrames()
2358 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2359 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2360 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2363 * Identify the DNA alignments
2365 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2368 AlignFrame af = candidate.getValue();
2369 if (af.getViewport().getAlignment().isNucleotide())
2371 dna.put(candidate.getKey().getId(), af);
2376 * Try to match up the protein complements
2378 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2381 AlignFrame af = candidate.getValue();
2382 if (!af.getViewport().getAlignment().isNucleotide())
2384 String complementId = candidate.getKey().getComplementId();
2385 // only non-null complements should be in the Map
2386 if (complementId != null && dna.containsKey(complementId))
2388 final AlignFrame dnaFrame = dna.get(complementId);
2389 SplitFrame sf = createSplitFrame(dnaFrame, af);
2390 addedToSplitFrames.add(dnaFrame);
2391 addedToSplitFrames.add(af);
2392 if (af.viewport.isGatherViewsHere())
2401 * Open any that we failed to pair up (which shouldn't happen!) as
2402 * standalone AlignFrame's.
2404 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2407 AlignFrame af = candidate.getValue();
2408 if (!addedToSplitFrames.contains(af))
2410 Viewport view = candidate.getKey();
2411 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2413 System.err.println("Failed to restore view " + view.getTitle()
2414 + " to split frame");
2419 * Gather back into tabbed views as flagged.
2421 for (SplitFrame sf : gatherTo)
2423 Desktop.instance.gatherViews(sf);
2426 splitFrameCandidates.clear();
2430 * Construct and display one SplitFrame holding DNA and protein alignments.
2433 * @param proteinFrame
2436 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2437 AlignFrame proteinFrame)
2439 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2440 String title = MessageManager.getString("label.linked_view_title");
2441 int width = (int) dnaFrame.getBounds().getWidth();
2442 int height = (int) (dnaFrame.getBounds().getHeight()
2443 + proteinFrame.getBounds().getHeight() + 50);
2446 * SplitFrame location is saved to both enclosed frames
2448 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2449 Desktop.addInternalFrame(splitFrame, title, width, height);
2452 * And compute cDNA consensus (couldn't do earlier with consensus as
2453 * mappings were not yet present)
2455 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2461 * check errorMessage for a valid error message and raise an error box in the
2462 * GUI or write the current errorMessage to stderr and then clear the error
2465 protected void reportErrors()
2467 reportErrors(false);
2470 protected void reportErrors(final boolean saving)
2472 if (errorMessage != null)
2474 final String finalErrorMessage = errorMessage;
2477 javax.swing.SwingUtilities.invokeLater(new Runnable()
2482 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2483 finalErrorMessage, "Error "
2484 + (saving ? "saving" : "loading")
2485 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2491 System.err.println("Problem loading Jalview file: " + errorMessage);
2494 errorMessage = null;
2497 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2500 * when set, local views will be updated from view stored in JalviewXML
2501 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2502 * sync if this is set to true.
2504 private final boolean updateLocalViews = false;
2507 * Returns the path to a temporary file holding the PDB file for the given PDB
2508 * id. The first time of asking, searches for a file of that name in the
2509 * Jalview project jar, and copies it to a new temporary file. Any repeat
2510 * requests just return the path to the file previously created.
2516 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2518 if (alreadyLoadedPDB.containsKey(pdbId))
2520 return alreadyLoadedPDB.get(pdbId).toString();
2523 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2524 if (tempFile != null)
2526 alreadyLoadedPDB.put(pdbId, tempFile);
2532 * Copies the jar entry of given name to a new temporary file and returns the
2533 * path to the file, or null if the entry is not found.
2536 * @param jarEntryName
2538 * a prefix for the temporary file name, must be at least three
2542 protected String copyJarEntry(jarInputStreamProvider jprovider,
2543 String jarEntryName, String prefix)
2545 BufferedReader in = null;
2546 PrintWriter out = null;
2550 JarInputStream jin = jprovider.getJarInputStream();
2552 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2553 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2554 * FileInputStream(jprovider)); }
2557 JarEntry entry = null;
2560 entry = jin.getNextJarEntry();
2561 } while (entry != null && !entry.getName().equals(jarEntryName));
2564 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2565 File outFile = File.createTempFile(prefix, ".tmp");
2566 outFile.deleteOnExit();
2567 out = new PrintWriter(new FileOutputStream(outFile));
2570 while ((data = in.readLine()) != null)
2575 String t = outFile.getAbsolutePath();
2580 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2582 } catch (Exception ex)
2584 ex.printStackTrace();
2592 } catch (IOException e)
2606 private class JvAnnotRow
2608 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2615 * persisted version of annotation row from which to take vis properties
2617 public jalview.datamodel.AlignmentAnnotation template;
2620 * original position of the annotation row in the alignment
2626 * Load alignment frame from jalview XML DOM object
2631 * filename source string
2632 * @param loadTreesAndStructures
2633 * when false only create Viewport
2635 * data source provider
2636 * @return alignment frame created from view stored in DOM
2638 AlignFrame loadFromObject(JalviewModel object, String file,
2639 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2641 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2642 Sequence[] vamsasSeq = vamsasSet.getSequence();
2644 JalviewModelSequence jms = object.getJalviewModelSequence();
2646 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2649 // ////////////////////////////////
2652 List<SequenceI> hiddenSeqs = null;
2653 jalview.datamodel.Sequence jseq;
2655 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2657 boolean multipleView = false;
2659 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2660 int vi = 0; // counter in vamsasSeq array
2661 for (int i = 0; i < jseqs.length; i++)
2663 String seqId = jseqs[i].getId();
2665 if (seqRefIds.get(seqId) != null)
2667 tmpseqs.add(seqRefIds.get(seqId));
2668 multipleView = true;
2672 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2673 vamsasSeq[vi].getSequence());
2674 jseq.setDescription(vamsasSeq[vi].getDescription());
2675 jseq.setStart(jseqs[i].getStart());
2676 jseq.setEnd(jseqs[i].getEnd());
2677 jseq.setVamsasId(uniqueSetSuffix + seqId);
2678 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2683 if (jseqs[i].getHidden())
2685 if (hiddenSeqs == null)
2687 hiddenSeqs = new ArrayList<SequenceI>();
2690 hiddenSeqs.add(seqRefIds.get(seqId));
2696 // Create the alignment object from the sequence set
2697 // ///////////////////////////////
2698 SequenceI[] orderedSeqs = tmpseqs
2699 .toArray(new SequenceI[tmpseqs.size()]);
2701 Alignment al = new Alignment(orderedSeqs);
2703 // / Add the alignment properties
2704 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2706 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2707 al.setProperty(ssp.getKey(), ssp.getValue());
2711 // SequenceFeatures are added to the DatasetSequence,
2712 // so we must create or recover the dataset before loading features
2713 // ///////////////////////////////
2714 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2716 // older jalview projects do not have a dataset id.
2717 al.setDataset(null);
2721 // recover dataset - passing on flag indicating if this a 'viewless'
2722 // sequence set (a.k.a. a stored dataset for the project)
2723 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2724 .getViewportCount() == 0);
2726 // ///////////////////////////////
2728 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2731 // load sequence features, database references and any associated PDB
2732 // structures for the alignment
2733 for (int i = 0; i < vamsasSeq.length; i++)
2735 if (jseqs[i].getFeaturesCount() > 0)
2737 Features[] features = jseqs[i].getFeatures();
2738 for (int f = 0; f < features.length; f++)
2740 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2741 features[f].getType(), features[f].getDescription(),
2742 features[f].getStatus(), features[f].getBegin(),
2743 features[f].getEnd(), features[f].getFeatureGroup());
2745 sf.setScore(features[f].getScore());
2746 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2748 OtherData keyValue = features[f].getOtherData(od);
2749 if (keyValue.getKey().startsWith("LINK"))
2751 sf.addLink(keyValue.getValue());
2755 sf.setValue(keyValue.getKey(), keyValue.getValue());
2760 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2763 if (vamsasSeq[i].getDBRefCount() > 0)
2765 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2767 if (jseqs[i].getPdbidsCount() > 0)
2769 Pdbids[] ids = jseqs[i].getPdbids();
2770 for (int p = 0; p < ids.length; p++)
2772 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2773 entry.setId(ids[p].getId());
2774 if (ids[p].getType() != null)
2776 if (ids[p].getType().equalsIgnoreCase("PDB"))
2778 entry.setType(PDBEntry.Type.PDB);
2782 entry.setType(PDBEntry.Type.FILE);
2785 if (ids[p].getFile() != null)
2787 if (!pdbloaded.containsKey(ids[p].getFile()))
2789 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2793 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2796 StructureSelectionManager.getStructureSelectionManager(
2797 Desktop.instance).registerPDBEntry(entry);
2798 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2802 } // end !multipleview
2804 // ///////////////////////////////
2805 // LOAD SEQUENCE MAPPINGS
2807 if (vamsasSet.getAlcodonFrameCount() > 0)
2809 // TODO Potentially this should only be done once for all views of an
2811 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2812 for (int i = 0; i < alc.length; i++)
2814 AlignedCodonFrame cf = new AlignedCodonFrame();
2815 if (alc[i].getAlcodMapCount() > 0)
2817 AlcodMap[] maps = alc[i].getAlcodMap();
2818 for (int m = 0; m < maps.length; m++)
2820 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2822 jalview.datamodel.Mapping mapping = null;
2823 // attach to dna sequence reference.
2824 if (maps[m].getMapping() != null)
2826 mapping = addMapping(maps[m].getMapping());
2828 if (dnaseq != null && mapping.getTo() != null)
2830 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2835 frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
2840 al.addCodonFrame(cf);
2844 // ////////////////////////////////
2846 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2849 * store any annotations which forward reference a group's ID
2851 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2853 if (vamsasSet.getAnnotationCount() > 0)
2855 Annotation[] an = vamsasSet.getAnnotation();
2857 for (int i = 0; i < an.length; i++)
2859 Annotation annotation = an[i];
2862 * test if annotation is automatically calculated for this view only
2864 boolean autoForView = false;
2865 if (annotation.getLabel().equals("Quality")
2866 || annotation.getLabel().equals("Conservation")
2867 || annotation.getLabel().equals("Consensus"))
2869 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2871 if (!annotation.hasAutoCalculated())
2873 annotation.setAutoCalculated(true);
2877 || (annotation.hasAutoCalculated() && annotation
2878 .isAutoCalculated()))
2880 // remove ID - we don't recover annotation from other views for
2881 // view-specific annotation
2882 annotation.setId(null);
2885 // set visiblity for other annotation in this view
2886 String annotationId = annotation.getId();
2887 if (annotationId != null && annotationIds.containsKey(annotationId))
2889 AlignmentAnnotation jda = annotationIds.get(annotationId);
2890 // in principle Visible should always be true for annotation displayed
2891 // in multiple views
2892 if (annotation.hasVisible())
2894 jda.visible = annotation.getVisible();
2897 al.addAnnotation(jda);
2901 // Construct new annotation from model.
2902 AnnotationElement[] ae = annotation.getAnnotationElement();
2903 jalview.datamodel.Annotation[] anot = null;
2904 java.awt.Color firstColour = null;
2906 if (!annotation.getScoreOnly())
2908 anot = new jalview.datamodel.Annotation[al.getWidth()];
2909 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2911 anpos = ae[aa].getPosition();
2913 if (anpos >= anot.length)
2918 anot[anpos] = new jalview.datamodel.Annotation(
2920 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2921 (ae[aa].getSecondaryStructure() == null || ae[aa]
2922 .getSecondaryStructure().length() == 0) ? ' '
2923 : ae[aa].getSecondaryStructure().charAt(0),
2927 // JBPNote: Consider verifying dataflow for IO of secondary
2928 // structure annotation read from Stockholm files
2929 // this was added to try to ensure that
2930 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2932 // anot[ae[aa].getPosition()].displayCharacter = "";
2934 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2935 if (firstColour == null)
2937 firstColour = anot[anpos].colour;
2941 jalview.datamodel.AlignmentAnnotation jaa = null;
2943 if (annotation.getGraph())
2945 float llim = 0, hlim = 0;
2946 // if (autoForView || an[i].isAutoCalculated()) {
2949 jaa = new jalview.datamodel.AlignmentAnnotation(
2950 annotation.getLabel(), annotation.getDescription(), anot,
2951 llim, hlim, annotation.getGraphType());
2953 jaa.graphGroup = annotation.getGraphGroup();
2954 jaa._linecolour = firstColour;
2955 if (annotation.getThresholdLine() != null)
2957 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
2958 .getThresholdLine().getValue(), annotation
2959 .getThresholdLine().getLabel(), new java.awt.Color(
2960 annotation.getThresholdLine().getColour())));
2963 if (autoForView || annotation.isAutoCalculated())
2965 // Hardwire the symbol display line to ensure that labels for
2966 // histograms are displayed
2972 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2973 an[i].getDescription(), anot);
2974 jaa._linecolour = firstColour;
2976 // register new annotation
2977 if (an[i].getId() != null)
2979 annotationIds.put(an[i].getId(), jaa);
2980 jaa.annotationId = an[i].getId();
2982 // recover sequence association
2983 String sequenceRef = an[i].getSequenceRef();
2984 if (sequenceRef != null)
2986 // from 2.9 sequenceRef is to sequence id (JAL-1781)
2987 SequenceI sequence = seqRefIds.get(sequenceRef);
2988 if (sequence == null)
2990 // in pre-2.9 projects sequence ref is to sequence name
2991 sequence = al.findName(sequenceRef);
2993 if (sequence != null)
2995 jaa.createSequenceMapping(sequence, 1, true);
2996 sequence.addAlignmentAnnotation(jaa);
2999 // and make a note of any group association
3000 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3002 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3003 .get(an[i].getGroupRef());
3006 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3007 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3012 if (an[i].hasScore())
3014 jaa.setScore(an[i].getScore());
3016 if (an[i].hasVisible())
3018 jaa.visible = an[i].getVisible();
3021 if (an[i].hasCentreColLabels())
3023 jaa.centreColLabels = an[i].getCentreColLabels();
3026 if (an[i].hasScaleColLabels())
3028 jaa.scaleColLabel = an[i].getScaleColLabels();
3030 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3032 // newer files have an 'autoCalculated' flag and store calculation
3033 // state in viewport properties
3034 jaa.autoCalculated = true; // means annotation will be marked for
3035 // update at end of load.
3037 if (an[i].hasGraphHeight())
3039 jaa.graphHeight = an[i].getGraphHeight();
3041 if (an[i].hasBelowAlignment())
3043 jaa.belowAlignment = an[i].isBelowAlignment();
3045 jaa.setCalcId(an[i].getCalcId());
3046 if (an[i].getPropertyCount() > 0)
3048 for (jalview.schemabinding.version2.Property prop : an[i]
3051 jaa.setProperty(prop.getName(), prop.getValue());
3054 if (jaa.autoCalculated)
3056 autoAlan.add(new JvAnnotRow(i, jaa));
3059 // if (!autoForView)
3061 // add autocalculated group annotation and any user created annotation
3063 al.addAnnotation(jaa);
3067 // ///////////////////////
3069 // Create alignment markup and styles for this view
3070 if (jms.getJGroupCount() > 0)
3072 JGroup[] groups = jms.getJGroup();
3073 boolean addAnnotSchemeGroup = false;
3074 for (int i = 0; i < groups.length; i++)
3076 JGroup jGroup = groups[i];
3077 ColourSchemeI cs = null;
3078 if (jGroup.getColour() != null)
3080 if (jGroup.getColour().startsWith("ucs"))
3082 cs = getUserColourScheme(jms, jGroup.getColour());
3084 else if (jGroup.getColour().equals("AnnotationColourGradient")
3085 && jGroup.getAnnotationColours() != null)
3087 addAnnotSchemeGroup = true;
3092 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3097 cs.setThreshold(jGroup.getPidThreshold(), true);
3101 Vector<SequenceI> seqs = new Vector<SequenceI>();
3103 for (int s = 0; s < jGroup.getSeqCount(); s++)
3105 String seqId = jGroup.getSeq(s) + "";
3106 SequenceI ts = seqRefIds.get(seqId);
3110 seqs.addElement(ts);
3114 if (seqs.size() < 1)
3119 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3120 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3121 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3123 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3125 sg.textColour = new Colour(jGroup.getTextCol1());
3126 sg.textColour2 = new Colour(jGroup.getTextCol2());
3127 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3128 .isShowUnconserved() : false);
3129 sg.thresholdTextColour = jGroup.getTextColThreshold();
3130 if (jGroup.hasShowConsensusHistogram())
3132 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3135 if (jGroup.hasShowSequenceLogo())
3137 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3139 if (jGroup.hasNormaliseSequenceLogo())
3141 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3143 if (jGroup.hasIgnoreGapsinConsensus())
3145 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3147 if (jGroup.getConsThreshold() != 0)
3149 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3150 "All", ResidueProperties.propHash, 3,
3151 sg.getSequences(null), 0, sg.getWidth() - 1);
3153 c.verdict(false, 25);
3154 sg.cs.setConservation(c);
3157 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3159 // re-instate unique group/annotation row reference
3160 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3164 for (AlignmentAnnotation jaa : jaal)
3167 if (jaa.autoCalculated)
3169 // match up and try to set group autocalc alignment row for this
3171 if (jaa.label.startsWith("Consensus for "))
3173 sg.setConsensus(jaa);
3175 // match up and try to set group autocalc alignment row for this
3177 if (jaa.label.startsWith("Conservation for "))
3179 sg.setConservationRow(jaa);
3186 if (addAnnotSchemeGroup)
3188 // reconstruct the annotation colourscheme
3189 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3190 null, al, jms, false);
3196 // only dataset in this model, so just return.
3199 // ///////////////////////////////
3202 // If we just load in the same jar file again, the sequenceSetId
3203 // will be the same, and we end up with multiple references
3204 // to the same sequenceSet. We must modify this id on load
3205 // so that each load of the file gives a unique id
3206 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3207 String viewId = (view.getId() == null ? null : view.getId()
3209 AlignFrame af = null;
3210 AlignViewport av = null;
3211 // now check to see if we really need to create a new viewport.
3212 if (multipleView && viewportsAdded.size() == 0)
3214 // We recovered an alignment for which a viewport already exists.
3215 // TODO: fix up any settings necessary for overlaying stored state onto
3216 // state recovered from another document. (may not be necessary).
3217 // we may need a binding from a viewport in memory to one recovered from
3219 // and then recover its containing af to allow the settings to be applied.
3220 // TODO: fix for vamsas demo
3222 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3224 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3225 if (seqsetobj != null)
3227 if (seqsetobj instanceof String)
3229 uniqueSeqSetId = (String) seqsetobj;
3231 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3237 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3243 * indicate that annotation colours are applied across all groups (pre
3244 * Jalview 2.8.1 behaviour)
3246 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3247 "2.8.1", object.getVersion());
3249 AlignmentPanel ap = null;
3250 boolean isnewview = true;
3253 // Check to see if this alignment already has a view id == viewId
3254 jalview.gui.AlignmentPanel views[] = Desktop
3255 .getAlignmentPanels(uniqueSeqSetId);
3256 if (views != null && views.length > 0)
3258 for (int v = 0; v < views.length; v++)
3260 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3262 // recover the existing alignpanel, alignframe, viewport
3263 af = views[v].alignFrame;
3266 // TODO: could even skip resetting view settings if we don't want to
3267 // change the local settings from other jalview processes
3276 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3277 uniqueSeqSetId, viewId, autoAlan);
3283 * Load any trees, PDB structures and viewers
3285 * Not done if flag is false (when this method is used for New View)
3287 if (loadTreesAndStructures)
3289 loadTrees(jms, view, af, av, ap);
3290 loadPDBStructures(jprovider, jseqs, af, ap);
3291 loadRnaViewers(jprovider, jseqs, ap);
3293 // and finally return.
3298 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3299 * panel is restored from separate jar entries, two (gapped and trimmed) per
3300 * sequence and secondary structure.
3302 * Currently each viewer shows just one sequence and structure (gapped and
3303 * trimmed), however this method is designed to support multiple sequences or
3304 * structures in viewers if wanted in future.
3310 private void loadRnaViewers(jarInputStreamProvider jprovider,
3311 JSeq[] jseqs, AlignmentPanel ap)
3314 * scan the sequences for references to viewers; create each one the first
3315 * time it is referenced, add Rna models to existing viewers
3317 for (JSeq jseq : jseqs)
3319 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3321 RnaViewer viewer = jseq.getRnaViewer(i);
3322 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3323 uniqueSetSuffix, ap);
3325 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3327 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3328 SequenceI seq = seqRefIds.get(jseq.getId());
3329 AlignmentAnnotation ann = this.annotationIds.get(ss
3330 .getAnnotationId());
3333 * add the structure to the Varna display (with session state copied
3334 * from the jar to a temporary file)
3336 boolean gapped = ss.isGapped();
3337 String rnaTitle = ss.getTitle();
3338 String sessionState = ss.getViewerState();
3339 String tempStateFile = copyJarEntry(jprovider, sessionState,
3341 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3342 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3344 appVarna.setInitialSelection(viewer.getSelectedRna());
3350 * Locate and return an already instantiated matching AppVarna, or create one
3354 * @param viewIdSuffix
3358 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3359 String viewIdSuffix, AlignmentPanel ap)
3362 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3363 * if load is repeated
3365 String postLoadId = viewer.getViewId() + viewIdSuffix;
3366 for (JInternalFrame frame : getAllFrames())
3368 if (frame instanceof AppVarna)
3370 AppVarna varna = (AppVarna) frame;
3371 if (postLoadId.equals(varna.getViewId()))
3373 // this viewer is already instantiated
3374 // could in future here add ap as another 'parent' of the
3375 // AppVarna window; currently just 1-to-many
3382 * viewer not found - make it
3384 RnaViewerModel model = new RnaViewerModel(postLoadId,
3385 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3386 viewer.getWidth(), viewer.getHeight(),
3387 viewer.getDividerLocation());
3388 AppVarna varna = new AppVarna(model, ap);
3394 * Load any saved trees
3402 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3403 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3405 // TODO result of automated refactoring - are all these parameters needed?
3408 for (int t = 0; t < jms.getTreeCount(); t++)
3411 Tree tree = jms.getTree(t);
3413 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3416 tp = af.ShowNewickTree(
3417 new jalview.io.NewickFile(tree.getNewick()),
3418 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3419 tree.getXpos(), tree.getYpos());
3420 if (tree.getId() != null)
3422 // perhaps bind the tree id to something ?
3427 // update local tree attributes ?
3428 // TODO: should check if tp has been manipulated by user - if so its
3429 // settings shouldn't be modified
3430 tp.setTitle(tree.getTitle());
3431 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3432 .getWidth(), tree.getHeight()));
3433 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3436 tp.treeCanvas.av = av; // af.viewport;
3437 tp.treeCanvas.ap = ap; // af.alignPanel;
3442 warn("There was a problem recovering stored Newick tree: \n"
3443 + tree.getNewick());
3447 tp.fitToWindow.setState(tree.getFitToWindow());
3448 tp.fitToWindow_actionPerformed(null);
3450 if (tree.getFontName() != null)
3452 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3453 .getFontStyle(), tree.getFontSize()));
3457 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3458 .getFontStyle(), tree.getFontSize()));
3461 tp.showPlaceholders(tree.getMarkUnlinked());
3462 tp.showBootstrap(tree.getShowBootstrap());
3463 tp.showDistances(tree.getShowDistances());
3465 tp.treeCanvas.threshold = tree.getThreshold();
3467 if (tree.getCurrentTree())
3469 af.viewport.setCurrentTree(tp.getTree());
3473 } catch (Exception ex)
3475 ex.printStackTrace();
3480 * Load and link any saved structure viewers.
3487 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3488 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3491 * Run through all PDB ids on the alignment, and collect mappings between
3492 * distinct view ids and all sequences referring to that view.
3494 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3496 for (int i = 0; i < jseqs.length; i++)
3498 if (jseqs[i].getPdbidsCount() > 0)
3500 Pdbids[] ids = jseqs[i].getPdbids();
3501 for (int p = 0; p < ids.length; p++)
3503 final int structureStateCount = ids[p].getStructureStateCount();
3504 for (int s = 0; s < structureStateCount; s++)
3506 // check to see if we haven't already created this structure view
3507 final StructureState structureState = ids[p]
3508 .getStructureState(s);
3509 String sviewid = (structureState.getViewId() == null) ? null
3510 : structureState.getViewId() + uniqueSetSuffix;
3511 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3512 // Originally : ids[p].getFile()
3513 // : TODO: verify external PDB file recovery still works in normal
3514 // jalview project load
3515 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3516 jpdb.setId(ids[p].getId());
3518 int x = structureState.getXpos();
3519 int y = structureState.getYpos();
3520 int width = structureState.getWidth();
3521 int height = structureState.getHeight();
3523 // Probably don't need to do this anymore...
3524 // Desktop.desktop.getComponentAt(x, y);
3525 // TODO: NOW: check that this recovers the PDB file correctly.
3526 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3527 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3529 if (sviewid == null)
3531 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3534 if (!structureViewers.containsKey(sviewid))
3536 structureViewers.put(sviewid,
3537 new StructureViewerModel(x, y, width, height, false,
3538 false, true, structureState.getViewId(),
3539 structureState.getType()));
3540 // Legacy pre-2.7 conversion JAL-823 :
3541 // do not assume any view has to be linked for colour by
3545 // assemble String[] { pdb files }, String[] { id for each
3546 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3547 // seqs_file 2}, boolean[] {
3548 // linkAlignPanel,superposeWithAlignpanel}} from hash
3549 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3550 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3551 | (structureState.hasAlignwithAlignPanel() ? structureState
3552 .getAlignwithAlignPanel() : false));
3555 * Default colour by linked panel to false if not specified (e.g.
3556 * for pre-2.7 projects)
3558 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3559 colourWithAlignPanel |= (structureState
3560 .hasColourwithAlignPanel() ? structureState
3561 .getColourwithAlignPanel() : false);
3562 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3565 * Default colour by viewer to true if not specified (e.g. for
3568 boolean colourByViewer = jmoldat.isColourByViewer();
3569 colourByViewer &= structureState.hasColourByJmol() ? structureState
3570 .getColourByJmol() : true;
3571 jmoldat.setColourByViewer(colourByViewer);
3573 if (jmoldat.getStateData().length() < structureState
3574 .getContent().length())
3577 jmoldat.setStateData(structureState.getContent());
3580 if (ids[p].getFile() != null)
3582 File mapkey = new File(ids[p].getFile());
3583 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3584 if (seqstrmaps == null)
3586 jmoldat.getFileData().put(
3588 seqstrmaps = jmoldat.new StructureData(pdbFile,
3591 if (!seqstrmaps.getSeqList().contains(seq))
3593 seqstrmaps.getSeqList().add(seq);
3599 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");
3606 // Instantiate the associated structure views
3607 for (Entry<String, StructureViewerModel> entry : structureViewers
3612 createOrLinkStructureViewer(entry, af, ap, jprovider);
3613 } catch (Exception e)
3615 System.err.println("Error loading structure viewer: "
3617 // failed - try the next one
3629 protected void createOrLinkStructureViewer(
3630 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3631 AlignmentPanel ap, jarInputStreamProvider jprovider)
3633 final StructureViewerModel stateData = viewerData.getValue();
3636 * Search for any viewer windows already open from other alignment views
3637 * that exactly match the stored structure state
3639 StructureViewerBase comp = findMatchingViewer(viewerData);
3643 linkStructureViewer(ap, comp, stateData);
3648 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3649 * "viewer_"+stateData.viewId
3651 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3653 createChimeraViewer(viewerData, af, jprovider);
3658 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3660 createJmolViewer(viewerData, af, jprovider);
3665 * Create a new Chimera viewer.
3671 protected void createChimeraViewer(
3672 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3673 jarInputStreamProvider jprovider)
3675 StructureViewerModel data = viewerData.getValue();
3676 String chimeraSessionFile = data.getStateData();
3679 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3681 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3682 * 'uniquified' sviewid used to reconstruct the viewer here
3684 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3685 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3688 Set<Entry<File, StructureData>> fileData = data.getFileData()
3690 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3691 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3692 for (Entry<File, StructureData> pdb : fileData)
3694 String filePath = pdb.getValue().getFilePath();
3695 String pdbId = pdb.getValue().getPdbId();
3696 // pdbs.add(new PDBEntry(filePath, pdbId));
3697 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3698 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3699 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3703 boolean colourByChimera = data.isColourByViewer();
3704 boolean colourBySequence = data.isColourWithAlignPanel();
3706 // TODO use StructureViewer as a factory here, see JAL-1761
3707 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3708 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3710 String newViewId = viewerData.getKey();
3712 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3713 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3714 colourBySequence, newViewId);
3715 cvf.setSize(data.getWidth(), data.getHeight());
3716 cvf.setLocation(data.getX(), data.getY());
3720 * Create a new Jmol window. First parse the Jmol state to translate filenames
3721 * loaded into the view, and record the order in which files are shown in the
3722 * Jmol view, so we can add the sequence mappings in same order.
3728 protected void createJmolViewer(
3729 final Entry<String, StructureViewerModel> viewerData,
3730 AlignFrame af, jarInputStreamProvider jprovider)
3732 final StructureViewerModel svattrib = viewerData.getValue();
3733 String state = svattrib.getStateData();
3736 * Pre-2.9: state element value is the Jmol state string
3738 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3741 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3743 state = readJarEntry(jprovider,
3744 getViewerJarEntryName(svattrib.getViewId()));
3747 List<String> pdbfilenames = new ArrayList<String>();
3748 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3749 List<String> pdbids = new ArrayList<String>();
3750 StringBuilder newFileLoc = new StringBuilder(64);
3751 int cp = 0, ncp, ecp;
3752 Map<File, StructureData> oldFiles = svattrib.getFileData();
3753 while ((ncp = state.indexOf("load ", cp)) > -1)
3757 // look for next filename in load statement
3758 newFileLoc.append(state.substring(cp,
3759 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3760 String oldfilenam = state.substring(ncp,
3761 ecp = state.indexOf("\"", ncp));
3762 // recover the new mapping data for this old filename
3763 // have to normalize filename - since Jmol and jalview do
3765 // translation differently.
3766 StructureData filedat = oldFiles.get(new File(oldfilenam));
3767 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3768 pdbfilenames.add(filedat.getFilePath());
3769 pdbids.add(filedat.getPdbId());
3770 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3771 newFileLoc.append("\"");
3772 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3773 // look for next file statement.
3774 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3778 // just append rest of state
3779 newFileLoc.append(state.substring(cp));
3783 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3784 newFileLoc = new StringBuilder(state);
3785 newFileLoc.append("; load append ");
3786 for (File id : oldFiles.keySet())
3788 // add this and any other pdb files that should be present in
3790 StructureData filedat = oldFiles.get(id);
3791 newFileLoc.append(filedat.getFilePath());
3792 pdbfilenames.add(filedat.getFilePath());
3793 pdbids.add(filedat.getPdbId());
3794 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3795 newFileLoc.append(" \"");
3796 newFileLoc.append(filedat.getFilePath());
3797 newFileLoc.append("\"");
3800 newFileLoc.append(";");
3803 if (newFileLoc.length() == 0)
3807 int histbug = newFileLoc.indexOf("history = ");
3811 * change "history = [true|false];" to "history = [1|0];"
3814 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3815 String val = (diff == -1) ? null : newFileLoc
3816 .substring(histbug, diff);
3817 if (val != null && val.length() >= 4)
3819 if (val.contains("e")) // eh? what can it be?
3821 if (val.trim().equals("true"))
3829 newFileLoc.replace(histbug, diff, val);
3834 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3836 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3837 final SequenceI[][] sq = seqmaps
3838 .toArray(new SequenceI[seqmaps.size()][]);
3839 final String fileloc = newFileLoc.toString();
3840 final String sviewid = viewerData.getKey();
3841 final AlignFrame alf = af;
3842 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3843 svattrib.getWidth(), svattrib.getHeight());
3846 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3851 JalviewStructureDisplayI sview = null;
3854 sview = new StructureViewer(alf.alignPanel
3855 .getStructureSelectionManager()).createView(
3856 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3857 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3858 addNewStructureViewer(sview);
3859 } catch (OutOfMemoryError ex)
3861 new OOMWarning("restoring structure view for PDB id " + id,
3862 (OutOfMemoryError) ex.getCause());
3863 if (sview != null && sview.isVisible())
3865 sview.closeViewer(false);
3866 sview.setVisible(false);
3872 } catch (InvocationTargetException ex)
3874 warn("Unexpected error when opening Jmol view.", ex);
3876 } catch (InterruptedException e)
3878 // e.printStackTrace();
3884 * Generates a name for the entry in the project jar file to hold state
3885 * information for a structure viewer
3890 protected String getViewerJarEntryName(String viewId)
3892 return VIEWER_PREFIX + viewId;
3896 * Returns any open frame that matches given structure viewer data. The match
3897 * is based on the unique viewId, or (for older project versions) the frame's
3903 protected StructureViewerBase findMatchingViewer(
3904 Entry<String, StructureViewerModel> viewerData)
3906 final String sviewid = viewerData.getKey();
3907 final StructureViewerModel svattrib = viewerData.getValue();
3908 StructureViewerBase comp = null;
3909 JInternalFrame[] frames = getAllFrames();
3910 for (JInternalFrame frame : frames)
3912 if (frame instanceof StructureViewerBase)
3915 * Post jalview 2.4 schema includes structure view id
3918 && ((StructureViewerBase) frame).getViewId()
3921 comp = (StructureViewerBase) frame;
3922 break; // break added in 2.9
3925 * Otherwise test for matching position and size of viewer frame
3927 else if (frame.getX() == svattrib.getX()
3928 && frame.getY() == svattrib.getY()
3929 && frame.getHeight() == svattrib.getHeight()
3930 && frame.getWidth() == svattrib.getWidth())
3932 comp = (StructureViewerBase) frame;
3933 // no break in faint hope of an exact match on viewId
3941 * Link an AlignmentPanel to an existing structure viewer.
3946 * @param useinViewerSuperpos
3947 * @param usetoColourbyseq
3948 * @param viewerColouring
3950 protected void linkStructureViewer(AlignmentPanel ap,
3951 StructureViewerBase viewer, StructureViewerModel stateData)
3953 // NOTE: if the jalview project is part of a shared session then
3954 // view synchronization should/could be done here.
3956 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
3957 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
3958 final boolean viewerColouring = stateData.isColourByViewer();
3959 Map<File, StructureData> oldFiles = stateData.getFileData();
3962 * Add mapping for sequences in this view to an already open viewer
3964 final AAStructureBindingModel binding = viewer.getBinding();
3965 for (File id : oldFiles.keySet())
3967 // add this and any other pdb files that should be present in the
3969 StructureData filedat = oldFiles.get(id);
3970 String pdbFile = filedat.getFilePath();
3971 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3972 binding.getSsm().setMapping(seq, null, pdbFile,
3973 jalview.io.AppletFormatAdapter.FILE);
3974 binding.addSequenceForStructFile(pdbFile, seq);
3976 // and add the AlignmentPanel's reference to the view panel
3977 viewer.addAlignmentPanel(ap);
3978 if (useinViewerSuperpos)
3980 viewer.useAlignmentPanelForSuperposition(ap);
3984 viewer.excludeAlignmentPanelForSuperposition(ap);
3986 if (usetoColourbyseq)
3988 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3992 viewer.excludeAlignmentPanelForColourbyseq(ap);
3997 * Get all frames within the Desktop.
4001 protected JInternalFrame[] getAllFrames()
4003 JInternalFrame[] frames = null;
4004 // TODO is this necessary - is it safe - risk of hanging?
4009 frames = Desktop.desktop.getAllFrames();
4010 } catch (ArrayIndexOutOfBoundsException e)
4012 // occasional No such child exceptions are thrown here...
4016 } catch (InterruptedException f)
4020 } while (frames == null);
4027 * - minimum version we are comparing against
4029 * - version of data being processsed.
4030 * @return true if version is development/null or evaluates to the same or
4031 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
4033 public static boolean isVersionStringLaterThan(String supported,
4036 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4037 || version.equalsIgnoreCase("Test")
4038 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4040 System.err.println("Assuming project file with "
4041 + (version == null ? "null" : version)
4042 + " is compatible with Jalview version " + supported);
4047 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
4049 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
4051 // convert b to decimal to catch bugfix releases within a series
4052 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
4053 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
4056 float supportedVersionToken = Float.parseFloat(curT);
4057 float myVersiontoken = Float.parseFloat(fileT);
4058 if (supportedVersionToken > myVersiontoken)
4060 // current version is newer than the version that wrote the file
4063 if (supportedVersionToken < myVersiontoken)
4065 // current version is older than the version that wrote the file
4068 } catch (NumberFormatException nfe)
4071 .println("** WARNING: Version comparison failed for tokens ("
4075 + ")\n** Current: '"
4076 + supported + "' and Version: '" + version + "'");
4079 if (currentV.hasMoreElements())
4081 // fileV has no minor version but identical series to current
4088 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4090 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4092 if (newStructureViewers != null)
4094 sview.getBinding().setFinishedLoadingFromArchive(false);
4095 newStructureViewers.add(sview);
4099 protected void setLoadingFinishedForNewStructureViewers()
4101 if (newStructureViewers != null)
4103 for (JalviewStructureDisplayI sview : newStructureViewers)
4105 sview.getBinding().setFinishedLoadingFromArchive(true);
4107 newStructureViewers.clear();
4108 newStructureViewers = null;
4112 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4113 List<SequenceI> hiddenSeqs, Alignment al,
4114 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4115 String viewId, List<JvAnnotRow> autoAlan)
4117 AlignFrame af = null;
4118 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4119 uniqueSeqSetId, viewId);
4121 af.setFileName(file, "Jalview");
4123 for (int i = 0; i < JSEQ.length; i++)
4125 af.viewport.setSequenceColour(af.viewport.getAlignment()
4126 .getSequenceAt(i), new Colour(JSEQ[i].getColour()));
4129 af.viewport.setGatherViewsHere(view.getGatheredViews());
4131 if (view.getSequenceSetId() != null)
4133 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4135 af.viewport.setSequenceSetId(uniqueSeqSetId);
4138 // propagate shared settings to this new view
4139 af.viewport.setHistoryList(av.getHistoryList());
4140 af.viewport.setRedoList(av.getRedoList());
4144 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4146 // TODO: check if this method can be called repeatedly without
4147 // side-effects if alignpanel already registered.
4148 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4150 // apply Hidden regions to view.
4151 if (hiddenSeqs != null)
4153 for (int s = 0; s < JSEQ.length; s++)
4155 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
4157 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4160 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
4162 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
4165 // jalview.datamodel.SequenceI[] hseqs = new
4166 // jalview.datamodel.SequenceI[hiddenSeqs
4169 // for (int s = 0; s < hiddenSeqs.size(); s++)
4171 // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
4174 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4176 af.viewport.hideSequence(hseqs);
4179 // recover view properties and display parameters
4180 if (view.getViewName() != null)
4182 af.viewport.viewName = view.getViewName();
4183 af.setInitialTabVisible();
4185 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4188 af.viewport.setShowAnnotation(view.getShowAnnotation());
4189 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4191 af.viewport.setColourText(view.getShowColourText());
4193 af.viewport.setConservationSelected(view.getConservationSelected());
4194 af.viewport.setShowJVSuffix(view.getShowFullId());
4195 af.viewport.setRightAlignIds(view.getRightAlignIds());
4196 af.viewport.setFont(
4197 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4198 .getFontSize()), true);
4199 ViewStyleI vs = af.viewport.getViewStyle();
4200 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4201 af.viewport.setViewStyle(vs);
4202 // TODO: allow custom charWidth/Heights to be restored by updating them
4203 // after setting font - which means set above to false
4204 af.viewport.setRenderGaps(view.getRenderGaps());
4205 af.viewport.setWrapAlignment(view.getWrapAlignment());
4206 af.viewport.setShowAnnotation(view.getShowAnnotation());
4208 af.viewport.setShowBoxes(view.getShowBoxes());
4210 af.viewport.setShowText(view.getShowText());
4212 af.viewport.setTextColour(new Colour(view.getTextCol1()));
4213 af.viewport.setTextColour2(new Colour(view.getTextCol2()));
4214 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4215 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4216 .isShowUnconserved() : false);
4217 af.viewport.setStartRes(view.getStartRes());
4218 af.viewport.setStartSeq(view.getStartSeq());
4219 af.alignPanel.updateLayout();
4220 ColourSchemeI cs = null;
4221 // apply colourschemes
4222 if (view.getBgColour() != null)
4224 if (view.getBgColour().startsWith("ucs"))
4226 cs = getUserColourScheme(jms, view.getBgColour());
4228 else if (view.getBgColour().startsWith("Annotation"))
4230 AnnotationColours viewAnnColour = view.getAnnotationColours();
4231 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4238 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4243 cs.setThreshold(view.getPidThreshold(), true);
4244 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4248 af.viewport.setGlobalColourScheme(cs);
4249 af.viewport.setColourAppliesToAllGroups(false);
4251 if (view.getConservationSelected() && cs != null)
4253 cs.setConservationInc(view.getConsThreshold());
4256 af.changeColour(cs);
4258 af.viewport.setColourAppliesToAllGroups(true);
4260 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4262 if (view.hasCentreColumnLabels())
4264 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4266 if (view.hasIgnoreGapsinConsensus())
4268 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4271 if (view.hasFollowHighlight())
4273 af.viewport.setFollowHighlight(view.getFollowHighlight());
4275 if (view.hasFollowSelection())
4277 af.viewport.followSelection = view.getFollowSelection();
4279 if (view.hasShowConsensusHistogram())
4281 af.viewport.setShowConsensusHistogram(view
4282 .getShowConsensusHistogram());
4286 af.viewport.setShowConsensusHistogram(true);
4288 if (view.hasShowSequenceLogo())
4290 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4294 af.viewport.setShowSequenceLogo(false);
4296 if (view.hasNormaliseSequenceLogo())
4298 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4300 if (view.hasShowDbRefTooltip())
4302 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4304 if (view.hasShowNPfeatureTooltip())
4306 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4308 if (view.hasShowGroupConsensus())
4310 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4314 af.viewport.setShowGroupConsensus(false);
4316 if (view.hasShowGroupConservation())
4318 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4322 af.viewport.setShowGroupConservation(false);
4325 // recover featre settings
4326 if (jms.getFeatureSettings() != null)
4328 FeaturesDisplayed fdi;
4329 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4330 String[] renderOrder = new String[jms.getFeatureSettings()
4331 .getSettingCount()];
4332 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4333 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4335 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4337 Setting setting = jms.getFeatureSettings().getSetting(fs);
4338 if (setting.hasMincolour())
4340 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4341 new Colour(new Color(setting.getMincolour())),
4342 new Colour(new Color(setting.getColour())),
4343 setting.getMin(), setting.getMax()) : new FeatureColour(
4344 new Colour(new Color(setting.getMincolour())),
4345 new Colour(new Color(setting.getColour())),
4347 if (setting.hasThreshold())
4349 gc.setThreshold(setting.getThreshold());
4350 int threshstate = setting.getThreshstate();
4351 // -1 = None, 0 = Below, 1 = Above threshold
4352 if (threshstate == 0)
4354 gc.setBelowThreshold(true);
4356 else if (threshstate == 1)
4358 gc.setAboveThreshold(true);
4361 gc.setAutoScaled(true); // default
4362 if (setting.hasAutoScale())
4364 gc.setAutoScaled(setting.getAutoScale());
4366 if (setting.hasColourByLabel())
4368 gc.setColourByLabel(setting.getColourByLabel());
4370 // and put in the feature colour table.
4371 featureColours.put(setting.getType(), gc);
4375 featureColours.put(setting.getType(), new FeatureColour(
4376 new Colour(new Color(setting.getColour()))));
4378 renderOrder[fs] = setting.getType();
4379 if (setting.hasOrder())
4381 featureOrder.put(setting.getType(), setting.getOrder());
4385 featureOrder.put(setting.getType(), new Float(fs
4386 / jms.getFeatureSettings().getSettingCount()));
4388 if (setting.getDisplay())
4390 fdi.setVisible(setting.getType());
4393 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4394 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4396 Group grp = jms.getFeatureSettings().getGroup(gs);
4397 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4399 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4400 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4401 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4402 FeatureRendererSettings frs = new FeatureRendererSettings(
4403 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4404 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4405 .transferSettings(frs);
4409 if (view.getHiddenColumnsCount() > 0)
4411 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4413 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4414 .getHiddenColumns(c).getEnd() // +1
4418 if (view.getCalcIdParam() != null)
4420 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4422 if (calcIdParam != null)
4424 if (recoverCalcIdParam(calcIdParam, af.viewport))
4429 warn("Couldn't recover parameters for "
4430 + calcIdParam.getCalcId());
4435 af.setMenusFromViewport(af.viewport);
4437 // TODO: we don't need to do this if the viewport is aready visible.
4439 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4440 * has a 'cdna/protein complement' view, in which case save it in order to
4441 * populate a SplitFrame once all views have been read in.
4443 String complementaryViewId = view.getComplementId();
4444 if (complementaryViewId == null)
4446 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4448 // recompute any autoannotation
4449 af.alignPanel.updateAnnotation(false, true);
4450 reorderAutoannotation(af, al, autoAlan);
4451 af.alignPanel.alignmentChanged();
4455 splitFrameCandidates.put(view, af);
4460 private ColourSchemeI constructAnnotationColour(
4461 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
4462 JalviewModelSequence jms, boolean checkGroupAnnColour)
4464 boolean propagateAnnColour = false;
4465 ColourSchemeI cs = null;
4466 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4467 if (checkGroupAnnColour && al.getGroups() != null
4468 && al.getGroups().size() > 0)
4470 // pre 2.8.1 behaviour
4471 // check to see if we should transfer annotation colours
4472 propagateAnnColour = true;
4473 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4475 if (sg.cs instanceof AnnotationColourGradient)
4477 propagateAnnColour = false;
4481 // int find annotation
4482 if (annAlignment.getAlignmentAnnotation() != null)
4484 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4486 if (annAlignment.getAlignmentAnnotation()[i].label
4487 .equals(viewAnnColour.getAnnotation()))
4489 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4491 annAlignment.getAlignmentAnnotation()[i]
4492 .setThreshold(new jalview.datamodel.GraphLine(
4493 viewAnnColour.getThreshold(), "Threshold",
4494 java.awt.Color.black)
4499 if (viewAnnColour.getColourScheme().equals("None"))
4501 cs = new AnnotationColourGradient(
4502 annAlignment.getAlignmentAnnotation()[i],
4503 new java.awt.Color(viewAnnColour.getMinColour()),
4504 new java.awt.Color(viewAnnColour.getMaxColour()),
4505 viewAnnColour.getAboveThreshold());
4507 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4509 cs = new AnnotationColourGradient(
4510 annAlignment.getAlignmentAnnotation()[i],
4511 getUserColourScheme(jms,
4512 viewAnnColour.getColourScheme()),
4513 viewAnnColour.getAboveThreshold());
4517 cs = new AnnotationColourGradient(
4518 annAlignment.getAlignmentAnnotation()[i],
4519 ColourSchemeProperty.getColour(al,
4520 viewAnnColour.getColourScheme()),
4521 viewAnnColour.getAboveThreshold());
4523 if (viewAnnColour.hasPerSequence())
4525 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4528 if (viewAnnColour.hasPredefinedColours())
4530 ((AnnotationColourGradient) cs)
4531 .setPredefinedColours(viewAnnColour
4532 .isPredefinedColours());
4534 if (propagateAnnColour && al.getGroups() != null)
4536 // Also use these settings for all the groups
4537 for (int g = 0; g < al.getGroups().size(); g++)
4539 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4547 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4548 * new AnnotationColourGradient(
4549 * annAlignment.getAlignmentAnnotation()[i], new
4550 * java.awt.Color(viewAnnColour. getMinColour()), new
4551 * java.awt.Color(viewAnnColour. getMaxColour()),
4552 * viewAnnColour.getAboveThreshold()); } else
4555 sg.cs = new AnnotationColourGradient(
4556 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4557 viewAnnColour.getAboveThreshold());
4558 if (cs instanceof AnnotationColourGradient)
4560 if (viewAnnColour.hasPerSequence())
4562 ((AnnotationColourGradient) cs)
4563 .setSeqAssociated(viewAnnColour.isPerSequence());
4565 if (viewAnnColour.hasPredefinedColours())
4567 ((AnnotationColourGradient) cs)
4568 .setPredefinedColours(viewAnnColour
4569 .isPredefinedColours());
4585 private void reorderAutoannotation(AlignFrame af, Alignment al,
4586 List<JvAnnotRow> autoAlan)
4588 // copy over visualization settings for autocalculated annotation in the
4590 if (al.getAlignmentAnnotation() != null)
4593 * Kludge for magic autoannotation names (see JAL-811)
4595 String[] magicNames = new String[] { "Consensus", "Quality",
4597 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4598 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4599 for (String nm : magicNames)
4601 visan.put(nm, nullAnnot);
4603 for (JvAnnotRow auan : autoAlan)
4605 visan.put(auan.template.label
4606 + (auan.template.getCalcId() == null ? "" : "\t"
4607 + auan.template.getCalcId()), auan);
4609 int hSize = al.getAlignmentAnnotation().length;
4610 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4611 // work through any autoCalculated annotation already on the view
4612 // removing it if it should be placed in a different location on the
4613 // annotation panel.
4614 List<String> remains = new ArrayList<String>(visan.keySet());
4615 for (int h = 0; h < hSize; h++)
4617 jalview.datamodel.AlignmentAnnotation jalan = al
4618 .getAlignmentAnnotation()[h];
4619 if (jalan.autoCalculated)
4622 JvAnnotRow valan = visan.get(k = jalan.label);
4623 if (jalan.getCalcId() != null)
4625 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4630 // delete the auto calculated row from the alignment
4631 al.deleteAnnotation(jalan, false);
4635 if (valan != nullAnnot)
4637 if (jalan != valan.template)
4639 // newly created autoannotation row instance
4640 // so keep a reference to the visible annotation row
4641 // and copy over all relevant attributes
4642 if (valan.template.graphHeight >= 0)
4645 jalan.graphHeight = valan.template.graphHeight;
4647 jalan.visible = valan.template.visible;
4649 reorder.add(new JvAnnotRow(valan.order, jalan));
4654 // Add any (possibly stale) autocalculated rows that were not appended to
4655 // the view during construction
4656 for (String other : remains)
4658 JvAnnotRow othera = visan.get(other);
4659 if (othera != nullAnnot && othera.template.getCalcId() != null
4660 && othera.template.getCalcId().length() > 0)
4662 reorder.add(othera);
4665 // now put the automatic annotation in its correct place
4666 int s = 0, srt[] = new int[reorder.size()];
4667 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4668 for (JvAnnotRow jvar : reorder)
4671 srt[s++] = jvar.order;
4674 jalview.util.QuickSort.sort(srt, rws);
4675 // and re-insert the annotation at its correct position
4676 for (JvAnnotRow jvar : rws)
4678 al.addAnnotation(jvar.template, jvar.order);
4680 af.alignPanel.adjustAnnotationHeight();
4684 Hashtable skipList = null;
4687 * TODO remove this method
4690 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4691 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4692 * throw new Error("Implementation Error. No skipList defined for this
4693 * Jalview2XML instance."); } return (AlignFrame)
4694 * skipList.get(view.getSequenceSetId()); }
4698 * Check if the Jalview view contained in object should be skipped or not.
4701 * @return true if view's sequenceSetId is a key in skipList
4703 private boolean skipViewport(JalviewModel object)
4705 if (skipList == null)
4710 if (skipList.containsKey(id = object.getJalviewModelSequence()
4711 .getViewport()[0].getSequenceSetId()))
4713 if (Cache.log != null && Cache.log.isDebugEnabled())
4715 Cache.log.debug("Skipping seuqence set id " + id);
4722 public void addToSkipList(AlignFrame af)
4724 if (skipList == null)
4726 skipList = new Hashtable();
4728 skipList.put(af.getViewport().getSequenceSetId(), af);
4731 public void clearSkipList()
4733 if (skipList != null)
4740 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4741 boolean ignoreUnrefed)
4743 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4744 Vector dseqs = null;
4747 // create a list of new dataset sequences
4748 dseqs = new Vector();
4750 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4752 Sequence vamsasSeq = vamsasSet.getSequence(i);
4753 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4755 // create a new dataset
4758 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4759 dseqs.copyInto(dsseqs);
4760 ds = new jalview.datamodel.Alignment(dsseqs);
4761 debug("Created new dataset " + vamsasSet.getDatasetId()
4762 + " for alignment " + System.identityHashCode(al));
4763 addDatasetRef(vamsasSet.getDatasetId(), ds);
4765 // set the dataset for the newly imported alignment.
4766 if (al.getDataset() == null && !ignoreUnrefed)
4775 * sequence definition to create/merge dataset sequence for
4779 * vector to add new dataset sequence to
4781 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4782 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4784 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4786 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4787 SequenceI dsq = null;
4788 if (sq != null && sq.getDatasetSequence() != null)
4790 dsq = sq.getDatasetSequence();
4792 if (sq == null && ignoreUnrefed)
4796 String sqid = vamsasSeq.getDsseqid();
4799 // need to create or add a new dataset sequence reference to this sequence
4802 dsq = seqRefIds.get(sqid);
4807 // make a new dataset sequence
4808 dsq = sq.createDatasetSequence();
4811 // make up a new dataset reference for this sequence
4812 sqid = seqHash(dsq);
4814 dsq.setVamsasId(uniqueSetSuffix + sqid);
4815 seqRefIds.put(sqid, dsq);
4820 dseqs.addElement(dsq);
4825 ds.addSequence(dsq);
4831 { // make this dataset sequence sq's dataset sequence
4832 sq.setDatasetSequence(dsq);
4833 // and update the current dataset alignment
4838 if (!dseqs.contains(dsq))
4845 if (ds.findIndex(dsq) < 0)
4847 ds.addSequence(dsq);
4854 // TODO: refactor this as a merge dataset sequence function
4855 // now check that sq (the dataset sequence) sequence really is the union of
4856 // all references to it
4857 // boolean pre = sq.getStart() < dsq.getStart();
4858 // boolean post = sq.getEnd() > dsq.getEnd();
4862 // StringBuffer sb = new StringBuffer();
4863 String newres = jalview.analysis.AlignSeq.extractGaps(
4864 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4865 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4866 && newres.length() > dsq.getLength())
4868 // Update with the longer sequence.
4872 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4873 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4874 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4875 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4877 dsq.setSequence(newres);
4879 // TODO: merges will never happen if we 'know' we have the real dataset
4880 // sequence - this should be detected when id==dssid
4882 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4883 // + (pre ? "prepended" : "") + " "
4884 // + (post ? "appended" : ""));
4890 * TODO use AlignmentI here and in related methods - needs
4891 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4893 Hashtable<String, Alignment> datasetIds = null;
4895 IdentityHashMap<Alignment, String> dataset2Ids = null;
4897 private Alignment getDatasetFor(String datasetId)
4899 if (datasetIds == null)
4901 datasetIds = new Hashtable<String, Alignment>();
4904 if (datasetIds.containsKey(datasetId))
4906 return datasetIds.get(datasetId);
4911 private void addDatasetRef(String datasetId, Alignment dataset)
4913 if (datasetIds == null)
4915 datasetIds = new Hashtable<String, Alignment>();
4917 datasetIds.put(datasetId, dataset);
4921 * make a new dataset ID for this jalview dataset alignment
4926 private String getDatasetIdRef(Alignment dataset)
4928 if (dataset.getDataset() != null)
4930 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4932 String datasetId = makeHashCode(dataset, null);
4933 if (datasetId == null)
4935 // make a new datasetId and record it
4936 if (dataset2Ids == null)
4938 dataset2Ids = new IdentityHashMap<Alignment, String>();
4942 datasetId = dataset2Ids.get(dataset);
4944 if (datasetId == null)
4946 datasetId = "ds" + dataset2Ids.size() + 1;
4947 dataset2Ids.put(dataset, datasetId);
4953 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4955 for (int d = 0; d < sequence.getDBRefCount(); d++)
4957 DBRef dr = sequence.getDBRef(d);
4958 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4959 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4960 .getVersion(), sequence.getDBRef(d).getAccessionId());
4961 if (dr.getMapping() != null)
4963 entry.setMap(addMapping(dr.getMapping()));
4965 datasetSequence.addDBRef(entry);
4969 private jalview.datamodel.Mapping addMapping(Mapping m)
4971 SequenceI dsto = null;
4972 // Mapping m = dr.getMapping();
4973 int fr[] = new int[m.getMapListFromCount() * 2];
4974 Enumeration f = m.enumerateMapListFrom();
4975 for (int _i = 0; f.hasMoreElements(); _i += 2)
4977 MapListFrom mf = (MapListFrom) f.nextElement();
4978 fr[_i] = mf.getStart();
4979 fr[_i + 1] = mf.getEnd();
4981 int fto[] = new int[m.getMapListToCount() * 2];
4982 f = m.enumerateMapListTo();
4983 for (int _i = 0; f.hasMoreElements(); _i += 2)
4985 MapListTo mf = (MapListTo) f.nextElement();
4986 fto[_i] = mf.getStart();
4987 fto[_i + 1] = mf.getEnd();
4989 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4990 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4991 if (m.getMappingChoice() != null)
4993 MappingChoice mc = m.getMappingChoice();
4994 if (mc.getDseqFor() != null)
4996 String dsfor = "" + mc.getDseqFor();
4997 if (seqRefIds.containsKey(dsfor))
5002 jmap.setTo(seqRefIds.get(dsfor));
5006 frefedSequence.add(new Object[] { dsfor, jmap });
5012 * local sequence definition
5014 Sequence ms = mc.getSequence();
5015 SequenceI djs = null;
5016 String sqid = ms.getDsseqid();
5017 if (sqid != null && sqid.length() > 0)
5020 * recover dataset sequence
5022 djs = seqRefIds.get(sqid);
5027 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5028 sqid = ((Object) ms).toString(); // make up a new hascode for
5029 // undefined dataset sequence hash
5030 // (unlikely to happen)
5036 * make a new dataset sequence and add it to refIds hash
5038 djs = new jalview.datamodel.Sequence(ms.getName(),
5040 djs.setStart(jmap.getMap().getToLowest());
5041 djs.setEnd(jmap.getMap().getToHighest());
5042 djs.setVamsasId(uniqueSetSuffix + sqid);
5044 seqRefIds.put(sqid, djs);
5047 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5056 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5057 boolean keepSeqRefs)
5060 JalviewModel jm = saveState(ap, null, null, null);
5065 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5069 uniqueSetSuffix = "";
5070 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5075 if (this.frefedSequence == null)
5077 frefedSequence = new Vector();
5080 viewportsAdded.clear();
5082 AlignFrame af = loadFromObject(jm, null, false, null);
5083 af.alignPanels.clear();
5084 af.closeMenuItem_actionPerformed(true);
5087 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5088 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5089 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5090 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5091 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5094 return af.alignPanel;
5098 * flag indicating if hashtables should be cleared on finalization TODO this
5099 * flag may not be necessary
5101 private final boolean _cleartables = true;
5103 private Hashtable jvids2vobj;
5108 * @see java.lang.Object#finalize()
5111 protected void finalize() throws Throwable
5113 // really make sure we have no buried refs left.
5118 this.seqRefIds = null;
5119 this.seqsToIds = null;
5123 private void warn(String msg)
5128 private void warn(String msg, Exception e)
5130 if (Cache.log != null)
5134 Cache.log.warn(msg, e);
5138 Cache.log.warn(msg);
5143 System.err.println("Warning: " + msg);
5146 e.printStackTrace();
5151 private void debug(String string)
5153 debug(string, null);
5156 private void debug(String msg, Exception e)
5158 if (Cache.log != null)
5162 Cache.log.debug(msg, e);
5166 Cache.log.debug(msg);
5171 System.err.println("Warning: " + msg);
5174 e.printStackTrace();
5180 * set the object to ID mapping tables used to write/recover objects and XML
5181 * ID strings for the jalview project. If external tables are provided then
5182 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5183 * object goes out of scope. - also populates the datasetIds hashtable with
5184 * alignment objects containing dataset sequences
5187 * Map from ID strings to jalview datamodel
5189 * Map from jalview datamodel to ID strings
5193 public void setObjectMappingTables(Hashtable vobj2jv,
5194 IdentityHashMap jv2vobj)
5196 this.jv2vobj = jv2vobj;
5197 this.vobj2jv = vobj2jv;
5198 Iterator ds = jv2vobj.keySet().iterator();
5200 while (ds.hasNext())
5202 Object jvobj = ds.next();
5203 id = jv2vobj.get(jvobj).toString();
5204 if (jvobj instanceof jalview.datamodel.Alignment)
5206 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5208 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5211 else if (jvobj instanceof jalview.datamodel.Sequence)
5213 // register sequence object so the XML parser can recover it.
5214 if (seqRefIds == null)
5216 seqRefIds = new HashMap<String, SequenceI>();
5218 if (seqsToIds == null)
5220 seqsToIds = new IdentityHashMap<SequenceI, String>();
5222 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5223 seqsToIds.put((SequenceI) jvobj, id);
5225 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5228 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5229 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5230 if (jvann.annotationId == null)
5232 jvann.annotationId = anid;
5234 if (!jvann.annotationId.equals(anid))
5236 // TODO verify that this is the correct behaviour
5237 this.warn("Overriding Annotation ID for " + anid
5238 + " from different id : " + jvann.annotationId);
5239 jvann.annotationId = anid;
5242 else if (jvobj instanceof String)
5244 if (jvids2vobj == null)
5246 jvids2vobj = new Hashtable();
5247 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5252 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5258 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5259 * objects created from the project archive. If string is null (default for
5260 * construction) then suffix will be set automatically.
5264 public void setUniqueSetSuffix(String string)
5266 uniqueSetSuffix = string;
5271 * uses skipList2 as the skipList for skipping views on sequence sets
5272 * associated with keys in the skipList
5276 public void setSkipList(Hashtable skipList2)
5278 skipList = skipList2;
5282 * Reads the jar entry of given name and returns its contents, or null if the
5283 * entry is not found.
5286 * @param jarEntryName
5289 protected String readJarEntry(jarInputStreamProvider jprovider,
5290 String jarEntryName)
5292 String result = null;
5293 BufferedReader in = null;
5298 * Reopen the jar input stream and traverse its entries to find a matching
5301 JarInputStream jin = jprovider.getJarInputStream();
5302 JarEntry entry = null;
5305 entry = jin.getNextJarEntry();
5306 } while (entry != null && !entry.getName().equals(jarEntryName));
5310 StringBuilder out = new StringBuilder(256);
5311 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5314 while ((data = in.readLine()) != null)
5318 result = out.toString();
5322 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5324 } catch (Exception ex)
5326 ex.printStackTrace();
5334 } catch (IOException e)
5345 * Returns an incrementing counter (0, 1, 2...)
5349 private synchronized int nextCounter()