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.ViewStyleI;
24 import jalview.api.structures.JalviewStructureDisplayI;
25 import jalview.bin.Cache;
26 import jalview.datamodel.AlignedCodonFrame;
27 import jalview.datamodel.Alignment;
28 import jalview.datamodel.AlignmentAnnotation;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.PDBEntry;
31 import jalview.datamodel.RnaViewerModel;
32 import jalview.datamodel.SequenceGroup;
33 import jalview.datamodel.SequenceI;
34 import jalview.datamodel.StructureViewerModel;
35 import jalview.datamodel.StructureViewerModel.StructureData;
36 import jalview.ext.varna.RnaModel;
37 import jalview.gui.StructureViewer.ViewerType;
38 import jalview.schemabinding.version2.AlcodMap;
39 import jalview.schemabinding.version2.AlcodonFrame;
40 import jalview.schemabinding.version2.Annotation;
41 import jalview.schemabinding.version2.AnnotationColours;
42 import jalview.schemabinding.version2.AnnotationElement;
43 import jalview.schemabinding.version2.CalcIdParam;
44 import jalview.schemabinding.version2.DBRef;
45 import jalview.schemabinding.version2.Features;
46 import jalview.schemabinding.version2.Group;
47 import jalview.schemabinding.version2.HiddenColumns;
48 import jalview.schemabinding.version2.JGroup;
49 import jalview.schemabinding.version2.JSeq;
50 import jalview.schemabinding.version2.JalviewModel;
51 import jalview.schemabinding.version2.JalviewModelSequence;
52 import jalview.schemabinding.version2.MapListFrom;
53 import jalview.schemabinding.version2.MapListTo;
54 import jalview.schemabinding.version2.Mapping;
55 import jalview.schemabinding.version2.MappingChoice;
56 import jalview.schemabinding.version2.OtherData;
57 import jalview.schemabinding.version2.PdbentryItem;
58 import jalview.schemabinding.version2.Pdbids;
59 import jalview.schemabinding.version2.Property;
60 import jalview.schemabinding.version2.RnaViewer;
61 import jalview.schemabinding.version2.SecondaryStructure;
62 import jalview.schemabinding.version2.Sequence;
63 import jalview.schemabinding.version2.SequenceSet;
64 import jalview.schemabinding.version2.SequenceSetProperties;
65 import jalview.schemabinding.version2.Setting;
66 import jalview.schemabinding.version2.StructureState;
67 import jalview.schemabinding.version2.ThresholdLine;
68 import jalview.schemabinding.version2.Tree;
69 import jalview.schemabinding.version2.UserColours;
70 import jalview.schemabinding.version2.Viewport;
71 import jalview.schemes.AnnotationColourGradient;
72 import jalview.schemes.ColourSchemeI;
73 import jalview.schemes.ColourSchemeProperty;
74 import jalview.schemes.GraduatedColor;
75 import jalview.schemes.ResidueColourScheme;
76 import jalview.schemes.ResidueProperties;
77 import jalview.schemes.UserColourScheme;
78 import jalview.structure.StructureSelectionManager;
79 import jalview.structures.models.AAStructureBindingModel;
80 import jalview.util.MessageManager;
81 import jalview.util.Platform;
82 import jalview.util.jarInputStreamProvider;
83 import jalview.viewmodel.AlignmentViewport;
84 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
85 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
86 import jalview.ws.jws2.Jws2Discoverer;
87 import jalview.ws.jws2.dm.AAConSettings;
88 import jalview.ws.jws2.jabaws2.Jws2Instance;
89 import jalview.ws.params.ArgumentI;
90 import jalview.ws.params.AutoCalcSetting;
91 import jalview.ws.params.WsParamSetI;
93 import java.awt.Rectangle;
94 import java.io.BufferedReader;
95 import java.io.DataInputStream;
96 import java.io.DataOutputStream;
98 import java.io.FileInputStream;
99 import java.io.FileOutputStream;
100 import java.io.IOException;
101 import java.io.InputStreamReader;
102 import java.io.OutputStreamWriter;
103 import java.io.PrintWriter;
104 import java.lang.reflect.InvocationTargetException;
105 import java.net.MalformedURLException;
107 import java.util.ArrayList;
108 import java.util.Enumeration;
109 import java.util.HashMap;
110 import java.util.HashSet;
111 import java.util.Hashtable;
112 import java.util.IdentityHashMap;
113 import java.util.Iterator;
114 import java.util.LinkedHashMap;
115 import java.util.List;
116 import java.util.Map;
117 import java.util.Map.Entry;
118 import java.util.Set;
119 import java.util.StringTokenizer;
120 import java.util.Vector;
121 import java.util.jar.JarEntry;
122 import java.util.jar.JarInputStream;
123 import java.util.jar.JarOutputStream;
125 import javax.swing.JInternalFrame;
126 import javax.swing.JOptionPane;
127 import javax.swing.SwingUtilities;
129 import org.exolab.castor.xml.Marshaller;
130 import org.exolab.castor.xml.Unmarshaller;
133 * Write out the current jalview desktop state as a Jalview XML stream.
135 * Note: the vamsas objects referred to here are primitive versions of the
136 * VAMSAS project schema elements - they are not the same and most likely never
140 * @version $Revision: 1.134 $
142 public class Jalview2XML
144 private static final String VIEWER_PREFIX = "viewer_";
146 private static final String RNA_PREFIX = "rna_";
148 private static final String UTF_8 = "UTF-8";
150 // use this with nextCounter() to make unique names for entities
151 private int counter = 0;
154 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
155 * of sequence objects are created.
157 IdentityHashMap<SequenceI, String> seqsToIds = null;
160 * jalview XML Sequence ID to jalview sequence object reference (both dataset
161 * and alignment sequences. Populated as XML reps of sequence objects are
164 Map<String, SequenceI> seqRefIds = null;
166 Vector frefedSequence = null;
168 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
171 * Map of reconstructed AlignFrame objects that appear to have come from
172 * SplitFrame objects (have a dna/protein complement view).
174 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
177 * Map from displayed rna structure models to their saved session state jar
180 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
183 * create/return unique hash string for sq
186 * @return new or existing unique string for sq
188 String seqHash(SequenceI sq)
190 if (seqsToIds == null)
194 if (seqsToIds.containsKey(sq))
196 return seqsToIds.get(sq);
200 // create sequential key
201 String key = "sq" + (seqsToIds.size() + 1);
202 key = makeHashCode(sq, key); // check we don't have an external reference
204 seqsToIds.put(sq, key);
213 if (seqRefIds != null)
217 if (seqsToIds != null)
227 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
228 // seqRefIds = new Hashtable();
229 // seqsToIds = new IdentityHashMap();
235 if (seqsToIds == null)
237 seqsToIds = new IdentityHashMap<SequenceI, String>();
239 if (seqRefIds == null)
241 seqRefIds = new HashMap<String, SequenceI>();
249 public Jalview2XML(boolean raiseGUI)
251 this.raiseGUI = raiseGUI;
254 public void resolveFrefedSequences()
256 if (frefedSequence.size() > 0)
258 int r = 0, rSize = frefedSequence.size();
261 Object[] ref = (Object[]) frefedSequence.elementAt(r);
264 String sref = (String) ref[0];
265 if (seqRefIds.containsKey(sref))
267 if (ref[1] instanceof jalview.datamodel.Mapping)
269 SequenceI seq = seqRefIds.get(sref);
270 while (seq.getDatasetSequence() != null)
272 seq = seq.getDatasetSequence();
274 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
278 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
280 SequenceI seq = seqRefIds.get(sref);
281 while (seq.getDatasetSequence() != null)
283 seq = seq.getDatasetSequence();
286 && ref[2] instanceof jalview.datamodel.Mapping)
288 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
289 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
290 seq, mp.getTo(), mp.getMap());
295 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
296 + ref[2].getClass() + " type objects.");
302 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
303 + ref[1].getClass() + " type objects.");
306 frefedSequence.remove(r);
312 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
314 + " with objecttype "
315 + ref[1].getClass());
322 frefedSequence.remove(r);
330 * This maintains a map of viewports, the key being the seqSetId. Important to
331 * set historyItem and redoList for multiple views
333 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
335 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
337 String uniqueSetSuffix = "";
340 * List of pdbfiles added to Jar
342 List<String> pdbfiles = null;
344 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
345 public void saveState(File statefile)
347 FileOutputStream fos = null;
350 fos = new FileOutputStream(statefile);
351 JarOutputStream jout = new JarOutputStream(fos);
354 } catch (Exception e)
356 // TODO: inform user of the problem - they need to know if their data was
358 if (errorMessage == null)
360 errorMessage = "Couldn't write Jalview Archive to output file '"
361 + statefile + "' - See console error log for details";
365 errorMessage += "(output file was '" + statefile + "')";
375 } catch (IOException e)
385 * Writes a jalview project archive to the given Jar output stream.
389 public void saveState(JarOutputStream jout)
391 AlignFrame[] frames = Desktop.getAlignFrames();
398 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
401 * ensure cached data is clear before starting
403 // todo tidy up seqRefIds, seqsToIds initialisation / reset
405 splitFrameCandidates.clear();
410 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
411 // //////////////////////////////////////////////////
413 List<String> shortNames = new ArrayList<String>();
414 List<String> viewIds = new ArrayList<String>();
417 for (int i = frames.length - 1; i > -1; i--)
419 AlignFrame af = frames[i];
423 .containsKey(af.getViewport().getSequenceSetId()))
428 String shortName = makeFilename(af, shortNames);
430 int ap, apSize = af.alignPanels.size();
432 for (ap = 0; ap < apSize; ap++)
434 AlignmentPanel apanel = af.alignPanels.get(ap);
435 String fileName = apSize == 1 ? shortName : ap + shortName;
436 if (!fileName.endsWith(".xml"))
438 fileName = fileName + ".xml";
441 saveState(apanel, fileName, jout, viewIds);
443 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
445 if (!dsses.containsKey(dssid))
447 dsses.put(dssid, af);
452 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
458 } catch (Exception foo)
463 } catch (Exception ex)
465 // TODO: inform user of the problem - they need to know if their data was
467 if (errorMessage == null)
469 errorMessage = "Couldn't write Jalview Archive - see error output for details";
471 ex.printStackTrace();
476 * Generates a distinct file name, based on the title of the AlignFrame, by
477 * appending _n for increasing n until an unused name is generated. The new
478 * name (without its extension) is added to the list.
482 * @return the generated name, with .xml extension
484 protected String makeFilename(AlignFrame af, List<String> namesUsed)
486 String shortName = af.getTitle();
488 if (shortName.indexOf(File.separatorChar) > -1)
490 shortName = shortName.substring(shortName
491 .lastIndexOf(File.separatorChar) + 1);
496 while (namesUsed.contains(shortName))
498 if (shortName.endsWith("_" + (count - 1)))
500 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
503 shortName = shortName.concat("_" + count);
507 namesUsed.add(shortName);
509 if (!shortName.endsWith(".xml"))
511 shortName = shortName + ".xml";
516 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
517 public boolean saveAlignment(AlignFrame af, String jarFile,
523 int apSize = af.alignPanels.size();
524 FileOutputStream fos = new FileOutputStream(jarFile);
525 JarOutputStream jout = new JarOutputStream(fos);
526 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
527 List<String> viewIds = new ArrayList<String>();
529 for (AlignmentPanel apanel : af.alignPanels)
531 String jfileName = apSize == 1 ? fileName : fileName + ap;
533 if (!jfileName.endsWith(".xml"))
535 jfileName = jfileName + ".xml";
537 saveState(apanel, jfileName, jout, viewIds);
538 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
540 if (!dsses.containsKey(dssid))
542 dsses.put(dssid, af);
545 writeDatasetFor(dsses, fileName, jout);
549 } catch (Exception foo)
555 } catch (Exception ex)
557 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
558 ex.printStackTrace();
563 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
564 String fileName, JarOutputStream jout)
567 for (String dssids : dsses.keySet())
569 AlignFrame _af = dsses.get(dssids);
570 String jfileName = fileName + " Dataset for " + _af.getTitle();
571 if (!jfileName.endsWith(".xml"))
573 jfileName = jfileName + ".xml";
575 saveState(_af.alignPanel, jfileName, true, jout, null);
580 * create a JalviewModel from an alignment view and marshall it to a
584 * panel to create jalview model for
586 * name of alignment panel written to output stream
593 public JalviewModel saveState(AlignmentPanel ap, String fileName,
594 JarOutputStream jout, List<String> viewIds)
596 return saveState(ap, fileName, false, jout, viewIds);
600 * create a JalviewModel from an alignment view and marshall it to a
604 * panel to create jalview model for
606 * name of alignment panel written to output stream
608 * when true, only write the dataset for the alignment, not the data
609 * associated with the view.
615 public JalviewModel saveState(AlignmentPanel ap, String fileName,
616 boolean storeDS, JarOutputStream jout, List<String> viewIds)
620 viewIds = new ArrayList<String>();
625 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
627 AlignViewport av = ap.av;
629 JalviewModel object = new JalviewModel();
630 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
632 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
633 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
634 "Development Build"));
636 jalview.datamodel.AlignmentI jal = av.getAlignment();
638 if (av.hasHiddenRows())
640 jal = jal.getHiddenSequences().getFullAlignment();
643 SequenceSet vamsasSet = new SequenceSet();
645 JalviewModelSequence jms = new JalviewModelSequence();
647 vamsasSet.setGapChar(jal.getGapCharacter() + "");
649 if (jal.getDataset() != null)
651 // dataset id is the dataset's hashcode
652 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
655 // switch jal and the dataset
656 jal = jal.getDataset();
659 if (jal.getProperties() != null)
661 Enumeration en = jal.getProperties().keys();
662 while (en.hasMoreElements())
664 String key = en.nextElement().toString();
665 SequenceSetProperties ssp = new SequenceSetProperties();
667 ssp.setValue(jal.getProperties().get(key).toString());
668 vamsasSet.addSequenceSetProperties(ssp);
673 Set<String> calcIdSet = new HashSet<String>();
676 for (int i = 0; i < jal.getHeight(); i++)
678 final SequenceI jds = jal.getSequenceAt(i);
679 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
680 : jds.getDatasetSequence();
681 String id = seqHash(jds);
683 if (seqRefIds.get(id) != null)
685 // This happens for two reasons: 1. multiple views are being serialised.
686 // 2. the hashCode has collided with another sequence's code. This DOES
687 // HAPPEN! (PF00072.15.stk does this)
688 // JBPNote: Uncomment to debug writing out of files that do not read
689 // back in due to ArrayOutOfBoundExceptions.
690 // System.err.println("vamsasSeq backref: "+id+"");
691 // System.err.println(jds.getName()+"
692 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
693 // System.err.println("Hashcode: "+seqHash(jds));
694 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
695 // System.err.println(rsq.getName()+"
696 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
697 // System.err.println("Hashcode: "+seqHash(rsq));
701 vamsasSeq = createVamsasSequence(id, jds);
702 vamsasSet.addSequence(vamsasSeq);
703 seqRefIds.put(id, jds);
707 jseq.setStart(jds.getStart());
708 jseq.setEnd(jds.getEnd());
709 jseq.setColour(av.getSequenceColour(jds).getRGB());
711 jseq.setId(id); // jseq id should be a string not a number
714 // Store any sequences this sequence represents
715 if (av.hasHiddenRows())
717 jseq.setHidden(av.getAlignment().getHiddenSequences()
720 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
722 jalview.datamodel.SequenceI[] reps = av
723 .getRepresentedSequences(jal.getSequenceAt(i))
724 .getSequencesInOrder(jal);
726 for (int h = 0; h < reps.length; h++)
728 if (reps[h] != jal.getSequenceAt(i))
730 jseq.addHiddenSequences(jal.findIndex(reps[h]));
737 if (jds.getSequenceFeatures() != null)
739 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
741 while (index < sf.length)
743 Features features = new Features();
745 features.setBegin(sf[index].getBegin());
746 features.setEnd(sf[index].getEnd());
747 features.setDescription(sf[index].getDescription());
748 features.setType(sf[index].getType());
749 features.setFeatureGroup(sf[index].getFeatureGroup());
750 features.setScore(sf[index].getScore());
751 if (sf[index].links != null)
753 for (int l = 0; l < sf[index].links.size(); l++)
755 OtherData keyValue = new OtherData();
756 keyValue.setKey("LINK_" + l);
757 keyValue.setValue(sf[index].links.elementAt(l).toString());
758 features.addOtherData(keyValue);
761 if (sf[index].otherDetails != null)
764 Enumeration keys = sf[index].otherDetails.keys();
765 while (keys.hasMoreElements())
767 key = keys.nextElement().toString();
768 OtherData keyValue = new OtherData();
769 keyValue.setKey(key);
770 keyValue.setValue(sf[index].otherDetails.get(key).toString());
771 features.addOtherData(keyValue);
775 jseq.addFeatures(features);
780 if (jdatasq.getAllPDBEntries() != null)
782 Enumeration en = jdatasq.getAllPDBEntries().elements();
783 while (en.hasMoreElements())
785 Pdbids pdb = new Pdbids();
786 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
789 String pdbId = entry.getId();
791 pdb.setType(entry.getType());
794 * Store any structure views associated with this sequence. This
795 * section copes with duplicate entries in the project, so a dataset
796 * only view *should* be coped with sensibly.
798 // This must have been loaded, is it still visible?
799 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
800 String matchedFile = null;
801 for (int f = frames.length - 1; f > -1; f--)
803 if (frames[f] instanceof StructureViewerBase)
805 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
806 matchedFile = saveStructureState(ap, jds, pdb, entry,
807 viewIds, matchedFile, viewFrame);
809 * Only store each structure viewer's state once in the project
810 * jar. First time through only (storeDS==false)
812 String viewId = viewFrame.getViewId();
813 if (!storeDS && !viewIds.contains(viewId))
818 String viewerState = viewFrame.getStateInfo();
819 writeJarEntry(jout, getViewerJarEntryName(viewId),
820 viewerState.getBytes());
821 } catch (IOException e)
823 System.err.println("Error saving viewer state: "
830 if (matchedFile != null || entry.getFile() != null)
832 if (entry.getFile() != null)
835 matchedFile = entry.getFile();
837 pdb.setFile(matchedFile); // entry.getFile());
838 if (pdbfiles == null)
840 pdbfiles = new ArrayList<String>();
843 if (!pdbfiles.contains(pdbId))
846 copyFileToJar(jout, matchedFile, pdbId);
850 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
852 PdbentryItem item = new PdbentryItem();
853 Hashtable properties = entry.getProperty();
854 Enumeration en2 = properties.keys();
855 while (en2.hasMoreElements())
857 Property prop = new Property();
858 String key = en2.nextElement().toString();
860 prop.setValue(properties.get(key).toString());
861 item.addProperty(prop);
863 pdb.addPdbentryItem(item);
870 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
875 if (!storeDS && av.hasHiddenRows())
877 jal = av.getAlignment();
880 if (jal.getCodonFrames() != null)
882 Set<AlignedCodonFrame> jac = jal.getCodonFrames();
883 for (AlignedCodonFrame acf : jac)
885 AlcodonFrame alc = new AlcodonFrame();
886 vamsasSet.addAlcodonFrame(alc);
887 if (acf.getProtMappings() != null
888 && acf.getProtMappings().length > 0)
890 SequenceI[] dnas = acf.getdnaSeqs();
891 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
892 for (int m = 0; m < pmaps.length; m++)
894 AlcodMap alcmap = new AlcodMap();
895 alcmap.setDnasq(seqHash(dnas[m]));
896 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
898 alc.addAlcodMap(alcmap);
903 // AlcodonFrame alc = new AlcodonFrame();
904 // vamsasSet.addAlcodonFrame(alc);
905 // for (int p = 0; p < acf.aaWidth; p++)
907 // Alcodon cmap = new Alcodon();
908 // if (acf.codons[p] != null)
910 // // Null codons indicate a gapped column in the translated peptide
912 // cmap.setPos1(acf.codons[p][0]);
913 // cmap.setPos2(acf.codons[p][1]);
914 // cmap.setPos3(acf.codons[p][2]);
916 // alc.addAlcodon(cmap);
918 // if (acf.getProtMappings() != null
919 // && acf.getProtMappings().length > 0)
921 // SequenceI[] dnas = acf.getdnaSeqs();
922 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
923 // for (int m = 0; m < pmaps.length; m++)
925 // AlcodMap alcmap = new AlcodMap();
926 // alcmap.setDnasq(seqHash(dnas[m]));
927 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
929 // alc.addAlcodMap(alcmap);
936 // /////////////////////////////////
937 if (!storeDS && av.currentTree != null)
939 // FIND ANY ASSOCIATED TREES
940 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
941 if (Desktop.desktop != null)
943 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
945 for (int t = 0; t < frames.length; t++)
947 if (frames[t] instanceof TreePanel)
949 TreePanel tp = (TreePanel) frames[t];
951 if (tp.treeCanvas.av.getAlignment() == jal)
953 Tree tree = new Tree();
954 tree.setTitle(tp.getTitle());
955 tree.setCurrentTree((av.currentTree == tp.getTree()));
956 tree.setNewick(tp.getTree().toString());
957 tree.setThreshold(tp.treeCanvas.threshold);
959 tree.setFitToWindow(tp.fitToWindow.getState());
960 tree.setFontName(tp.getTreeFont().getName());
961 tree.setFontSize(tp.getTreeFont().getSize());
962 tree.setFontStyle(tp.getTreeFont().getStyle());
963 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
965 tree.setShowBootstrap(tp.bootstrapMenu.getState());
966 tree.setShowDistances(tp.distanceMenu.getState());
968 tree.setHeight(tp.getHeight());
969 tree.setWidth(tp.getWidth());
970 tree.setXpos(tp.getX());
971 tree.setYpos(tp.getY());
972 tree.setId(makeHashCode(tp, null));
982 * store forward refs from an annotationRow to any groups
984 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
987 for (SequenceI sq : jal.getSequences())
989 // Store annotation on dataset sequences only
990 AlignmentAnnotation[] aa = sq.getAnnotation();
991 if (aa != null && aa.length > 0)
993 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1000 if (jal.getAlignmentAnnotation() != null)
1002 // Store the annotation shown on the alignment.
1003 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1004 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1009 if (jal.getGroups() != null)
1011 JGroup[] groups = new JGroup[jal.getGroups().size()];
1013 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1015 JGroup jGroup = new JGroup();
1016 groups[++i] = jGroup;
1018 jGroup.setStart(sg.getStartRes());
1019 jGroup.setEnd(sg.getEndRes());
1020 jGroup.setName(sg.getName());
1021 if (groupRefs.containsKey(sg))
1023 // group has references so set its ID field
1024 jGroup.setId(groupRefs.get(sg));
1028 if (sg.cs.conservationApplied())
1030 jGroup.setConsThreshold(sg.cs.getConservationInc());
1032 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1034 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1038 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1041 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1043 jGroup.setColour("AnnotationColourGradient");
1044 jGroup.setAnnotationColours(constructAnnotationColours(
1045 (jalview.schemes.AnnotationColourGradient) sg.cs,
1048 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1050 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1054 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1057 jGroup.setPidThreshold(sg.cs.getThreshold());
1060 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1061 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1062 jGroup.setDisplayText(sg.getDisplayText());
1063 jGroup.setColourText(sg.getColourText());
1064 jGroup.setTextCol1(sg.textColour.getRGB());
1065 jGroup.setTextCol2(sg.textColour2.getRGB());
1066 jGroup.setTextColThreshold(sg.thresholdTextColour);
1067 jGroup.setShowUnconserved(sg.getShowNonconserved());
1068 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1069 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1070 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1071 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1072 for (SequenceI seq : sg.getSequences())
1074 jGroup.addSeq(seqHash(seq));
1078 jms.setJGroup(groups);
1082 // /////////SAVE VIEWPORT
1083 Viewport view = new Viewport();
1084 view.setTitle(ap.alignFrame.getTitle());
1085 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1086 av.getSequenceSetId()));
1087 view.setId(av.getViewId());
1088 if (av.getCodingComplement() != null)
1090 view.setComplementId(av.getCodingComplement().getViewId());
1092 view.setViewName(av.viewName);
1093 view.setGatheredViews(av.isGatherViewsHere());
1095 Rectangle position = ap.av.getExplodedGeometry();
1096 if (position == null)
1098 position = ap.alignFrame.getBounds();
1100 view.setXpos(position.x);
1101 view.setYpos(position.y);
1102 view.setWidth(position.width);
1103 view.setHeight(position.height);
1105 view.setStartRes(av.startRes);
1106 view.setStartSeq(av.startSeq);
1108 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1110 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1113 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1115 AnnotationColours ac = constructAnnotationColours(
1116 (jalview.schemes.AnnotationColourGradient) av
1117 .getGlobalColourScheme(),
1120 view.setAnnotationColours(ac);
1121 view.setBgColour("AnnotationColourGradient");
1125 view.setBgColour(ColourSchemeProperty.getColourName(av
1126 .getGlobalColourScheme()));
1129 ColourSchemeI cs = av.getGlobalColourScheme();
1133 if (cs.conservationApplied())
1135 view.setConsThreshold(cs.getConservationInc());
1136 if (cs instanceof jalview.schemes.UserColourScheme)
1138 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1142 if (cs instanceof ResidueColourScheme)
1144 view.setPidThreshold(cs.getThreshold());
1148 view.setConservationSelected(av.getConservationSelected());
1149 view.setPidSelected(av.getAbovePIDThreshold());
1150 view.setFontName(av.font.getName());
1151 view.setFontSize(av.font.getSize());
1152 view.setFontStyle(av.font.getStyle());
1153 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1154 view.setRenderGaps(av.isRenderGaps());
1155 view.setShowAnnotation(av.isShowAnnotation());
1156 view.setShowBoxes(av.getShowBoxes());
1157 view.setShowColourText(av.getColourText());
1158 view.setShowFullId(av.getShowJVSuffix());
1159 view.setRightAlignIds(av.isRightAlignIds());
1160 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1161 view.setShowText(av.getShowText());
1162 view.setShowUnconserved(av.getShowUnconserved());
1163 view.setWrapAlignment(av.getWrapAlignment());
1164 view.setTextCol1(av.getTextColour().getRGB());
1165 view.setTextCol2(av.getTextColour2().getRGB());
1166 view.setTextColThreshold(av.getThresholdTextColour());
1167 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1168 view.setShowSequenceLogo(av.isShowSequenceLogo());
1169 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1170 view.setShowGroupConsensus(av.isShowGroupConsensus());
1171 view.setShowGroupConservation(av.isShowGroupConservation());
1172 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1173 view.setShowDbRefTooltip(av.isShowDBRefs());
1174 view.setFollowHighlight(av.isFollowHighlight());
1175 view.setFollowSelection(av.followSelection);
1176 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1177 if (av.getFeaturesDisplayed() != null)
1179 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1181 String[] renderOrder = ap.getSeqPanel().seqCanvas
1182 .getFeatureRenderer().getRenderOrder()
1183 .toArray(new String[0]);
1185 Vector settingsAdded = new Vector();
1186 Object gstyle = null;
1187 GraduatedColor gcol = null;
1188 if (renderOrder != null)
1190 for (int ro = 0; ro < renderOrder.length; ro++)
1192 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1193 .getFeatureStyle(renderOrder[ro]);
1194 Setting setting = new Setting();
1195 setting.setType(renderOrder[ro]);
1196 if (gstyle instanceof GraduatedColor)
1198 gcol = (GraduatedColor) gstyle;
1199 setting.setColour(gcol.getMaxColor().getRGB());
1200 setting.setMincolour(gcol.getMinColor().getRGB());
1201 setting.setMin(gcol.getMin());
1202 setting.setMax(gcol.getMax());
1203 setting.setColourByLabel(gcol.isColourByLabel());
1204 setting.setAutoScale(gcol.isAutoScale());
1205 setting.setThreshold(gcol.getThresh());
1206 setting.setThreshstate(gcol.getThreshType());
1210 setting.setColour(ap.getSeqPanel().seqCanvas
1211 .getFeatureRenderer().getColour(renderOrder[ro])
1215 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1217 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1218 .getOrder(renderOrder[ro]);
1221 setting.setOrder(rorder);
1223 fs.addSetting(setting);
1224 settingsAdded.addElement(renderOrder[ro]);
1228 // Make sure we save none displayed feature settings
1229 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1230 .getFeatureColours().keySet().iterator();
1231 while (en.hasNext())
1233 String key = en.next().toString();
1234 if (settingsAdded.contains(key))
1239 Setting setting = new Setting();
1240 setting.setType(key);
1241 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1242 .getColour(key).getRGB());
1244 setting.setDisplay(false);
1245 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1249 setting.setOrder(rorder);
1251 fs.addSetting(setting);
1252 settingsAdded.addElement(key);
1254 // is groups actually supposed to be a map here ?
1255 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1256 .getFeatureGroups().iterator();
1257 Vector groupsAdded = new Vector();
1258 while (en.hasNext())
1260 String grp = en.next().toString();
1261 if (groupsAdded.contains(grp))
1265 Group g = new Group();
1267 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1268 .getFeatureRenderer().checkGroupVisibility(grp, false))
1271 groupsAdded.addElement(grp);
1273 jms.setFeatureSettings(fs);
1277 if (av.hasHiddenColumns())
1279 if (av.getColumnSelection() == null
1280 || av.getColumnSelection().getHiddenColumns() == null)
1282 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1286 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1289 int[] region = av.getColumnSelection().getHiddenColumns()
1291 HiddenColumns hc = new HiddenColumns();
1292 hc.setStart(region[0]);
1293 hc.setEnd(region[1]);
1294 view.addHiddenColumns(hc);
1298 if (calcIdSet.size() > 0)
1300 for (String calcId : calcIdSet)
1302 if (calcId.trim().length() > 0)
1304 CalcIdParam cidp = createCalcIdParam(calcId, av);
1305 // Some calcIds have no parameters.
1308 view.addCalcIdParam(cidp);
1314 jms.addViewport(view);
1316 object.setJalviewModelSequence(jms);
1317 object.getVamsasModel().addSequenceSet(vamsasSet);
1319 if (jout != null && fileName != null)
1321 // We may not want to write the object to disk,
1322 // eg we can copy the alignViewport to a new view object
1323 // using save and then load
1326 System.out.println("Writing jar entry " + fileName);
1327 JarEntry entry = new JarEntry(fileName);
1328 jout.putNextEntry(entry);
1329 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1331 Marshaller marshaller = new Marshaller(pout);
1332 marshaller.marshal(object);
1335 } catch (Exception ex)
1337 // TODO: raise error in GUI if marshalling failed.
1338 ex.printStackTrace();
1345 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1346 * for each viewer, with
1348 * <li>viewer geometry (position, size, split pane divider location)</li>
1349 * <li>index of the selected structure in the viewer (currently shows gapped
1351 * <li>the id of the annotation holding RNA secondary structure</li>
1352 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1354 * Varna viewer state is also written out (in native Varna XML) to separate
1355 * project jar entries. A separate entry is written for each RNA structure
1356 * displayed, with the naming convention
1358 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1366 * @param storeDataset
1368 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1369 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1370 boolean storeDataset)
1372 if (Desktop.desktop == null)
1376 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1377 for (int f = frames.length - 1; f > -1; f--)
1379 if (frames[f] instanceof AppVarna)
1381 AppVarna varna = (AppVarna) frames[f];
1383 * link the sequence to every viewer that is showing it and is linked to
1384 * its alignment panel
1386 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1388 String viewId = varna.getViewId();
1389 RnaViewer rna = new RnaViewer();
1390 rna.setViewId(viewId);
1391 rna.setTitle(varna.getTitle());
1392 rna.setXpos(varna.getX());
1393 rna.setYpos(varna.getY());
1394 rna.setWidth(varna.getWidth());
1395 rna.setHeight(varna.getHeight());
1396 rna.setDividerLocation(varna.getDividerLocation());
1397 rna.setSelectedRna(varna.getSelectedIndex());
1398 jseq.addRnaViewer(rna);
1401 * Store each Varna panel's state once in the project per sequence.
1402 * First time through only (storeDataset==false)
1404 // boolean storeSessions = false;
1405 // String sequenceViewId = viewId + seqsToIds.get(jds);
1406 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1408 // viewIds.add(sequenceViewId);
1409 // storeSessions = true;
1411 for (RnaModel model : varna.getModels())
1413 if (model.seq == jds)
1416 * VARNA saves each view (sequence or alignment secondary
1417 * structure, gapped or trimmed) as a separate XML file
1419 String jarEntryName = rnaSessions.get(model);
1420 if (jarEntryName == null)
1423 String varnaStateFile = varna.getStateInfo(model.rna);
1424 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1425 copyFileToJar(jout, varnaStateFile, jarEntryName);
1426 rnaSessions.put(model, jarEntryName);
1428 SecondaryStructure ss = new SecondaryStructure();
1429 String annotationId = varna.getAnnotation(jds).annotationId;
1430 ss.setAnnotationId(annotationId);
1431 ss.setViewerState(jarEntryName);
1432 ss.setGapped(model.gapped);
1433 ss.setTitle(model.title);
1434 rna.addSecondaryStructure(ss);
1443 * Copy the contents of a file to a new entry added to the output jar
1447 * @param jarEntryName
1449 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1450 String jarEntryName)
1452 DataInputStream dis = null;
1455 File file = new File(infilePath);
1456 if (file.exists() && jout != null)
1458 dis = new DataInputStream(new FileInputStream(file));
1459 byte[] data = new byte[(int) file.length()];
1460 dis.readFully(data);
1461 writeJarEntry(jout, jarEntryName, data);
1463 } catch (Exception ex)
1465 ex.printStackTrace();
1473 } catch (IOException e)
1482 * Write the data to a new entry of given name in the output jar file
1485 * @param jarEntryName
1487 * @throws IOException
1489 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1490 byte[] data) throws IOException
1494 System.out.println("Writing jar entry " + jarEntryName);
1495 jout.putNextEntry(new JarEntry(jarEntryName));
1496 DataOutputStream dout = new DataOutputStream(jout);
1497 dout.write(data, 0, data.length);
1504 * Save the state of a structure viewer
1509 * the archive XML element under which to save the state
1512 * @param matchedFile
1516 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1517 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1518 String matchedFile, StructureViewerBase viewFrame)
1520 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1523 * Look for any bindings for this viewer to the PDB file of interest
1524 * (including part matches excluding chain id)
1526 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1528 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1529 final String pdbId = pdbentry.getId();
1530 if (!pdbId.equals(entry.getId())
1531 && !(entry.getId().length() > 4 && entry.getId()
1532 .toLowerCase().startsWith(pdbId.toLowerCase())))
1535 * not interested in a binding to a different PDB entry here
1539 if (matchedFile == null)
1541 matchedFile = pdbentry.getFile();
1543 else if (!matchedFile.equals(pdbentry.getFile()))
1546 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1547 + pdbentry.getFile());
1551 // can get at it if the ID
1552 // match is ambiguous (e.g.
1555 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1557 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1558 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1560 StructureState state = new StructureState();
1561 state.setVisible(true);
1562 state.setXpos(viewFrame.getX());
1563 state.setYpos(viewFrame.getY());
1564 state.setWidth(viewFrame.getWidth());
1565 state.setHeight(viewFrame.getHeight());
1566 final String viewId = viewFrame.getViewId();
1567 state.setViewId(viewId);
1568 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1569 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1570 state.setColourByJmol(viewFrame.isColouredByViewer());
1571 state.setType(viewFrame.getViewerType().toString());
1572 pdb.addStructureState(state);
1579 private AnnotationColours constructAnnotationColours(
1580 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1581 JalviewModelSequence jms)
1583 AnnotationColours ac = new AnnotationColours();
1584 ac.setAboveThreshold(acg.getAboveThreshold());
1585 ac.setThreshold(acg.getAnnotationThreshold());
1586 ac.setAnnotation(acg.getAnnotation());
1587 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1589 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1594 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1598 ac.setMaxColour(acg.getMaxColour().getRGB());
1599 ac.setMinColour(acg.getMinColour().getRGB());
1600 ac.setPerSequence(acg.isSeqAssociated());
1601 ac.setPredefinedColours(acg.isPredefinedColours());
1605 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1606 IdentityHashMap<SequenceGroup, String> groupRefs,
1607 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1608 SequenceSet vamsasSet)
1611 for (int i = 0; i < aa.length; i++)
1613 Annotation an = new Annotation();
1615 AlignmentAnnotation annotation = aa[i];
1616 if (annotation.annotationId != null)
1618 annotationIds.put(annotation.annotationId, annotation);
1621 an.setId(annotation.annotationId);
1623 an.setVisible(annotation.visible);
1625 an.setDescription(annotation.description);
1627 if (annotation.sequenceRef != null)
1629 // 2.9 JAL-1781 xref on sequence id rather than name
1630 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1632 if (annotation.groupRef != null)
1634 String groupIdr = groupRefs.get(annotation.groupRef);
1635 if (groupIdr == null)
1637 // make a locally unique String
1639 annotation.groupRef,
1640 groupIdr = ("" + System.currentTimeMillis()
1641 + annotation.groupRef.getName() + groupRefs
1644 an.setGroupRef(groupIdr.toString());
1647 // store all visualization attributes for annotation
1648 an.setGraphHeight(annotation.graphHeight);
1649 an.setCentreColLabels(annotation.centreColLabels);
1650 an.setScaleColLabels(annotation.scaleColLabel);
1651 an.setShowAllColLabels(annotation.showAllColLabels);
1652 an.setBelowAlignment(annotation.belowAlignment);
1654 if (annotation.graph > 0)
1657 an.setGraphType(annotation.graph);
1658 an.setGraphGroup(annotation.graphGroup);
1659 if (annotation.getThreshold() != null)
1661 ThresholdLine line = new ThresholdLine();
1662 line.setLabel(annotation.getThreshold().label);
1663 line.setValue(annotation.getThreshold().value);
1664 line.setColour(annotation.getThreshold().colour.getRGB());
1665 an.setThresholdLine(line);
1673 an.setLabel(annotation.label);
1675 if (annotation == av.getAlignmentQualityAnnot()
1676 || annotation == av.getAlignmentConservationAnnotation()
1677 || annotation == av.getAlignmentConsensusAnnotation()
1678 || annotation.autoCalculated)
1680 // new way of indicating autocalculated annotation -
1681 an.setAutoCalculated(annotation.autoCalculated);
1683 if (annotation.hasScore())
1685 an.setScore(annotation.getScore());
1688 if (annotation.getCalcId() != null)
1690 calcIdSet.add(annotation.getCalcId());
1691 an.setCalcId(annotation.getCalcId());
1693 if (annotation.hasProperties())
1695 for (String pr : annotation.getProperties())
1697 Property prop = new Property();
1699 prop.setValue(annotation.getProperty(pr));
1700 an.addProperty(prop);
1704 AnnotationElement ae;
1705 if (annotation.annotations != null)
1707 an.setScoreOnly(false);
1708 for (int a = 0; a < annotation.annotations.length; a++)
1710 if ((annotation == null) || (annotation.annotations[a] == null))
1715 ae = new AnnotationElement();
1716 if (annotation.annotations[a].description != null)
1718 ae.setDescription(annotation.annotations[a].description);
1720 if (annotation.annotations[a].displayCharacter != null)
1722 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1725 if (!Float.isNaN(annotation.annotations[a].value))
1727 ae.setValue(annotation.annotations[a].value);
1731 if (annotation.annotations[a].secondaryStructure > ' ')
1733 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1737 if (annotation.annotations[a].colour != null
1738 && annotation.annotations[a].colour != java.awt.Color.black)
1740 ae.setColour(annotation.annotations[a].colour.getRGB());
1743 an.addAnnotationElement(ae);
1744 if (annotation.autoCalculated)
1746 // only write one non-null entry into the annotation row -
1747 // sufficient to get the visualization attributes necessary to
1755 an.setScoreOnly(true);
1757 if (!storeDS || (storeDS && !annotation.autoCalculated))
1759 // skip autocalculated annotation - these are only provided for
1761 vamsasSet.addAnnotation(an);
1767 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1769 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1770 if (settings != null)
1772 CalcIdParam vCalcIdParam = new CalcIdParam();
1773 vCalcIdParam.setCalcId(calcId);
1774 vCalcIdParam.addServiceURL(settings.getServiceURI());
1775 // generic URI allowing a third party to resolve another instance of the
1776 // service used for this calculation
1777 for (String urls : settings.getServiceURLs())
1779 vCalcIdParam.addServiceURL(urls);
1781 vCalcIdParam.setVersion("1.0");
1782 if (settings.getPreset() != null)
1784 WsParamSetI setting = settings.getPreset();
1785 vCalcIdParam.setName(setting.getName());
1786 vCalcIdParam.setDescription(setting.getDescription());
1790 vCalcIdParam.setName("");
1791 vCalcIdParam.setDescription("Last used parameters");
1793 // need to be able to recover 1) settings 2) user-defined presets or
1794 // recreate settings from preset 3) predefined settings provided by
1795 // service - or settings that can be transferred (or discarded)
1796 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1798 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1799 // todo - decide if updateImmediately is needed for any projects.
1801 return vCalcIdParam;
1806 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1809 if (calcIdParam.getVersion().equals("1.0"))
1811 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1812 .getPreferredServiceFor(calcIdParam.getServiceURL());
1813 if (service != null)
1815 WsParamSetI parmSet = null;
1818 parmSet = service.getParamStore().parseServiceParameterFile(
1819 calcIdParam.getName(), calcIdParam.getDescription(),
1820 calcIdParam.getServiceURL(),
1821 calcIdParam.getParameters().replace("|\\n|", "\n"));
1822 } catch (IOException x)
1824 warn("Couldn't parse parameter data for "
1825 + calcIdParam.getCalcId(), x);
1828 List<ArgumentI> argList = null;
1829 if (calcIdParam.getName().length() > 0)
1831 parmSet = service.getParamStore()
1832 .getPreset(calcIdParam.getName());
1833 if (parmSet != null)
1835 // TODO : check we have a good match with settings in AACon -
1836 // otherwise we'll need to create a new preset
1841 argList = parmSet.getArguments();
1844 AAConSettings settings = new AAConSettings(
1845 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1846 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1847 calcIdParam.isNeedsUpdate());
1852 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1856 throw new Error(MessageManager.formatMessage(
1857 "error.unsupported_version_calcIdparam",
1858 new Object[] { calcIdParam.toString() }));
1862 * External mapping between jalview objects and objects yielding a valid and
1863 * unique object ID string. This is null for normal Jalview project IO, but
1864 * non-null when a jalview project is being read or written as part of a
1867 IdentityHashMap jv2vobj = null;
1870 * Construct a unique ID for jvobj using either existing bindings or if none
1871 * exist, the result of the hashcode call for the object.
1874 * jalview data object
1875 * @return unique ID for referring to jvobj
1877 private String makeHashCode(Object jvobj, String altCode)
1879 if (jv2vobj != null)
1881 Object id = jv2vobj.get(jvobj);
1884 return id.toString();
1886 // check string ID mappings
1887 if (jvids2vobj != null && jvobj instanceof String)
1889 id = jvids2vobj.get(jvobj);
1893 return id.toString();
1895 // give up and warn that something has gone wrong
1896 warn("Cannot find ID for object in external mapping : " + jvobj);
1902 * return local jalview object mapped to ID, if it exists
1906 * @return null or object bound to idcode
1908 private Object retrieveExistingObj(String idcode)
1910 if (idcode != null && vobj2jv != null)
1912 return vobj2jv.get(idcode);
1918 * binding from ID strings from external mapping table to jalview data model
1921 private Hashtable vobj2jv;
1923 private Sequence createVamsasSequence(String id, SequenceI jds)
1925 return createVamsasSequence(true, id, jds, null);
1928 private Sequence createVamsasSequence(boolean recurse, String id,
1929 SequenceI jds, SequenceI parentseq)
1931 Sequence vamsasSeq = new Sequence();
1932 vamsasSeq.setId(id);
1933 vamsasSeq.setName(jds.getName());
1934 vamsasSeq.setSequence(jds.getSequenceAsString());
1935 vamsasSeq.setDescription(jds.getDescription());
1936 jalview.datamodel.DBRefEntry[] dbrefs = null;
1937 if (jds.getDatasetSequence() != null)
1939 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1940 if (jds.getDatasetSequence().getDBRef() != null)
1942 dbrefs = jds.getDatasetSequence().getDBRef();
1947 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1948 // dataset sequences only
1949 dbrefs = jds.getDBRef();
1953 for (int d = 0; d < dbrefs.length; d++)
1955 DBRef dbref = new DBRef();
1956 dbref.setSource(dbrefs[d].getSource());
1957 dbref.setVersion(dbrefs[d].getVersion());
1958 dbref.setAccessionId(dbrefs[d].getAccessionId());
1959 if (dbrefs[d].hasMap())
1961 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1963 dbref.setMapping(mp);
1965 vamsasSeq.addDBRef(dbref);
1971 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1972 SequenceI parentseq, SequenceI jds, boolean recurse)
1975 if (jmp.getMap() != null)
1979 jalview.util.MapList mlst = jmp.getMap();
1980 List<int[]> r = mlst.getFromRanges();
1981 for (int[] range : r)
1983 MapListFrom mfrom = new MapListFrom();
1984 mfrom.setStart(range[0]);
1985 mfrom.setEnd(range[1]);
1986 mp.addMapListFrom(mfrom);
1988 r = mlst.getToRanges();
1989 for (int[] range : r)
1991 MapListTo mto = new MapListTo();
1992 mto.setStart(range[0]);
1993 mto.setEnd(range[1]);
1994 mp.addMapListTo(mto);
1996 mp.setMapFromUnit(mlst.getFromRatio());
1997 mp.setMapToUnit(mlst.getToRatio());
1998 if (jmp.getTo() != null)
2000 MappingChoice mpc = new MappingChoice();
2002 && (parentseq != jmp.getTo() || parentseq
2003 .getDatasetSequence() != jmp.getTo()))
2005 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2011 SequenceI ps = null;
2012 if (parentseq != jmp.getTo()
2013 && parentseq.getDatasetSequence() != jmp.getTo())
2015 // chaining dbref rather than a handshaking one
2016 jmpid = seqHash(ps = jmp.getTo());
2020 jmpid = seqHash(ps = parentseq);
2022 mpc.setDseqFor(jmpid);
2023 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2025 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2026 seqRefIds.put(mpc.getDseqFor(), ps);
2030 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2033 mp.setMappingChoice(mpc);
2039 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2040 List<UserColourScheme> userColours, JalviewModelSequence jms)
2043 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2044 boolean newucs = false;
2045 if (!userColours.contains(ucs))
2047 userColours.add(ucs);
2050 id = "ucs" + userColours.indexOf(ucs);
2053 // actually create the scheme's entry in the XML model
2054 java.awt.Color[] colours = ucs.getColours();
2055 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2056 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2058 for (int i = 0; i < colours.length; i++)
2060 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2061 col.setName(ResidueProperties.aa[i]);
2062 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2063 jbucs.addColour(col);
2065 if (ucs.getLowerCaseColours() != null)
2067 colours = ucs.getLowerCaseColours();
2068 for (int i = 0; i < colours.length; i++)
2070 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2071 col.setName(ResidueProperties.aa[i].toLowerCase());
2072 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2073 jbucs.addColour(col);
2078 uc.setUserColourScheme(jbucs);
2079 jms.addUserColours(uc);
2085 jalview.schemes.UserColourScheme getUserColourScheme(
2086 JalviewModelSequence jms, String id)
2088 UserColours[] uc = jms.getUserColours();
2089 UserColours colours = null;
2091 for (int i = 0; i < uc.length; i++)
2093 if (uc[i].getId().equals(id))
2101 java.awt.Color[] newColours = new java.awt.Color[24];
2103 for (int i = 0; i < 24; i++)
2105 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2106 .getUserColourScheme().getColour(i).getRGB(), 16));
2109 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2112 if (colours.getUserColourScheme().getColourCount() > 24)
2114 newColours = new java.awt.Color[23];
2115 for (int i = 0; i < 23; i++)
2117 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2118 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2120 ucs.setLowerCaseColours(newColours);
2127 * contains last error message (if any) encountered by XML loader.
2129 String errorMessage = null;
2132 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2133 * exceptions are raised during project XML parsing
2135 public boolean attemptversion1parse = true;
2138 * Load a jalview project archive from a jar file
2141 * - HTTP URL or filename
2143 public AlignFrame loadJalviewAlign(final String file)
2146 jalview.gui.AlignFrame af = null;
2150 // create list to store references for any new Jmol viewers created
2151 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2152 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2153 // Workaround is to make sure caller implements the JarInputStreamProvider
2155 // so we can re-open the jar input stream for each entry.
2157 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2158 af = loadJalviewAlign(jprovider);
2160 } catch (MalformedURLException e)
2162 errorMessage = "Invalid URL format for '" + file + "'";
2168 SwingUtilities.invokeAndWait(new Runnable()
2172 setLoadingFinishedForNewStructureViewers();
2175 } catch (Exception x)
2177 System.err.println("Error loading alignment: " + x.getMessage());
2183 private jarInputStreamProvider createjarInputStreamProvider(
2184 final String file) throws MalformedURLException
2187 errorMessage = null;
2188 uniqueSetSuffix = null;
2190 viewportsAdded.clear();
2191 frefedSequence = null;
2193 if (file.startsWith("http://"))
2195 url = new URL(file);
2197 final URL _url = url;
2198 return new jarInputStreamProvider()
2202 public JarInputStream getJarInputStream() throws IOException
2206 return new JarInputStream(_url.openStream());
2210 return new JarInputStream(new FileInputStream(file));
2215 public String getFilename()
2223 * Recover jalview session from a jalview project archive. Caller may
2224 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2225 * themselves. Any null fields will be initialised with default values,
2226 * non-null fields are left alone.
2231 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2233 errorMessage = null;
2234 if (uniqueSetSuffix == null)
2236 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2238 if (seqRefIds == null)
2240 seqRefIds = new HashMap<String, SequenceI>();
2242 if (frefedSequence == null)
2244 frefedSequence = new Vector();
2247 AlignFrame af = null, _af = null;
2248 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2249 final String file = jprovider.getFilename();
2252 JarInputStream jin = null;
2253 JarEntry jarentry = null;
2258 jin = jprovider.getJarInputStream();
2259 for (int i = 0; i < entryCount; i++)
2261 jarentry = jin.getNextJarEntry();
2264 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2266 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2267 JalviewModel object = new JalviewModel();
2269 Unmarshaller unmar = new Unmarshaller(object);
2270 unmar.setValidation(false);
2271 object = (JalviewModel) unmar.unmarshal(in);
2272 if (true) // !skipViewport(object))
2274 _af = loadFromObject(object, file, true, jprovider);
2275 if (object.getJalviewModelSequence().getViewportCount() > 0)
2278 if (af.viewport.isGatherViewsHere())
2280 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2286 else if (jarentry != null)
2288 // Some other file here.
2291 } while (jarentry != null);
2292 resolveFrefedSequences();
2293 } catch (IOException ex)
2295 ex.printStackTrace();
2296 errorMessage = "Couldn't locate Jalview XML file : " + file;
2297 System.err.println("Exception whilst loading jalview XML file : "
2299 } catch (Exception ex)
2301 System.err.println("Parsing as Jalview Version 2 file failed.");
2302 ex.printStackTrace(System.err);
2303 if (attemptversion1parse)
2305 // Is Version 1 Jar file?
2308 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2309 } catch (Exception ex2)
2311 System.err.println("Exception whilst loading as jalviewXMLV1:");
2312 ex2.printStackTrace();
2316 if (Desktop.instance != null)
2318 Desktop.instance.stopLoading();
2322 System.out.println("Successfully loaded archive file");
2325 ex.printStackTrace();
2327 System.err.println("Exception whilst loading jalview XML file : "
2329 } catch (OutOfMemoryError e)
2331 // Don't use the OOM Window here
2332 errorMessage = "Out of memory loading jalview XML file";
2333 System.err.println("Out of memory whilst loading jalview XML file");
2334 e.printStackTrace();
2337 if (Desktop.instance != null)
2339 Desktop.instance.stopLoading();
2343 * Regather multiple views (with the same sequence set id) to the frame (if
2344 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2345 * views instead of separate frames. Note this doesn't restore a state where
2346 * some expanded views in turn have tabbed views - the last "first tab" read
2347 * in will play the role of gatherer for all.
2349 for (AlignFrame fr : gatherToThisFrame.values())
2351 Desktop.instance.gatherViews(fr);
2354 restoreSplitFrames();
2356 if (errorMessage != null)
2364 * Try to reconstruct and display SplitFrame windows, where each contains
2365 * complementary dna and protein alignments. Done by pairing up AlignFrame
2366 * objects (created earlier) which have complementary viewport ids associated.
2368 protected void restoreSplitFrames()
2370 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2371 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2372 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2375 * Identify the DNA alignments
2377 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2380 AlignFrame af = candidate.getValue();
2381 if (af.getViewport().getAlignment().isNucleotide())
2383 dna.put(candidate.getKey().getId(), af);
2388 * Try to match up the protein complements
2390 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2393 AlignFrame af = candidate.getValue();
2394 if (!af.getViewport().getAlignment().isNucleotide())
2396 String complementId = candidate.getKey().getComplementId();
2397 // only non-null complements should be in the Map
2398 if (complementId != null && dna.containsKey(complementId))
2400 final AlignFrame dnaFrame = dna.get(complementId);
2401 SplitFrame sf = createSplitFrame(dnaFrame, af);
2402 addedToSplitFrames.add(dnaFrame);
2403 addedToSplitFrames.add(af);
2404 if (af.viewport.isGatherViewsHere())
2413 * Open any that we failed to pair up (which shouldn't happen!) as
2414 * standalone AlignFrame's.
2416 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2419 AlignFrame af = candidate.getValue();
2420 if (!addedToSplitFrames.contains(af))
2422 Viewport view = candidate.getKey();
2423 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2425 System.err.println("Failed to restore view " + view.getTitle()
2426 + " to split frame");
2431 * Gather back into tabbed views as flagged.
2433 for (SplitFrame sf : gatherTo)
2435 Desktop.instance.gatherViews(sf);
2438 splitFrameCandidates.clear();
2442 * Construct and display one SplitFrame holding DNA and protein alignments.
2445 * @param proteinFrame
2448 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2449 AlignFrame proteinFrame)
2451 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2452 String title = MessageManager.getString("label.linked_view_title");
2453 int width = (int) dnaFrame.getBounds().getWidth();
2454 int height = (int) (dnaFrame.getBounds().getHeight()
2455 + proteinFrame.getBounds().getHeight() + 50);
2456 Desktop.addInternalFrame(splitFrame, title, width, height);
2459 * And compute cDNA consensus (couldn't do earlier with consensus as
2460 * mappings were not yet present)
2462 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2468 * check errorMessage for a valid error message and raise an error box in the
2469 * GUI or write the current errorMessage to stderr and then clear the error
2472 protected void reportErrors()
2474 reportErrors(false);
2477 protected void reportErrors(final boolean saving)
2479 if (errorMessage != null)
2481 final String finalErrorMessage = errorMessage;
2484 javax.swing.SwingUtilities.invokeLater(new Runnable()
2489 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2490 finalErrorMessage, "Error "
2491 + (saving ? "saving" : "loading")
2492 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2498 System.err.println("Problem loading Jalview file: " + errorMessage);
2501 errorMessage = null;
2504 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2507 * when set, local views will be updated from view stored in JalviewXML
2508 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2509 * sync if this is set to true.
2511 private final boolean updateLocalViews = false;
2514 * Returns the path to a temporary file holding the PDB file for the given PDB
2515 * id. The first time of asking, searches for a file of that name in the
2516 * Jalview project jar, and copies it to a new temporary file. Any repeat
2517 * requests just return the path to the file previously created.
2523 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2525 if (alreadyLoadedPDB.containsKey(pdbId))
2527 return alreadyLoadedPDB.get(pdbId).toString();
2530 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2531 if (tempFile != null)
2533 alreadyLoadedPDB.put(pdbId, tempFile);
2539 * Copies the jar entry of given name to a new temporary file and returns the
2540 * path to the file, or null if the entry is not found.
2543 * @param jarEntryName
2545 * a prefix for the temporary file name, must be at least three
2549 protected String copyJarEntry(jarInputStreamProvider jprovider,
2550 String jarEntryName, String prefix)
2552 BufferedReader in = null;
2553 PrintWriter out = null;
2557 JarInputStream jin = jprovider.getJarInputStream();
2559 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2560 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2561 * FileInputStream(jprovider)); }
2564 JarEntry entry = null;
2567 entry = jin.getNextJarEntry();
2568 } while (entry != null && !entry.getName().equals(jarEntryName));
2571 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2572 File outFile = File.createTempFile(prefix, ".tmp");
2573 outFile.deleteOnExit();
2574 out = new PrintWriter(new FileOutputStream(outFile));
2577 while ((data = in.readLine()) != null)
2582 String t = outFile.getAbsolutePath();
2587 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2589 } catch (Exception ex)
2591 ex.printStackTrace();
2599 } catch (IOException e)
2613 private class JvAnnotRow
2615 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2622 * persisted version of annotation row from which to take vis properties
2624 public jalview.datamodel.AlignmentAnnotation template;
2627 * original position of the annotation row in the alignment
2633 * Load alignment frame from jalview XML DOM object
2638 * filename source string
2639 * @param loadTreesAndStructures
2640 * when false only create Viewport
2642 * data source provider
2643 * @return alignment frame created from view stored in DOM
2645 AlignFrame loadFromObject(JalviewModel object, String file,
2646 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2648 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2649 Sequence[] vamsasSeq = vamsasSet.getSequence();
2651 JalviewModelSequence jms = object.getJalviewModelSequence();
2653 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2656 // ////////////////////////////////
2659 List<SequenceI> hiddenSeqs = null;
2660 jalview.datamodel.Sequence jseq;
2662 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2664 boolean multipleView = false;
2666 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2667 int vi = 0; // counter in vamsasSeq array
2668 for (int i = 0; i < jseqs.length; i++)
2670 String seqId = jseqs[i].getId();
2672 if (seqRefIds.get(seqId) != null)
2674 tmpseqs.add(seqRefIds.get(seqId));
2675 multipleView = true;
2679 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2680 vamsasSeq[vi].getSequence());
2681 jseq.setDescription(vamsasSeq[vi].getDescription());
2682 jseq.setStart(jseqs[i].getStart());
2683 jseq.setEnd(jseqs[i].getEnd());
2684 jseq.setVamsasId(uniqueSetSuffix + seqId);
2685 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2690 if (jseqs[i].getHidden())
2692 if (hiddenSeqs == null)
2694 hiddenSeqs = new ArrayList<SequenceI>();
2697 hiddenSeqs.add(seqRefIds.get(seqId));
2703 // Create the alignment object from the sequence set
2704 // ///////////////////////////////
2705 SequenceI[] orderedSeqs = tmpseqs
2706 .toArray(new SequenceI[tmpseqs.size()]);
2708 Alignment al = new Alignment(orderedSeqs);
2710 // / Add the alignment properties
2711 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2713 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2714 al.setProperty(ssp.getKey(), ssp.getValue());
2718 // SequenceFeatures are added to the DatasetSequence,
2719 // so we must create or recover the dataset before loading features
2720 // ///////////////////////////////
2721 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2723 // older jalview projects do not have a dataset id.
2724 al.setDataset(null);
2728 // recover dataset - passing on flag indicating if this a 'viewless'
2729 // sequence set (a.k.a. a stored dataset for the project)
2730 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2731 .getViewportCount() == 0);
2733 // ///////////////////////////////
2735 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2738 // load sequence features, database references and any associated PDB
2739 // structures for the alignment
2740 for (int i = 0; i < vamsasSeq.length; i++)
2742 if (jseqs[i].getFeaturesCount() > 0)
2744 Features[] features = jseqs[i].getFeatures();
2745 for (int f = 0; f < features.length; f++)
2747 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2748 features[f].getType(), features[f].getDescription(),
2749 features[f].getStatus(), features[f].getBegin(),
2750 features[f].getEnd(), features[f].getFeatureGroup());
2752 sf.setScore(features[f].getScore());
2753 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2755 OtherData keyValue = features[f].getOtherData(od);
2756 if (keyValue.getKey().startsWith("LINK"))
2758 sf.addLink(keyValue.getValue());
2762 sf.setValue(keyValue.getKey(), keyValue.getValue());
2767 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2770 if (vamsasSeq[i].getDBRefCount() > 0)
2772 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2774 if (jseqs[i].getPdbidsCount() > 0)
2776 Pdbids[] ids = jseqs[i].getPdbids();
2777 for (int p = 0; p < ids.length; p++)
2779 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2780 entry.setId(ids[p].getId());
2781 if (ids[p].getType() != null)
2783 if (ids[p].getType().equalsIgnoreCase("PDB"))
2785 entry.setType(PDBEntry.Type.PDB);
2789 entry.setType(PDBEntry.Type.FILE);
2792 if (ids[p].getFile() != null)
2794 if (!pdbloaded.containsKey(ids[p].getFile()))
2796 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2800 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2803 StructureSelectionManager.getStructureSelectionManager(
2804 Desktop.instance).registerPDBEntry(entry);
2805 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2809 } // end !multipleview
2811 // ///////////////////////////////
2812 // LOAD SEQUENCE MAPPINGS
2814 if (vamsasSet.getAlcodonFrameCount() > 0)
2816 // TODO Potentially this should only be done once for all views of an
2818 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2819 for (int i = 0; i < alc.length; i++)
2821 AlignedCodonFrame cf = new AlignedCodonFrame();
2822 if (alc[i].getAlcodMapCount() > 0)
2824 AlcodMap[] maps = alc[i].getAlcodMap();
2825 for (int m = 0; m < maps.length; m++)
2827 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2829 jalview.datamodel.Mapping mapping = null;
2830 // attach to dna sequence reference.
2831 if (maps[m].getMapping() != null)
2833 mapping = addMapping(maps[m].getMapping());
2837 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2842 frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
2847 al.addCodonFrame(cf);
2851 // ////////////////////////////////
2853 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2856 * store any annotations which forward reference a group's ID
2858 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2860 if (vamsasSet.getAnnotationCount() > 0)
2862 Annotation[] an = vamsasSet.getAnnotation();
2864 for (int i = 0; i < an.length; i++)
2866 Annotation annotation = an[i];
2869 * test if annotation is automatically calculated for this view only
2871 boolean autoForView = false;
2872 if (annotation.getLabel().equals("Quality")
2873 || annotation.getLabel().equals("Conservation")
2874 || annotation.getLabel().equals("Consensus"))
2876 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2878 if (!annotation.hasAutoCalculated())
2880 annotation.setAutoCalculated(true);
2884 || (annotation.hasAutoCalculated() && annotation
2885 .isAutoCalculated()))
2887 // remove ID - we don't recover annotation from other views for
2888 // view-specific annotation
2889 annotation.setId(null);
2892 // set visiblity for other annotation in this view
2893 String annotationId = annotation.getId();
2894 if (annotationId != null && annotationIds.containsKey(annotationId))
2896 AlignmentAnnotation jda = annotationIds.get(annotationId);
2897 // in principle Visible should always be true for annotation displayed
2898 // in multiple views
2899 if (annotation.hasVisible())
2901 jda.visible = annotation.getVisible();
2904 al.addAnnotation(jda);
2908 // Construct new annotation from model.
2909 AnnotationElement[] ae = annotation.getAnnotationElement();
2910 jalview.datamodel.Annotation[] anot = null;
2911 java.awt.Color firstColour = null;
2913 if (!annotation.getScoreOnly())
2915 anot = new jalview.datamodel.Annotation[al.getWidth()];
2916 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2918 anpos = ae[aa].getPosition();
2920 if (anpos >= anot.length)
2925 anot[anpos] = new jalview.datamodel.Annotation(
2927 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2928 (ae[aa].getSecondaryStructure() == null || ae[aa]
2929 .getSecondaryStructure().length() == 0) ? ' '
2930 : ae[aa].getSecondaryStructure().charAt(0),
2934 // JBPNote: Consider verifying dataflow for IO of secondary
2935 // structure annotation read from Stockholm files
2936 // this was added to try to ensure that
2937 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2939 // anot[ae[aa].getPosition()].displayCharacter = "";
2941 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2942 if (firstColour == null)
2944 firstColour = anot[anpos].colour;
2948 jalview.datamodel.AlignmentAnnotation jaa = null;
2950 if (annotation.getGraph())
2952 float llim = 0, hlim = 0;
2953 // if (autoForView || an[i].isAutoCalculated()) {
2956 jaa = new jalview.datamodel.AlignmentAnnotation(
2957 annotation.getLabel(), annotation.getDescription(), anot,
2958 llim, hlim, annotation.getGraphType());
2960 jaa.graphGroup = annotation.getGraphGroup();
2961 jaa._linecolour = firstColour;
2962 if (annotation.getThresholdLine() != null)
2964 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
2965 .getThresholdLine().getValue(), annotation
2966 .getThresholdLine().getLabel(), new java.awt.Color(
2967 annotation.getThresholdLine().getColour())));
2970 if (autoForView || annotation.isAutoCalculated())
2972 // Hardwire the symbol display line to ensure that labels for
2973 // histograms are displayed
2979 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2980 an[i].getDescription(), anot);
2981 jaa._linecolour = firstColour;
2983 // register new annotation
2984 if (an[i].getId() != null)
2986 annotationIds.put(an[i].getId(), jaa);
2987 jaa.annotationId = an[i].getId();
2989 // recover sequence association
2990 String sequenceRef = an[i].getSequenceRef();
2991 if (sequenceRef != null)
2993 // from 2.9 sequenceRef is to sequence id (JAL-1781)
2994 SequenceI sequence = seqRefIds.get(sequenceRef);
2995 if (sequence == null)
2997 // in pre-2.9 projects sequence ref is to sequence name
2998 sequence = al.findName(sequenceRef);
3000 if (sequence != null)
3002 jaa.createSequenceMapping(sequence, 1, true);
3003 sequence.addAlignmentAnnotation(jaa);
3006 // and make a note of any group association
3007 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3009 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3010 .get(an[i].getGroupRef());
3013 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3014 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3019 if (an[i].hasScore())
3021 jaa.setScore(an[i].getScore());
3023 if (an[i].hasVisible())
3025 jaa.visible = an[i].getVisible();
3028 if (an[i].hasCentreColLabels())
3030 jaa.centreColLabels = an[i].getCentreColLabels();
3033 if (an[i].hasScaleColLabels())
3035 jaa.scaleColLabel = an[i].getScaleColLabels();
3037 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3039 // newer files have an 'autoCalculated' flag and store calculation
3040 // state in viewport properties
3041 jaa.autoCalculated = true; // means annotation will be marked for
3042 // update at end of load.
3044 if (an[i].hasGraphHeight())
3046 jaa.graphHeight = an[i].getGraphHeight();
3048 if (an[i].hasBelowAlignment())
3050 jaa.belowAlignment = an[i].isBelowAlignment();
3052 jaa.setCalcId(an[i].getCalcId());
3053 if (an[i].getPropertyCount() > 0)
3055 for (jalview.schemabinding.version2.Property prop : an[i]
3058 jaa.setProperty(prop.getName(), prop.getValue());
3061 if (jaa.autoCalculated)
3063 autoAlan.add(new JvAnnotRow(i, jaa));
3066 // if (!autoForView)
3068 // add autocalculated group annotation and any user created annotation
3070 al.addAnnotation(jaa);
3074 // ///////////////////////
3076 // Create alignment markup and styles for this view
3077 if (jms.getJGroupCount() > 0)
3079 JGroup[] groups = jms.getJGroup();
3080 boolean addAnnotSchemeGroup = false;
3081 for (int i = 0; i < groups.length; i++)
3083 JGroup jGroup = groups[i];
3084 ColourSchemeI cs = null;
3085 if (jGroup.getColour() != null)
3087 if (jGroup.getColour().startsWith("ucs"))
3089 cs = getUserColourScheme(jms, jGroup.getColour());
3091 else if (jGroup.getColour().equals("AnnotationColourGradient")
3092 && jGroup.getAnnotationColours() != null)
3094 addAnnotSchemeGroup = true;
3099 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3104 cs.setThreshold(jGroup.getPidThreshold(), true);
3108 Vector<SequenceI> seqs = new Vector<SequenceI>();
3110 for (int s = 0; s < jGroup.getSeqCount(); s++)
3112 String seqId = jGroup.getSeq(s) + "";
3113 SequenceI ts = seqRefIds.get(seqId);
3117 seqs.addElement(ts);
3121 if (seqs.size() < 1)
3126 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3127 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3128 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3130 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3132 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3133 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3134 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3135 .isShowUnconserved() : false);
3136 sg.thresholdTextColour = jGroup.getTextColThreshold();
3137 if (jGroup.hasShowConsensusHistogram())
3139 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3142 if (jGroup.hasShowSequenceLogo())
3144 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3146 if (jGroup.hasNormaliseSequenceLogo())
3148 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3150 if (jGroup.hasIgnoreGapsinConsensus())
3152 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3154 if (jGroup.getConsThreshold() != 0)
3156 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3157 "All", ResidueProperties.propHash, 3,
3158 sg.getSequences(null), 0, sg.getWidth() - 1);
3160 c.verdict(false, 25);
3161 sg.cs.setConservation(c);
3164 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3166 // re-instate unique group/annotation row reference
3167 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3171 for (AlignmentAnnotation jaa : jaal)
3174 if (jaa.autoCalculated)
3176 // match up and try to set group autocalc alignment row for this
3178 if (jaa.label.startsWith("Consensus for "))
3180 sg.setConsensus(jaa);
3182 // match up and try to set group autocalc alignment row for this
3184 if (jaa.label.startsWith("Conservation for "))
3186 sg.setConservationRow(jaa);
3193 if (addAnnotSchemeGroup)
3195 // reconstruct the annotation colourscheme
3196 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3197 null, al, jms, false);
3203 // only dataset in this model, so just return.
3206 // ///////////////////////////////
3209 // If we just load in the same jar file again, the sequenceSetId
3210 // will be the same, and we end up with multiple references
3211 // to the same sequenceSet. We must modify this id on load
3212 // so that each load of the file gives a unique id
3213 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3214 String viewId = (view.getId() == null ? null : view.getId()
3216 AlignFrame af = null;
3217 AlignViewport av = null;
3218 // now check to see if we really need to create a new viewport.
3219 if (multipleView && viewportsAdded.size() == 0)
3221 // We recovered an alignment for which a viewport already exists.
3222 // TODO: fix up any settings necessary for overlaying stored state onto
3223 // state recovered from another document. (may not be necessary).
3224 // we may need a binding from a viewport in memory to one recovered from
3226 // and then recover its containing af to allow the settings to be applied.
3227 // TODO: fix for vamsas demo
3229 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3231 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3232 if (seqsetobj != null)
3234 if (seqsetobj instanceof String)
3236 uniqueSeqSetId = (String) seqsetobj;
3238 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3244 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3250 * indicate that annotation colours are applied across all groups (pre
3251 * Jalview 2.8.1 behaviour)
3253 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
3254 object.getVersion());
3256 AlignmentPanel ap = null;
3257 boolean isnewview = true;
3260 // Check to see if this alignment already has a view id == viewId
3261 jalview.gui.AlignmentPanel views[] = Desktop
3262 .getAlignmentPanels(uniqueSeqSetId);
3263 if (views != null && views.length > 0)
3265 for (int v = 0; v < views.length; v++)
3267 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3269 // recover the existing alignpanel, alignframe, viewport
3270 af = views[v].alignFrame;
3273 // TODO: could even skip resetting view settings if we don't want to
3274 // change the local settings from other jalview processes
3283 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3284 uniqueSeqSetId, viewId, autoAlan);
3290 * Load any trees, PDB structures and viewers
3292 * Not done if flag is false (when this method is used for New View)
3294 if (loadTreesAndStructures)
3296 loadTrees(jms, view, af, av, ap);
3297 loadPDBStructures(jprovider, jseqs, af, ap);
3298 loadRnaViewers(jprovider, jseqs, ap);
3300 // and finally return.
3305 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3306 * panel is restored from separate jar entries, two (gapped and trimmed) per
3307 * sequence and secondary structure.
3309 * Currently each viewer shows just one sequence and structure (gapped and
3310 * trimmed), however this method is designed to support multiple sequences or
3311 * structures in viewers if wanted in future.
3317 private void loadRnaViewers(jarInputStreamProvider jprovider,
3318 JSeq[] jseqs, AlignmentPanel ap)
3321 * scan the sequences for references to viewers; create each one the first
3322 * time it is referenced, add Rna models to existing viewers
3324 for (JSeq jseq : jseqs)
3326 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3328 RnaViewer viewer = jseq.getRnaViewer(i);
3329 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3330 uniqueSetSuffix, ap);
3332 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3334 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3335 SequenceI seq = seqRefIds.get(jseq.getId());
3336 AlignmentAnnotation ann = this.annotationIds.get(ss
3337 .getAnnotationId());
3340 * add the structure to the Varna display (with session state copied
3341 * from the jar to a temporary file)
3343 boolean gapped = ss.isGapped();
3344 String rnaTitle = ss.getTitle();
3345 String sessionState = ss.getViewerState();
3346 String tempStateFile = copyJarEntry(jprovider, sessionState,
3348 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3349 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3351 appVarna.setInitialSelection(viewer.getSelectedRna());
3357 * Locate and return an already instantiated matching AppVarna, or create one
3361 * @param viewIdSuffix
3365 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3366 String viewIdSuffix, AlignmentPanel ap)
3369 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3370 * if load is repeated
3372 String postLoadId = viewer.getViewId() + viewIdSuffix;
3373 for (JInternalFrame frame : getAllFrames())
3375 if (frame instanceof AppVarna)
3377 AppVarna varna = (AppVarna) frame;
3378 if (postLoadId.equals(varna.getViewId()))
3380 // this viewer is already instantiated
3381 // could in future here add ap as another 'parent' of the
3382 // AppVarna window; currently just 1-to-many
3389 * viewer not found - make it
3391 RnaViewerModel model = new RnaViewerModel(postLoadId,
3392 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3393 viewer.getWidth(), viewer.getHeight(),
3394 viewer.getDividerLocation());
3395 AppVarna varna = new AppVarna(model, ap);
3401 * Load any saved trees
3409 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3410 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3412 // TODO result of automated refactoring - are all these parameters needed?
3415 for (int t = 0; t < jms.getTreeCount(); t++)
3418 Tree tree = jms.getTree(t);
3420 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3423 tp = af.ShowNewickTree(
3424 new jalview.io.NewickFile(tree.getNewick()),
3425 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3426 tree.getXpos(), tree.getYpos());
3427 if (tree.getId() != null)
3429 // perhaps bind the tree id to something ?
3434 // update local tree attributes ?
3435 // TODO: should check if tp has been manipulated by user - if so its
3436 // settings shouldn't be modified
3437 tp.setTitle(tree.getTitle());
3438 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3439 .getWidth(), tree.getHeight()));
3440 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3443 tp.treeCanvas.av = av; // af.viewport;
3444 tp.treeCanvas.ap = ap; // af.alignPanel;
3449 warn("There was a problem recovering stored Newick tree: \n"
3450 + tree.getNewick());
3454 tp.fitToWindow.setState(tree.getFitToWindow());
3455 tp.fitToWindow_actionPerformed(null);
3457 if (tree.getFontName() != null)
3459 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3460 .getFontStyle(), tree.getFontSize()));
3464 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3465 .getFontStyle(), tree.getFontSize()));
3468 tp.showPlaceholders(tree.getMarkUnlinked());
3469 tp.showBootstrap(tree.getShowBootstrap());
3470 tp.showDistances(tree.getShowDistances());
3472 tp.treeCanvas.threshold = tree.getThreshold();
3474 if (tree.getCurrentTree())
3476 af.viewport.setCurrentTree(tp.getTree());
3480 } catch (Exception ex)
3482 ex.printStackTrace();
3487 * Load and link any saved structure viewers.
3494 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3495 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3498 * Run through all PDB ids on the alignment, and collect mappings between
3499 * distinct view ids and all sequences referring to that view.
3501 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3503 for (int i = 0; i < jseqs.length; i++)
3505 if (jseqs[i].getPdbidsCount() > 0)
3507 Pdbids[] ids = jseqs[i].getPdbids();
3508 for (int p = 0; p < ids.length; p++)
3510 final int structureStateCount = ids[p].getStructureStateCount();
3511 for (int s = 0; s < structureStateCount; s++)
3513 // check to see if we haven't already created this structure view
3514 final StructureState structureState = ids[p]
3515 .getStructureState(s);
3516 String sviewid = (structureState.getViewId() == null) ? null
3517 : structureState.getViewId() + uniqueSetSuffix;
3518 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3519 // Originally : ids[p].getFile()
3520 // : TODO: verify external PDB file recovery still works in normal
3521 // jalview project load
3522 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3523 jpdb.setId(ids[p].getId());
3525 int x = structureState.getXpos();
3526 int y = structureState.getYpos();
3527 int width = structureState.getWidth();
3528 int height = structureState.getHeight();
3530 // Probably don't need to do this anymore...
3531 // Desktop.desktop.getComponentAt(x, y);
3532 // TODO: NOW: check that this recovers the PDB file correctly.
3533 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3534 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3536 if (sviewid == null)
3538 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3541 if (!structureViewers.containsKey(sviewid))
3543 structureViewers.put(sviewid,
3544 new StructureViewerModel(x, y, width, height, false,
3545 false, true, structureState.getViewId(),
3546 structureState.getType()));
3547 // Legacy pre-2.7 conversion JAL-823 :
3548 // do not assume any view has to be linked for colour by
3552 // assemble String[] { pdb files }, String[] { id for each
3553 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3554 // seqs_file 2}, boolean[] {
3555 // linkAlignPanel,superposeWithAlignpanel}} from hash
3556 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3557 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3558 | (structureState.hasAlignwithAlignPanel() ? structureState
3559 .getAlignwithAlignPanel() : false));
3562 * Default colour by linked panel to false if not specified (e.g.
3563 * for pre-2.7 projects)
3565 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3566 colourWithAlignPanel |= (structureState
3567 .hasColourwithAlignPanel() ? structureState
3568 .getColourwithAlignPanel() : false);
3569 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3572 * Default colour by viewer to true if not specified (e.g. for
3575 boolean colourByViewer = jmoldat.isColourByViewer();
3576 colourByViewer &= structureState.hasColourByJmol() ? structureState
3577 .getColourByJmol() : true;
3578 jmoldat.setColourByViewer(colourByViewer);
3580 if (jmoldat.getStateData().length() < structureState
3581 .getContent().length())
3584 jmoldat.setStateData(structureState.getContent());
3587 if (ids[p].getFile() != null)
3589 File mapkey = new File(ids[p].getFile());
3590 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3591 if (seqstrmaps == null)
3593 jmoldat.getFileData().put(
3595 seqstrmaps = jmoldat.new StructureData(pdbFile,
3598 if (!seqstrmaps.getSeqList().contains(seq))
3600 seqstrmaps.getSeqList().add(seq);
3606 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");
3613 // Instantiate the associated structure views
3614 for (Entry<String, StructureViewerModel> entry : structureViewers
3619 createOrLinkStructureViewer(entry, af, ap, jprovider);
3620 } catch (Exception e)
3622 System.err.println("Error loading structure viewer: "
3624 // failed - try the next one
3636 protected void createOrLinkStructureViewer(
3637 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3638 AlignmentPanel ap, jarInputStreamProvider jprovider)
3640 final StructureViewerModel stateData = viewerData.getValue();
3643 * Search for any viewer windows already open from other alignment views
3644 * that exactly match the stored structure state
3646 StructureViewerBase comp = findMatchingViewer(viewerData);
3650 linkStructureViewer(ap, comp, stateData);
3655 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3656 * "viewer_"+stateData.viewId
3658 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3660 createChimeraViewer(viewerData, af, jprovider);
3665 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3667 createJmolViewer(viewerData, af, jprovider);
3672 * Create a new Chimera viewer.
3678 protected void createChimeraViewer(
3679 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3680 jarInputStreamProvider jprovider)
3682 StructureViewerModel data = viewerData.getValue();
3683 String chimeraSessionFile = data.getStateData();
3686 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3688 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3689 * 'uniquified' sviewid used to reconstruct the viewer here
3691 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3692 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3695 Set<Entry<File, StructureData>> fileData = data.getFileData()
3697 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3698 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3699 for (Entry<File, StructureData> pdb : fileData)
3701 String filePath = pdb.getValue().getFilePath();
3702 String pdbId = pdb.getValue().getPdbId();
3703 // pdbs.add(new PDBEntry(filePath, pdbId));
3704 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3705 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3706 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3710 boolean colourByChimera = data.isColourByViewer();
3711 boolean colourBySequence = data.isColourWithAlignPanel();
3713 // TODO use StructureViewer as a factory here, see JAL-1761
3714 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3715 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3717 String newViewId = viewerData.getKey();
3719 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3720 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3721 colourBySequence, newViewId);
3722 cvf.setSize(data.getWidth(), data.getHeight());
3723 cvf.setLocation(data.getX(), data.getY());
3727 * Create a new Jmol window. First parse the Jmol state to translate filenames
3728 * loaded into the view, and record the order in which files are shown in the
3729 * Jmol view, so we can add the sequence mappings in same order.
3735 protected void createJmolViewer(
3736 final Entry<String, StructureViewerModel> viewerData,
3737 AlignFrame af, jarInputStreamProvider jprovider)
3739 final StructureViewerModel svattrib = viewerData.getValue();
3740 String state = svattrib.getStateData();
3743 * Pre-2.9: state element value is the Jmol state string
3745 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3748 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3750 state = readJarEntry(jprovider,
3751 getViewerJarEntryName(svattrib.getViewId()));
3754 List<String> pdbfilenames = new ArrayList<String>();
3755 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3756 List<String> pdbids = new ArrayList<String>();
3757 StringBuilder newFileLoc = new StringBuilder(64);
3758 int cp = 0, ncp, ecp;
3759 Map<File, StructureData> oldFiles = svattrib.getFileData();
3760 while ((ncp = state.indexOf("load ", cp)) > -1)
3764 // look for next filename in load statement
3765 newFileLoc.append(state.substring(cp,
3766 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3767 String oldfilenam = state.substring(ncp,
3768 ecp = state.indexOf("\"", ncp));
3769 // recover the new mapping data for this old filename
3770 // have to normalize filename - since Jmol and jalview do
3772 // translation differently.
3773 StructureData filedat = oldFiles.get(new File(oldfilenam));
3774 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3775 pdbfilenames.add(filedat.getFilePath());
3776 pdbids.add(filedat.getPdbId());
3777 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3778 newFileLoc.append("\"");
3779 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3780 // look for next file statement.
3781 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3785 // just append rest of state
3786 newFileLoc.append(state.substring(cp));
3790 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3791 newFileLoc = new StringBuilder(state);
3792 newFileLoc.append("; load append ");
3793 for (File id : oldFiles.keySet())
3795 // add this and any other pdb files that should be present in
3797 StructureData filedat = oldFiles.get(id);
3798 newFileLoc.append(filedat.getFilePath());
3799 pdbfilenames.add(filedat.getFilePath());
3800 pdbids.add(filedat.getPdbId());
3801 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3802 newFileLoc.append(" \"");
3803 newFileLoc.append(filedat.getFilePath());
3804 newFileLoc.append("\"");
3807 newFileLoc.append(";");
3810 if (newFileLoc.length() == 0)
3814 int histbug = newFileLoc.indexOf("history = ");
3818 * change "history = [true|false];" to "history = [1|0];"
3821 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3822 String val = (diff == -1) ? null : newFileLoc
3823 .substring(histbug, diff);
3824 if (val != null && val.length() >= 4)
3826 if (val.contains("e")) // eh? what can it be?
3828 if (val.trim().equals("true"))
3836 newFileLoc.replace(histbug, diff, val);
3841 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3843 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3844 final SequenceI[][] sq = seqmaps
3845 .toArray(new SequenceI[seqmaps.size()][]);
3846 final String fileloc = newFileLoc.toString();
3847 final String sviewid = viewerData.getKey();
3848 final AlignFrame alf = af;
3849 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3850 svattrib.getWidth(), svattrib.getHeight());
3853 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3858 JalviewStructureDisplayI sview = null;
3861 sview = new StructureViewer(alf.alignPanel
3862 .getStructureSelectionManager()).createView(
3863 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3864 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3865 addNewStructureViewer(sview);
3866 } catch (OutOfMemoryError ex)
3868 new OOMWarning("restoring structure view for PDB id " + id,
3869 (OutOfMemoryError) ex.getCause());
3870 if (sview != null && sview.isVisible())
3872 sview.closeViewer(false);
3873 sview.setVisible(false);
3879 } catch (InvocationTargetException ex)
3881 warn("Unexpected error when opening Jmol view.", ex);
3883 } catch (InterruptedException e)
3885 // e.printStackTrace();
3891 * Generates a name for the entry in the project jar file to hold state
3892 * information for a structure viewer
3897 protected String getViewerJarEntryName(String viewId)
3899 return VIEWER_PREFIX + viewId;
3903 * Returns any open frame that matches given structure viewer data. The match
3904 * is based on the unique viewId, or (for older project versions) the frame's
3910 protected StructureViewerBase findMatchingViewer(
3911 Entry<String, StructureViewerModel> viewerData)
3913 final String sviewid = viewerData.getKey();
3914 final StructureViewerModel svattrib = viewerData.getValue();
3915 StructureViewerBase comp = null;
3916 JInternalFrame[] frames = getAllFrames();
3917 for (JInternalFrame frame : frames)
3919 if (frame instanceof StructureViewerBase)
3922 * Post jalview 2.4 schema includes structure view id
3925 && ((StructureViewerBase) frame).getViewId()
3928 comp = (StructureViewerBase) frame;
3929 break; // break added in 2.9
3932 * Otherwise test for matching position and size of viewer frame
3934 else if (frame.getX() == svattrib.getX()
3935 && frame.getY() == svattrib.getY()
3936 && frame.getHeight() == svattrib.getHeight()
3937 && frame.getWidth() == svattrib.getWidth())
3939 comp = (StructureViewerBase) frame;
3940 // no break in faint hope of an exact match on viewId
3948 * Link an AlignmentPanel to an existing structure viewer.
3953 * @param useinViewerSuperpos
3954 * @param usetoColourbyseq
3955 * @param viewerColouring
3957 protected void linkStructureViewer(AlignmentPanel ap,
3958 StructureViewerBase viewer, StructureViewerModel stateData)
3960 // NOTE: if the jalview project is part of a shared session then
3961 // view synchronization should/could be done here.
3963 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
3964 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
3965 final boolean viewerColouring = stateData.isColourByViewer();
3966 Map<File, StructureData> oldFiles = stateData.getFileData();
3969 * Add mapping for sequences in this view to an already open viewer
3971 final AAStructureBindingModel binding = viewer.getBinding();
3972 for (File id : oldFiles.keySet())
3974 // add this and any other pdb files that should be present in the
3976 StructureData filedat = oldFiles.get(id);
3977 String pdbFile = filedat.getFilePath();
3978 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3979 binding.getSsm().setMapping(seq, null, pdbFile,
3980 jalview.io.AppletFormatAdapter.FILE);
3981 binding.addSequenceForStructFile(pdbFile, seq);
3983 // and add the AlignmentPanel's reference to the view panel
3984 viewer.addAlignmentPanel(ap);
3985 if (useinViewerSuperpos)
3987 viewer.useAlignmentPanelForSuperposition(ap);
3991 viewer.excludeAlignmentPanelForSuperposition(ap);
3993 if (usetoColourbyseq)
3995 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3999 viewer.excludeAlignmentPanelForColourbyseq(ap);
4004 * Get all frames within the Desktop.
4008 protected JInternalFrame[] getAllFrames()
4010 JInternalFrame[] frames = null;
4011 // TODO is this necessary - is it safe - risk of hanging?
4016 frames = Desktop.desktop.getAllFrames();
4017 } catch (ArrayIndexOutOfBoundsException e)
4019 // occasional No such child exceptions are thrown here...
4023 } catch (InterruptedException f)
4027 } while (frames == null);
4034 * - minimum version we are comparing against
4036 * - version of data being processsed.
4037 * @return true if version is development/null or evaluates to the same or
4038 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
4040 protected boolean isVersionStringLaterThan(String supported,
4043 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4044 || version.equalsIgnoreCase("Test")
4045 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4047 System.err.println("Assuming project file with "
4048 + (version == null ? "null" : version)
4049 + " is compatible with Jalview version " + supported);
4054 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
4056 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
4058 // convert b to decimal to catch bugfix releases within a series
4059 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
4060 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
4063 if (Float.valueOf(curT) > Float.valueOf(fileT))
4065 // current version is newer 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 java.awt.Color(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 java.awt.Color(view.getTextCol1()));
4213 af.viewport.setTextColour2(new java.awt.Color(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 Hashtable featureGroups = new Hashtable();
4333 Hashtable featureColours = new Hashtable();
4334 Hashtable featureOrder = new Hashtable();
4336 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4338 Setting setting = jms.getFeatureSettings().getSetting(fs);
4339 if (setting.hasMincolour())
4341 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
4342 new java.awt.Color(setting.getMincolour()),
4343 new java.awt.Color(setting.getColour()),
4344 setting.getMin(), setting.getMax()) : new GraduatedColor(
4345 new java.awt.Color(setting.getMincolour()),
4346 new java.awt.Color(setting.getColour()), 0, 1);
4347 if (setting.hasThreshold())
4349 gc.setThresh(setting.getThreshold());
4350 gc.setThreshType(setting.getThreshstate());
4352 gc.setAutoScaled(true); // default
4353 if (setting.hasAutoScale())
4355 gc.setAutoScaled(setting.getAutoScale());
4357 if (setting.hasColourByLabel())
4359 gc.setColourByLabel(setting.getColourByLabel());
4361 // and put in the feature colour table.
4362 featureColours.put(setting.getType(), gc);
4366 featureColours.put(setting.getType(),
4367 new java.awt.Color(setting.getColour()));
4369 renderOrder[fs] = setting.getType();
4370 if (setting.hasOrder())
4372 featureOrder.put(setting.getType(), setting.getOrder());
4376 featureOrder.put(setting.getType(), new Float(fs
4377 / jms.getFeatureSettings().getSettingCount()));
4379 if (setting.getDisplay())
4381 fdi.setVisible(setting.getType());
4384 Hashtable fgtable = new Hashtable();
4385 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4387 Group grp = jms.getFeatureSettings().getGroup(gs);
4388 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4390 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4391 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4392 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4393 FeatureRendererSettings frs = new FeatureRendererSettings(
4394 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4395 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4396 .transferSettings(frs);
4400 if (view.getHiddenColumnsCount() > 0)
4402 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4404 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4405 .getHiddenColumns(c).getEnd() // +1
4409 if (view.getCalcIdParam() != null)
4411 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4413 if (calcIdParam != null)
4415 if (recoverCalcIdParam(calcIdParam, af.viewport))
4420 warn("Couldn't recover parameters for "
4421 + calcIdParam.getCalcId());
4426 af.setMenusFromViewport(af.viewport);
4428 // TODO: we don't need to do this if the viewport is aready visible.
4430 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4431 * has a 'cdna/protein complement' view, in which case save it in order to
4432 * populate a SplitFrame once all views have been read in.
4434 String complementaryViewId = view.getComplementId();
4435 if (complementaryViewId == null)
4437 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4439 // recompute any autoannotation
4440 af.alignPanel.updateAnnotation(false, true);
4441 reorderAutoannotation(af, al, autoAlan);
4442 af.alignPanel.alignmentChanged();
4446 splitFrameCandidates.put(view, af);
4451 private ColourSchemeI constructAnnotationColour(
4452 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
4453 JalviewModelSequence jms, boolean checkGroupAnnColour)
4455 boolean propagateAnnColour = false;
4456 ColourSchemeI cs = null;
4457 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4458 if (checkGroupAnnColour && al.getGroups() != null
4459 && al.getGroups().size() > 0)
4461 // pre 2.8.1 behaviour
4462 // check to see if we should transfer annotation colours
4463 propagateAnnColour = true;
4464 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4466 if (sg.cs instanceof AnnotationColourGradient)
4468 propagateAnnColour = false;
4472 // int find annotation
4473 if (annAlignment.getAlignmentAnnotation() != null)
4475 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4477 if (annAlignment.getAlignmentAnnotation()[i].label
4478 .equals(viewAnnColour.getAnnotation()))
4480 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4482 annAlignment.getAlignmentAnnotation()[i]
4483 .setThreshold(new jalview.datamodel.GraphLine(
4484 viewAnnColour.getThreshold(), "Threshold",
4485 java.awt.Color.black)
4490 if (viewAnnColour.getColourScheme().equals("None"))
4492 cs = new AnnotationColourGradient(
4493 annAlignment.getAlignmentAnnotation()[i],
4494 new java.awt.Color(viewAnnColour.getMinColour()),
4495 new java.awt.Color(viewAnnColour.getMaxColour()),
4496 viewAnnColour.getAboveThreshold());
4498 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4500 cs = new AnnotationColourGradient(
4501 annAlignment.getAlignmentAnnotation()[i],
4502 getUserColourScheme(jms,
4503 viewAnnColour.getColourScheme()),
4504 viewAnnColour.getAboveThreshold());
4508 cs = new AnnotationColourGradient(
4509 annAlignment.getAlignmentAnnotation()[i],
4510 ColourSchemeProperty.getColour(al,
4511 viewAnnColour.getColourScheme()),
4512 viewAnnColour.getAboveThreshold());
4514 if (viewAnnColour.hasPerSequence())
4516 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4519 if (viewAnnColour.hasPredefinedColours())
4521 ((AnnotationColourGradient) cs)
4522 .setPredefinedColours(viewAnnColour
4523 .isPredefinedColours());
4525 if (propagateAnnColour && al.getGroups() != null)
4527 // Also use these settings for all the groups
4528 for (int g = 0; g < al.getGroups().size(); g++)
4530 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4538 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4539 * new AnnotationColourGradient(
4540 * annAlignment.getAlignmentAnnotation()[i], new
4541 * java.awt.Color(viewAnnColour. getMinColour()), new
4542 * java.awt.Color(viewAnnColour. getMaxColour()),
4543 * viewAnnColour.getAboveThreshold()); } else
4546 sg.cs = new AnnotationColourGradient(
4547 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4548 viewAnnColour.getAboveThreshold());
4549 if (cs instanceof AnnotationColourGradient)
4551 if (viewAnnColour.hasPerSequence())
4553 ((AnnotationColourGradient) cs)
4554 .setSeqAssociated(viewAnnColour.isPerSequence());
4556 if (viewAnnColour.hasPredefinedColours())
4558 ((AnnotationColourGradient) cs)
4559 .setPredefinedColours(viewAnnColour
4560 .isPredefinedColours());
4576 private void reorderAutoannotation(AlignFrame af, Alignment al,
4577 List<JvAnnotRow> autoAlan)
4579 // copy over visualization settings for autocalculated annotation in the
4581 if (al.getAlignmentAnnotation() != null)
4584 * Kludge for magic autoannotation names (see JAL-811)
4586 String[] magicNames = new String[] { "Consensus", "Quality",
4588 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4589 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4590 for (String nm : magicNames)
4592 visan.put(nm, nullAnnot);
4594 for (JvAnnotRow auan : autoAlan)
4596 visan.put(auan.template.label
4597 + (auan.template.getCalcId() == null ? "" : "\t"
4598 + auan.template.getCalcId()), auan);
4600 int hSize = al.getAlignmentAnnotation().length;
4601 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4602 // work through any autoCalculated annotation already on the view
4603 // removing it if it should be placed in a different location on the
4604 // annotation panel.
4605 List<String> remains = new ArrayList<String>(visan.keySet());
4606 for (int h = 0; h < hSize; h++)
4608 jalview.datamodel.AlignmentAnnotation jalan = al
4609 .getAlignmentAnnotation()[h];
4610 if (jalan.autoCalculated)
4613 JvAnnotRow valan = visan.get(k = jalan.label);
4614 if (jalan.getCalcId() != null)
4616 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4621 // delete the auto calculated row from the alignment
4622 al.deleteAnnotation(jalan, false);
4626 if (valan != nullAnnot)
4628 if (jalan != valan.template)
4630 // newly created autoannotation row instance
4631 // so keep a reference to the visible annotation row
4632 // and copy over all relevant attributes
4633 if (valan.template.graphHeight >= 0)
4636 jalan.graphHeight = valan.template.graphHeight;
4638 jalan.visible = valan.template.visible;
4640 reorder.add(new JvAnnotRow(valan.order, jalan));
4645 // Add any (possibly stale) autocalculated rows that were not appended to
4646 // the view during construction
4647 for (String other : remains)
4649 JvAnnotRow othera = visan.get(other);
4650 if (othera != nullAnnot && othera.template.getCalcId() != null
4651 && othera.template.getCalcId().length() > 0)
4653 reorder.add(othera);
4656 // now put the automatic annotation in its correct place
4657 int s = 0, srt[] = new int[reorder.size()];
4658 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4659 for (JvAnnotRow jvar : reorder)
4662 srt[s++] = jvar.order;
4665 jalview.util.QuickSort.sort(srt, rws);
4666 // and re-insert the annotation at its correct position
4667 for (JvAnnotRow jvar : rws)
4669 al.addAnnotation(jvar.template, jvar.order);
4671 af.alignPanel.adjustAnnotationHeight();
4675 Hashtable skipList = null;
4678 * TODO remove this method
4681 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4682 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4683 * throw new Error("Implementation Error. No skipList defined for this
4684 * Jalview2XML instance."); } return (AlignFrame)
4685 * skipList.get(view.getSequenceSetId()); }
4689 * Check if the Jalview view contained in object should be skipped or not.
4692 * @return true if view's sequenceSetId is a key in skipList
4694 private boolean skipViewport(JalviewModel object)
4696 if (skipList == null)
4701 if (skipList.containsKey(id = object.getJalviewModelSequence()
4702 .getViewport()[0].getSequenceSetId()))
4704 if (Cache.log != null && Cache.log.isDebugEnabled())
4706 Cache.log.debug("Skipping seuqence set id " + id);
4713 public void addToSkipList(AlignFrame af)
4715 if (skipList == null)
4717 skipList = new Hashtable();
4719 skipList.put(af.getViewport().getSequenceSetId(), af);
4722 public void clearSkipList()
4724 if (skipList != null)
4731 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4732 boolean ignoreUnrefed)
4734 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4735 Vector dseqs = null;
4738 // create a list of new dataset sequences
4739 dseqs = new Vector();
4741 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4743 Sequence vamsasSeq = vamsasSet.getSequence(i);
4744 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4746 // create a new dataset
4749 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4750 dseqs.copyInto(dsseqs);
4751 ds = new jalview.datamodel.Alignment(dsseqs);
4752 debug("Created new dataset " + vamsasSet.getDatasetId()
4753 + " for alignment " + System.identityHashCode(al));
4754 addDatasetRef(vamsasSet.getDatasetId(), ds);
4756 // set the dataset for the newly imported alignment.
4757 if (al.getDataset() == null && !ignoreUnrefed)
4766 * sequence definition to create/merge dataset sequence for
4770 * vector to add new dataset sequence to
4772 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4773 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4775 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4777 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4778 SequenceI dsq = null;
4779 if (sq != null && sq.getDatasetSequence() != null)
4781 dsq = sq.getDatasetSequence();
4783 if (sq == null && ignoreUnrefed)
4787 String sqid = vamsasSeq.getDsseqid();
4790 // need to create or add a new dataset sequence reference to this sequence
4793 dsq = seqRefIds.get(sqid);
4798 // make a new dataset sequence
4799 dsq = sq.createDatasetSequence();
4802 // make up a new dataset reference for this sequence
4803 sqid = seqHash(dsq);
4805 dsq.setVamsasId(uniqueSetSuffix + sqid);
4806 seqRefIds.put(sqid, dsq);
4811 dseqs.addElement(dsq);
4816 ds.addSequence(dsq);
4822 { // make this dataset sequence sq's dataset sequence
4823 sq.setDatasetSequence(dsq);
4824 // and update the current dataset alignment
4829 if (!dseqs.contains(dsq))
4836 if (ds.findIndex(dsq) < 0)
4838 ds.addSequence(dsq);
4845 // TODO: refactor this as a merge dataset sequence function
4846 // now check that sq (the dataset sequence) sequence really is the union of
4847 // all references to it
4848 // boolean pre = sq.getStart() < dsq.getStart();
4849 // boolean post = sq.getEnd() > dsq.getEnd();
4853 // StringBuffer sb = new StringBuffer();
4854 String newres = jalview.analysis.AlignSeq.extractGaps(
4855 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4856 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4857 && newres.length() > dsq.getLength())
4859 // Update with the longer sequence.
4863 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4864 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4865 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4866 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4868 dsq.setSequence(newres);
4870 // TODO: merges will never happen if we 'know' we have the real dataset
4871 // sequence - this should be detected when id==dssid
4873 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4874 // + (pre ? "prepended" : "") + " "
4875 // + (post ? "appended" : ""));
4881 * TODO use AlignmentI here and in related methods - needs
4882 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4884 Hashtable<String, Alignment> datasetIds = null;
4886 IdentityHashMap<Alignment, String> dataset2Ids = null;
4888 private Alignment getDatasetFor(String datasetId)
4890 if (datasetIds == null)
4892 datasetIds = new Hashtable<String, Alignment>();
4895 if (datasetIds.containsKey(datasetId))
4897 return datasetIds.get(datasetId);
4902 private void addDatasetRef(String datasetId, Alignment dataset)
4904 if (datasetIds == null)
4906 datasetIds = new Hashtable<String, Alignment>();
4908 datasetIds.put(datasetId, dataset);
4912 * make a new dataset ID for this jalview dataset alignment
4917 private String getDatasetIdRef(Alignment dataset)
4919 if (dataset.getDataset() != null)
4921 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4923 String datasetId = makeHashCode(dataset, null);
4924 if (datasetId == null)
4926 // make a new datasetId and record it
4927 if (dataset2Ids == null)
4929 dataset2Ids = new IdentityHashMap<Alignment, String>();
4933 datasetId = dataset2Ids.get(dataset);
4935 if (datasetId == null)
4937 datasetId = "ds" + dataset2Ids.size() + 1;
4938 dataset2Ids.put(dataset, datasetId);
4944 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4946 for (int d = 0; d < sequence.getDBRefCount(); d++)
4948 DBRef dr = sequence.getDBRef(d);
4949 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4950 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4951 .getVersion(), sequence.getDBRef(d).getAccessionId());
4952 if (dr.getMapping() != null)
4954 entry.setMap(addMapping(dr.getMapping()));
4956 datasetSequence.addDBRef(entry);
4960 private jalview.datamodel.Mapping addMapping(Mapping m)
4962 SequenceI dsto = null;
4963 // Mapping m = dr.getMapping();
4964 int fr[] = new int[m.getMapListFromCount() * 2];
4965 Enumeration f = m.enumerateMapListFrom();
4966 for (int _i = 0; f.hasMoreElements(); _i += 2)
4968 MapListFrom mf = (MapListFrom) f.nextElement();
4969 fr[_i] = mf.getStart();
4970 fr[_i + 1] = mf.getEnd();
4972 int fto[] = new int[m.getMapListToCount() * 2];
4973 f = m.enumerateMapListTo();
4974 for (int _i = 0; f.hasMoreElements(); _i += 2)
4976 MapListTo mf = (MapListTo) f.nextElement();
4977 fto[_i] = mf.getStart();
4978 fto[_i + 1] = mf.getEnd();
4980 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4981 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4982 if (m.getMappingChoice() != null)
4984 MappingChoice mc = m.getMappingChoice();
4985 if (mc.getDseqFor() != null)
4987 String dsfor = "" + mc.getDseqFor();
4988 if (seqRefIds.containsKey(dsfor))
4993 jmap.setTo(seqRefIds.get(dsfor));
4997 frefedSequence.add(new Object[] { dsfor, jmap });
5003 * local sequence definition
5005 Sequence ms = mc.getSequence();
5006 SequenceI djs = null;
5007 String sqid = ms.getDsseqid();
5008 if (sqid != null && sqid.length() > 0)
5011 * recover dataset sequence
5013 djs = seqRefIds.get(sqid);
5018 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5019 sqid = ((Object) ms).toString(); // make up a new hascode for
5020 // undefined dataset sequence hash
5021 // (unlikely to happen)
5027 * make a new dataset sequence and add it to refIds hash
5029 djs = new jalview.datamodel.Sequence(ms.getName(),
5031 djs.setStart(jmap.getMap().getToLowest());
5032 djs.setEnd(jmap.getMap().getToHighest());
5033 djs.setVamsasId(uniqueSetSuffix + sqid);
5035 seqRefIds.put(sqid, djs);
5038 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5047 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5048 boolean keepSeqRefs)
5051 JalviewModel jm = saveState(ap, null, null, null);
5056 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5060 uniqueSetSuffix = "";
5061 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5066 if (this.frefedSequence == null)
5068 frefedSequence = new Vector();
5071 viewportsAdded.clear();
5073 AlignFrame af = loadFromObject(jm, null, false, null);
5074 af.alignPanels.clear();
5075 af.closeMenuItem_actionPerformed(true);
5078 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5079 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5080 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5081 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5082 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5085 return af.alignPanel;
5089 * flag indicating if hashtables should be cleared on finalization TODO this
5090 * flag may not be necessary
5092 private final boolean _cleartables = true;
5094 private Hashtable jvids2vobj;
5099 * @see java.lang.Object#finalize()
5102 protected void finalize() throws Throwable
5104 // really make sure we have no buried refs left.
5109 this.seqRefIds = null;
5110 this.seqsToIds = null;
5114 private void warn(String msg)
5119 private void warn(String msg, Exception e)
5121 if (Cache.log != null)
5125 Cache.log.warn(msg, e);
5129 Cache.log.warn(msg);
5134 System.err.println("Warning: " + msg);
5137 e.printStackTrace();
5142 private void debug(String string)
5144 debug(string, null);
5147 private void debug(String msg, Exception e)
5149 if (Cache.log != null)
5153 Cache.log.debug(msg, e);
5157 Cache.log.debug(msg);
5162 System.err.println("Warning: " + msg);
5165 e.printStackTrace();
5171 * set the object to ID mapping tables used to write/recover objects and XML
5172 * ID strings for the jalview project. If external tables are provided then
5173 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5174 * object goes out of scope. - also populates the datasetIds hashtable with
5175 * alignment objects containing dataset sequences
5178 * Map from ID strings to jalview datamodel
5180 * Map from jalview datamodel to ID strings
5184 public void setObjectMappingTables(Hashtable vobj2jv,
5185 IdentityHashMap jv2vobj)
5187 this.jv2vobj = jv2vobj;
5188 this.vobj2jv = vobj2jv;
5189 Iterator ds = jv2vobj.keySet().iterator();
5191 while (ds.hasNext())
5193 Object jvobj = ds.next();
5194 id = jv2vobj.get(jvobj).toString();
5195 if (jvobj instanceof jalview.datamodel.Alignment)
5197 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5199 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5202 else if (jvobj instanceof jalview.datamodel.Sequence)
5204 // register sequence object so the XML parser can recover it.
5205 if (seqRefIds == null)
5207 seqRefIds = new HashMap<String, SequenceI>();
5209 if (seqsToIds == null)
5211 seqsToIds = new IdentityHashMap<SequenceI, String>();
5213 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5214 seqsToIds.put((SequenceI) jvobj, id);
5216 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5219 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5220 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5221 if (jvann.annotationId == null)
5223 jvann.annotationId = anid;
5225 if (!jvann.annotationId.equals(anid))
5227 // TODO verify that this is the correct behaviour
5228 this.warn("Overriding Annotation ID for " + anid
5229 + " from different id : " + jvann.annotationId);
5230 jvann.annotationId = anid;
5233 else if (jvobj instanceof String)
5235 if (jvids2vobj == null)
5237 jvids2vobj = new Hashtable();
5238 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5243 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5249 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5250 * objects created from the project archive. If string is null (default for
5251 * construction) then suffix will be set automatically.
5255 public void setUniqueSetSuffix(String string)
5257 uniqueSetSuffix = string;
5262 * uses skipList2 as the skipList for skipping views on sequence sets
5263 * associated with keys in the skipList
5267 public void setSkipList(Hashtable skipList2)
5269 skipList = skipList2;
5273 * Reads the jar entry of given name and returns its contents, or null if the
5274 * entry is not found.
5277 * @param jarEntryName
5280 protected String readJarEntry(jarInputStreamProvider jprovider,
5281 String jarEntryName)
5283 String result = null;
5284 BufferedReader in = null;
5289 * Reopen the jar input stream and traverse its entries to find a matching
5292 JarInputStream jin = jprovider.getJarInputStream();
5293 JarEntry entry = null;
5296 entry = jin.getNextJarEntry();
5297 } while (entry != null && !entry.getName().equals(jarEntryName));
5301 StringBuilder out = new StringBuilder(256);
5302 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5305 while ((data = in.readLine()) != null)
5309 result = out.toString();
5313 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5315 } catch (Exception ex)
5317 ex.printStackTrace();
5325 } catch (IOException e)
5336 * Returns an incrementing counter (0, 1, 2...)
5340 private synchronized int nextCounter()