2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2)
3 * Copyright (C) 2015 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 size = ap.av.getExplodedGeometry();
1096 Rectangle position = size;
1099 size = ap.alignFrame.getBounds();
1100 if (av.getCodingComplement() != null)
1102 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1110 view.setXpos(position.x);
1111 view.setYpos(position.y);
1113 view.setWidth(size.width);
1114 view.setHeight(size.height);
1116 view.setStartRes(av.startRes);
1117 view.setStartSeq(av.startSeq);
1119 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1121 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1124 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1126 AnnotationColours ac = constructAnnotationColours(
1127 (jalview.schemes.AnnotationColourGradient) av
1128 .getGlobalColourScheme(),
1131 view.setAnnotationColours(ac);
1132 view.setBgColour("AnnotationColourGradient");
1136 view.setBgColour(ColourSchemeProperty.getColourName(av
1137 .getGlobalColourScheme()));
1140 ColourSchemeI cs = av.getGlobalColourScheme();
1144 if (cs.conservationApplied())
1146 view.setConsThreshold(cs.getConservationInc());
1147 if (cs instanceof jalview.schemes.UserColourScheme)
1149 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1153 if (cs instanceof ResidueColourScheme)
1155 view.setPidThreshold(cs.getThreshold());
1159 view.setConservationSelected(av.getConservationSelected());
1160 view.setPidSelected(av.getAbovePIDThreshold());
1161 view.setFontName(av.font.getName());
1162 view.setFontSize(av.font.getSize());
1163 view.setFontStyle(av.font.getStyle());
1164 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1165 view.setRenderGaps(av.isRenderGaps());
1166 view.setShowAnnotation(av.isShowAnnotation());
1167 view.setShowBoxes(av.getShowBoxes());
1168 view.setShowColourText(av.getColourText());
1169 view.setShowFullId(av.getShowJVSuffix());
1170 view.setRightAlignIds(av.isRightAlignIds());
1171 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1172 view.setShowText(av.getShowText());
1173 view.setShowUnconserved(av.getShowUnconserved());
1174 view.setWrapAlignment(av.getWrapAlignment());
1175 view.setTextCol1(av.getTextColour().getRGB());
1176 view.setTextCol2(av.getTextColour2().getRGB());
1177 view.setTextColThreshold(av.getThresholdTextColour());
1178 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1179 view.setShowSequenceLogo(av.isShowSequenceLogo());
1180 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1181 view.setShowGroupConsensus(av.isShowGroupConsensus());
1182 view.setShowGroupConservation(av.isShowGroupConservation());
1183 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1184 view.setShowDbRefTooltip(av.isShowDBRefs());
1185 view.setFollowHighlight(av.isFollowHighlight());
1186 view.setFollowSelection(av.followSelection);
1187 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1188 if (av.getFeaturesDisplayed() != null)
1190 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1192 String[] renderOrder = ap.getSeqPanel().seqCanvas
1193 .getFeatureRenderer().getRenderOrder()
1194 .toArray(new String[0]);
1196 Vector settingsAdded = new Vector();
1197 Object gstyle = null;
1198 GraduatedColor gcol = null;
1199 if (renderOrder != null)
1201 for (int ro = 0; ro < renderOrder.length; ro++)
1203 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1204 .getFeatureStyle(renderOrder[ro]);
1205 Setting setting = new Setting();
1206 setting.setType(renderOrder[ro]);
1207 if (gstyle instanceof GraduatedColor)
1209 gcol = (GraduatedColor) gstyle;
1210 setting.setColour(gcol.getMaxColor().getRGB());
1211 setting.setMincolour(gcol.getMinColor().getRGB());
1212 setting.setMin(gcol.getMin());
1213 setting.setMax(gcol.getMax());
1214 setting.setColourByLabel(gcol.isColourByLabel());
1215 setting.setAutoScale(gcol.isAutoScale());
1216 setting.setThreshold(gcol.getThresh());
1217 setting.setThreshstate(gcol.getThreshType());
1221 setting.setColour(ap.getSeqPanel().seqCanvas
1222 .getFeatureRenderer().getColour(renderOrder[ro])
1226 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1228 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1229 .getOrder(renderOrder[ro]);
1232 setting.setOrder(rorder);
1234 fs.addSetting(setting);
1235 settingsAdded.addElement(renderOrder[ro]);
1239 // Make sure we save none displayed feature settings
1240 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1241 .getFeatureColours().keySet().iterator();
1242 while (en.hasNext())
1244 String key = en.next().toString();
1245 if (settingsAdded.contains(key))
1250 Setting setting = new Setting();
1251 setting.setType(key);
1252 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1253 .getColour(key).getRGB());
1255 setting.setDisplay(false);
1256 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1260 setting.setOrder(rorder);
1262 fs.addSetting(setting);
1263 settingsAdded.addElement(key);
1265 // is groups actually supposed to be a map here ?
1266 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1267 .getFeatureGroups().iterator();
1268 Vector groupsAdded = new Vector();
1269 while (en.hasNext())
1271 String grp = en.next().toString();
1272 if (groupsAdded.contains(grp))
1276 Group g = new Group();
1278 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1279 .getFeatureRenderer().checkGroupVisibility(grp, false))
1282 groupsAdded.addElement(grp);
1284 jms.setFeatureSettings(fs);
1288 if (av.hasHiddenColumns())
1290 if (av.getColumnSelection() == null
1291 || av.getColumnSelection().getHiddenColumns() == null)
1293 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1297 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1300 int[] region = av.getColumnSelection().getHiddenColumns()
1302 HiddenColumns hc = new HiddenColumns();
1303 hc.setStart(region[0]);
1304 hc.setEnd(region[1]);
1305 view.addHiddenColumns(hc);
1309 if (calcIdSet.size() > 0)
1311 for (String calcId : calcIdSet)
1313 if (calcId.trim().length() > 0)
1315 CalcIdParam cidp = createCalcIdParam(calcId, av);
1316 // Some calcIds have no parameters.
1319 view.addCalcIdParam(cidp);
1325 jms.addViewport(view);
1327 object.setJalviewModelSequence(jms);
1328 object.getVamsasModel().addSequenceSet(vamsasSet);
1330 if (jout != null && fileName != null)
1332 // We may not want to write the object to disk,
1333 // eg we can copy the alignViewport to a new view object
1334 // using save and then load
1337 System.out.println("Writing jar entry " + fileName);
1338 JarEntry entry = new JarEntry(fileName);
1339 jout.putNextEntry(entry);
1340 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1342 Marshaller marshaller = new Marshaller(pout);
1343 marshaller.marshal(object);
1346 } catch (Exception ex)
1348 // TODO: raise error in GUI if marshalling failed.
1349 ex.printStackTrace();
1356 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1357 * for each viewer, with
1359 * <li>viewer geometry (position, size, split pane divider location)</li>
1360 * <li>index of the selected structure in the viewer (currently shows gapped
1362 * <li>the id of the annotation holding RNA secondary structure</li>
1363 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1365 * Varna viewer state is also written out (in native Varna XML) to separate
1366 * project jar entries. A separate entry is written for each RNA structure
1367 * displayed, with the naming convention
1369 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1377 * @param storeDataset
1379 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1380 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1381 boolean storeDataset)
1383 if (Desktop.desktop == null)
1387 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1388 for (int f = frames.length - 1; f > -1; f--)
1390 if (frames[f] instanceof AppVarna)
1392 AppVarna varna = (AppVarna) frames[f];
1394 * link the sequence to every viewer that is showing it and is linked to
1395 * its alignment panel
1397 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1399 String viewId = varna.getViewId();
1400 RnaViewer rna = new RnaViewer();
1401 rna.setViewId(viewId);
1402 rna.setTitle(varna.getTitle());
1403 rna.setXpos(varna.getX());
1404 rna.setYpos(varna.getY());
1405 rna.setWidth(varna.getWidth());
1406 rna.setHeight(varna.getHeight());
1407 rna.setDividerLocation(varna.getDividerLocation());
1408 rna.setSelectedRna(varna.getSelectedIndex());
1409 jseq.addRnaViewer(rna);
1412 * Store each Varna panel's state once in the project per sequence.
1413 * First time through only (storeDataset==false)
1415 // boolean storeSessions = false;
1416 // String sequenceViewId = viewId + seqsToIds.get(jds);
1417 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1419 // viewIds.add(sequenceViewId);
1420 // storeSessions = true;
1422 for (RnaModel model : varna.getModels())
1424 if (model.seq == jds)
1427 * VARNA saves each view (sequence or alignment secondary
1428 * structure, gapped or trimmed) as a separate XML file
1430 String jarEntryName = rnaSessions.get(model);
1431 if (jarEntryName == null)
1434 String varnaStateFile = varna.getStateInfo(model.rna);
1435 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1436 copyFileToJar(jout, varnaStateFile, jarEntryName);
1437 rnaSessions.put(model, jarEntryName);
1439 SecondaryStructure ss = new SecondaryStructure();
1440 String annotationId = varna.getAnnotation(jds).annotationId;
1441 ss.setAnnotationId(annotationId);
1442 ss.setViewerState(jarEntryName);
1443 ss.setGapped(model.gapped);
1444 ss.setTitle(model.title);
1445 rna.addSecondaryStructure(ss);
1454 * Copy the contents of a file to a new entry added to the output jar
1458 * @param jarEntryName
1460 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1461 String jarEntryName)
1463 DataInputStream dis = null;
1466 File file = new File(infilePath);
1467 if (file.exists() && jout != null)
1469 dis = new DataInputStream(new FileInputStream(file));
1470 byte[] data = new byte[(int) file.length()];
1471 dis.readFully(data);
1472 writeJarEntry(jout, jarEntryName, data);
1474 } catch (Exception ex)
1476 ex.printStackTrace();
1484 } catch (IOException e)
1493 * Write the data to a new entry of given name in the output jar file
1496 * @param jarEntryName
1498 * @throws IOException
1500 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1501 byte[] data) throws IOException
1505 System.out.println("Writing jar entry " + jarEntryName);
1506 jout.putNextEntry(new JarEntry(jarEntryName));
1507 DataOutputStream dout = new DataOutputStream(jout);
1508 dout.write(data, 0, data.length);
1515 * Save the state of a structure viewer
1520 * the archive XML element under which to save the state
1523 * @param matchedFile
1527 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1528 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1529 String matchedFile, StructureViewerBase viewFrame)
1531 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1534 * Look for any bindings for this viewer to the PDB file of interest
1535 * (including part matches excluding chain id)
1537 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1539 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1540 final String pdbId = pdbentry.getId();
1541 if (!pdbId.equals(entry.getId())
1542 && !(entry.getId().length() > 4 && entry.getId()
1543 .toLowerCase().startsWith(pdbId.toLowerCase())))
1546 * not interested in a binding to a different PDB entry here
1550 if (matchedFile == null)
1552 matchedFile = pdbentry.getFile();
1554 else if (!matchedFile.equals(pdbentry.getFile()))
1557 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1558 + pdbentry.getFile());
1562 // can get at it if the ID
1563 // match is ambiguous (e.g.
1566 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1568 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1569 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1571 StructureState state = new StructureState();
1572 state.setVisible(true);
1573 state.setXpos(viewFrame.getX());
1574 state.setYpos(viewFrame.getY());
1575 state.setWidth(viewFrame.getWidth());
1576 state.setHeight(viewFrame.getHeight());
1577 final String viewId = viewFrame.getViewId();
1578 state.setViewId(viewId);
1579 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1580 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1581 state.setColourByJmol(viewFrame.isColouredByViewer());
1582 state.setType(viewFrame.getViewerType().toString());
1583 pdb.addStructureState(state);
1590 private AnnotationColours constructAnnotationColours(
1591 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1592 JalviewModelSequence jms)
1594 AnnotationColours ac = new AnnotationColours();
1595 ac.setAboveThreshold(acg.getAboveThreshold());
1596 ac.setThreshold(acg.getAnnotationThreshold());
1597 ac.setAnnotation(acg.getAnnotation());
1598 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1600 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1605 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1609 ac.setMaxColour(acg.getMaxColour().getRGB());
1610 ac.setMinColour(acg.getMinColour().getRGB());
1611 ac.setPerSequence(acg.isSeqAssociated());
1612 ac.setPredefinedColours(acg.isPredefinedColours());
1616 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1617 IdentityHashMap<SequenceGroup, String> groupRefs,
1618 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1619 SequenceSet vamsasSet)
1622 for (int i = 0; i < aa.length; i++)
1624 Annotation an = new Annotation();
1626 AlignmentAnnotation annotation = aa[i];
1627 if (annotation.annotationId != null)
1629 annotationIds.put(annotation.annotationId, annotation);
1632 an.setId(annotation.annotationId);
1634 an.setVisible(annotation.visible);
1636 an.setDescription(annotation.description);
1638 if (annotation.sequenceRef != null)
1640 // 2.9 JAL-1781 xref on sequence id rather than name
1641 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1643 if (annotation.groupRef != null)
1645 String groupIdr = groupRefs.get(annotation.groupRef);
1646 if (groupIdr == null)
1648 // make a locally unique String
1650 annotation.groupRef,
1651 groupIdr = ("" + System.currentTimeMillis()
1652 + annotation.groupRef.getName() + groupRefs
1655 an.setGroupRef(groupIdr.toString());
1658 // store all visualization attributes for annotation
1659 an.setGraphHeight(annotation.graphHeight);
1660 an.setCentreColLabels(annotation.centreColLabels);
1661 an.setScaleColLabels(annotation.scaleColLabel);
1662 an.setShowAllColLabels(annotation.showAllColLabels);
1663 an.setBelowAlignment(annotation.belowAlignment);
1665 if (annotation.graph > 0)
1668 an.setGraphType(annotation.graph);
1669 an.setGraphGroup(annotation.graphGroup);
1670 if (annotation.getThreshold() != null)
1672 ThresholdLine line = new ThresholdLine();
1673 line.setLabel(annotation.getThreshold().label);
1674 line.setValue(annotation.getThreshold().value);
1675 line.setColour(annotation.getThreshold().colour.getRGB());
1676 an.setThresholdLine(line);
1684 an.setLabel(annotation.label);
1686 if (annotation == av.getAlignmentQualityAnnot()
1687 || annotation == av.getAlignmentConservationAnnotation()
1688 || annotation == av.getAlignmentConsensusAnnotation()
1689 || annotation.autoCalculated)
1691 // new way of indicating autocalculated annotation -
1692 an.setAutoCalculated(annotation.autoCalculated);
1694 if (annotation.hasScore())
1696 an.setScore(annotation.getScore());
1699 if (annotation.getCalcId() != null)
1701 calcIdSet.add(annotation.getCalcId());
1702 an.setCalcId(annotation.getCalcId());
1704 if (annotation.hasProperties())
1706 for (String pr : annotation.getProperties())
1708 Property prop = new Property();
1710 prop.setValue(annotation.getProperty(pr));
1711 an.addProperty(prop);
1715 AnnotationElement ae;
1716 if (annotation.annotations != null)
1718 an.setScoreOnly(false);
1719 for (int a = 0; a < annotation.annotations.length; a++)
1721 if ((annotation == null) || (annotation.annotations[a] == null))
1726 ae = new AnnotationElement();
1727 if (annotation.annotations[a].description != null)
1729 ae.setDescription(annotation.annotations[a].description);
1731 if (annotation.annotations[a].displayCharacter != null)
1733 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1736 if (!Float.isNaN(annotation.annotations[a].value))
1738 ae.setValue(annotation.annotations[a].value);
1742 if (annotation.annotations[a].secondaryStructure > ' ')
1744 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1748 if (annotation.annotations[a].colour != null
1749 && annotation.annotations[a].colour != java.awt.Color.black)
1751 ae.setColour(annotation.annotations[a].colour.getRGB());
1754 an.addAnnotationElement(ae);
1755 if (annotation.autoCalculated)
1757 // only write one non-null entry into the annotation row -
1758 // sufficient to get the visualization attributes necessary to
1766 an.setScoreOnly(true);
1768 if (!storeDS || (storeDS && !annotation.autoCalculated))
1770 // skip autocalculated annotation - these are only provided for
1772 vamsasSet.addAnnotation(an);
1778 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1780 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1781 if (settings != null)
1783 CalcIdParam vCalcIdParam = new CalcIdParam();
1784 vCalcIdParam.setCalcId(calcId);
1785 vCalcIdParam.addServiceURL(settings.getServiceURI());
1786 // generic URI allowing a third party to resolve another instance of the
1787 // service used for this calculation
1788 for (String urls : settings.getServiceURLs())
1790 vCalcIdParam.addServiceURL(urls);
1792 vCalcIdParam.setVersion("1.0");
1793 if (settings.getPreset() != null)
1795 WsParamSetI setting = settings.getPreset();
1796 vCalcIdParam.setName(setting.getName());
1797 vCalcIdParam.setDescription(setting.getDescription());
1801 vCalcIdParam.setName("");
1802 vCalcIdParam.setDescription("Last used parameters");
1804 // need to be able to recover 1) settings 2) user-defined presets or
1805 // recreate settings from preset 3) predefined settings provided by
1806 // service - or settings that can be transferred (or discarded)
1807 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1809 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1810 // todo - decide if updateImmediately is needed for any projects.
1812 return vCalcIdParam;
1817 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1820 if (calcIdParam.getVersion().equals("1.0"))
1822 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1823 .getPreferredServiceFor(calcIdParam.getServiceURL());
1824 if (service != null)
1826 WsParamSetI parmSet = null;
1829 parmSet = service.getParamStore().parseServiceParameterFile(
1830 calcIdParam.getName(), calcIdParam.getDescription(),
1831 calcIdParam.getServiceURL(),
1832 calcIdParam.getParameters().replace("|\\n|", "\n"));
1833 } catch (IOException x)
1835 warn("Couldn't parse parameter data for "
1836 + calcIdParam.getCalcId(), x);
1839 List<ArgumentI> argList = null;
1840 if (calcIdParam.getName().length() > 0)
1842 parmSet = service.getParamStore()
1843 .getPreset(calcIdParam.getName());
1844 if (parmSet != null)
1846 // TODO : check we have a good match with settings in AACon -
1847 // otherwise we'll need to create a new preset
1852 argList = parmSet.getArguments();
1855 AAConSettings settings = new AAConSettings(
1856 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1857 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1858 calcIdParam.isNeedsUpdate());
1863 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1867 throw new Error(MessageManager.formatMessage(
1868 "error.unsupported_version_calcIdparam",
1869 new Object[] { calcIdParam.toString() }));
1873 * External mapping between jalview objects and objects yielding a valid and
1874 * unique object ID string. This is null for normal Jalview project IO, but
1875 * non-null when a jalview project is being read or written as part of a
1878 IdentityHashMap jv2vobj = null;
1881 * Construct a unique ID for jvobj using either existing bindings or if none
1882 * exist, the result of the hashcode call for the object.
1885 * jalview data object
1886 * @return unique ID for referring to jvobj
1888 private String makeHashCode(Object jvobj, String altCode)
1890 if (jv2vobj != null)
1892 Object id = jv2vobj.get(jvobj);
1895 return id.toString();
1897 // check string ID mappings
1898 if (jvids2vobj != null && jvobj instanceof String)
1900 id = jvids2vobj.get(jvobj);
1904 return id.toString();
1906 // give up and warn that something has gone wrong
1907 warn("Cannot find ID for object in external mapping : " + jvobj);
1913 * return local jalview object mapped to ID, if it exists
1917 * @return null or object bound to idcode
1919 private Object retrieveExistingObj(String idcode)
1921 if (idcode != null && vobj2jv != null)
1923 return vobj2jv.get(idcode);
1929 * binding from ID strings from external mapping table to jalview data model
1932 private Hashtable vobj2jv;
1934 private Sequence createVamsasSequence(String id, SequenceI jds)
1936 return createVamsasSequence(true, id, jds, null);
1939 private Sequence createVamsasSequence(boolean recurse, String id,
1940 SequenceI jds, SequenceI parentseq)
1942 Sequence vamsasSeq = new Sequence();
1943 vamsasSeq.setId(id);
1944 vamsasSeq.setName(jds.getName());
1945 vamsasSeq.setSequence(jds.getSequenceAsString());
1946 vamsasSeq.setDescription(jds.getDescription());
1947 jalview.datamodel.DBRefEntry[] dbrefs = null;
1948 if (jds.getDatasetSequence() != null)
1950 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1951 if (jds.getDatasetSequence().getDBRef() != null)
1953 dbrefs = jds.getDatasetSequence().getDBRef();
1958 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1959 // dataset sequences only
1960 dbrefs = jds.getDBRef();
1964 for (int d = 0; d < dbrefs.length; d++)
1966 DBRef dbref = new DBRef();
1967 dbref.setSource(dbrefs[d].getSource());
1968 dbref.setVersion(dbrefs[d].getVersion());
1969 dbref.setAccessionId(dbrefs[d].getAccessionId());
1970 if (dbrefs[d].hasMap())
1972 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1974 dbref.setMapping(mp);
1976 vamsasSeq.addDBRef(dbref);
1982 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1983 SequenceI parentseq, SequenceI jds, boolean recurse)
1986 if (jmp.getMap() != null)
1990 jalview.util.MapList mlst = jmp.getMap();
1991 List<int[]> r = mlst.getFromRanges();
1992 for (int[] range : r)
1994 MapListFrom mfrom = new MapListFrom();
1995 mfrom.setStart(range[0]);
1996 mfrom.setEnd(range[1]);
1997 mp.addMapListFrom(mfrom);
1999 r = mlst.getToRanges();
2000 for (int[] range : r)
2002 MapListTo mto = new MapListTo();
2003 mto.setStart(range[0]);
2004 mto.setEnd(range[1]);
2005 mp.addMapListTo(mto);
2007 mp.setMapFromUnit(mlst.getFromRatio());
2008 mp.setMapToUnit(mlst.getToRatio());
2009 if (jmp.getTo() != null)
2011 MappingChoice mpc = new MappingChoice();
2013 && (parentseq != jmp.getTo() || parentseq
2014 .getDatasetSequence() != jmp.getTo()))
2016 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2022 SequenceI ps = null;
2023 if (parentseq != jmp.getTo()
2024 && parentseq.getDatasetSequence() != jmp.getTo())
2026 // chaining dbref rather than a handshaking one
2027 jmpid = seqHash(ps = jmp.getTo());
2031 jmpid = seqHash(ps = parentseq);
2033 mpc.setDseqFor(jmpid);
2034 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2036 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2037 seqRefIds.put(mpc.getDseqFor(), ps);
2041 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2044 mp.setMappingChoice(mpc);
2050 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2051 List<UserColourScheme> userColours, JalviewModelSequence jms)
2054 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2055 boolean newucs = false;
2056 if (!userColours.contains(ucs))
2058 userColours.add(ucs);
2061 id = "ucs" + userColours.indexOf(ucs);
2064 // actually create the scheme's entry in the XML model
2065 java.awt.Color[] colours = ucs.getColours();
2066 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2067 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2069 for (int i = 0; i < colours.length; i++)
2071 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2072 col.setName(ResidueProperties.aa[i]);
2073 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2074 jbucs.addColour(col);
2076 if (ucs.getLowerCaseColours() != null)
2078 colours = ucs.getLowerCaseColours();
2079 for (int i = 0; i < colours.length; i++)
2081 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2082 col.setName(ResidueProperties.aa[i].toLowerCase());
2083 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2084 jbucs.addColour(col);
2089 uc.setUserColourScheme(jbucs);
2090 jms.addUserColours(uc);
2096 jalview.schemes.UserColourScheme getUserColourScheme(
2097 JalviewModelSequence jms, String id)
2099 UserColours[] uc = jms.getUserColours();
2100 UserColours colours = null;
2102 for (int i = 0; i < uc.length; i++)
2104 if (uc[i].getId().equals(id))
2112 java.awt.Color[] newColours = new java.awt.Color[24];
2114 for (int i = 0; i < 24; i++)
2116 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2117 .getUserColourScheme().getColour(i).getRGB(), 16));
2120 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2123 if (colours.getUserColourScheme().getColourCount() > 24)
2125 newColours = new java.awt.Color[23];
2126 for (int i = 0; i < 23; i++)
2128 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2129 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2131 ucs.setLowerCaseColours(newColours);
2138 * contains last error message (if any) encountered by XML loader.
2140 String errorMessage = null;
2143 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2144 * exceptions are raised during project XML parsing
2146 public boolean attemptversion1parse = true;
2149 * Load a jalview project archive from a jar file
2152 * - HTTP URL or filename
2154 public AlignFrame loadJalviewAlign(final String file)
2157 jalview.gui.AlignFrame af = null;
2161 // create list to store references for any new Jmol viewers created
2162 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2163 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2164 // Workaround is to make sure caller implements the JarInputStreamProvider
2166 // so we can re-open the jar input stream for each entry.
2168 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2169 af = loadJalviewAlign(jprovider);
2171 } catch (MalformedURLException e)
2173 errorMessage = "Invalid URL format for '" + file + "'";
2179 SwingUtilities.invokeAndWait(new Runnable()
2183 setLoadingFinishedForNewStructureViewers();
2186 } catch (Exception x)
2188 System.err.println("Error loading alignment: " + x.getMessage());
2194 private jarInputStreamProvider createjarInputStreamProvider(
2195 final String file) throws MalformedURLException
2198 errorMessage = null;
2199 uniqueSetSuffix = null;
2201 viewportsAdded.clear();
2202 frefedSequence = null;
2204 if (file.startsWith("http://"))
2206 url = new URL(file);
2208 final URL _url = url;
2209 return new jarInputStreamProvider()
2213 public JarInputStream getJarInputStream() throws IOException
2217 return new JarInputStream(_url.openStream());
2221 return new JarInputStream(new FileInputStream(file));
2226 public String getFilename()
2234 * Recover jalview session from a jalview project archive. Caller may
2235 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2236 * themselves. Any null fields will be initialised with default values,
2237 * non-null fields are left alone.
2242 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2244 errorMessage = null;
2245 if (uniqueSetSuffix == null)
2247 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2249 if (seqRefIds == null)
2251 seqRefIds = new HashMap<String, SequenceI>();
2253 if (frefedSequence == null)
2255 frefedSequence = new Vector();
2258 AlignFrame af = null, _af = null;
2259 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2260 final String file = jprovider.getFilename();
2263 JarInputStream jin = null;
2264 JarEntry jarentry = null;
2269 jin = jprovider.getJarInputStream();
2270 for (int i = 0; i < entryCount; i++)
2272 jarentry = jin.getNextJarEntry();
2275 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2277 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2278 JalviewModel object = new JalviewModel();
2280 Unmarshaller unmar = new Unmarshaller(object);
2281 unmar.setValidation(false);
2282 object = (JalviewModel) unmar.unmarshal(in);
2283 if (true) // !skipViewport(object))
2285 _af = loadFromObject(object, file, true, jprovider);
2286 if (object.getJalviewModelSequence().getViewportCount() > 0)
2289 if (af.viewport.isGatherViewsHere())
2291 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2297 else if (jarentry != null)
2299 // Some other file here.
2302 } while (jarentry != null);
2303 resolveFrefedSequences();
2304 } catch (IOException ex)
2306 ex.printStackTrace();
2307 errorMessage = "Couldn't locate Jalview XML file : " + file;
2308 System.err.println("Exception whilst loading jalview XML file : "
2310 } catch (Exception ex)
2312 System.err.println("Parsing as Jalview Version 2 file failed.");
2313 ex.printStackTrace(System.err);
2314 if (attemptversion1parse)
2316 // Is Version 1 Jar file?
2319 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2320 } catch (Exception ex2)
2322 System.err.println("Exception whilst loading as jalviewXMLV1:");
2323 ex2.printStackTrace();
2327 if (Desktop.instance != null)
2329 Desktop.instance.stopLoading();
2333 System.out.println("Successfully loaded archive file");
2336 ex.printStackTrace();
2338 System.err.println("Exception whilst loading jalview XML file : "
2340 } catch (OutOfMemoryError e)
2342 // Don't use the OOM Window here
2343 errorMessage = "Out of memory loading jalview XML file";
2344 System.err.println("Out of memory whilst loading jalview XML file");
2345 e.printStackTrace();
2348 if (Desktop.instance != null)
2350 Desktop.instance.stopLoading();
2354 * Regather multiple views (with the same sequence set id) to the frame (if
2355 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2356 * views instead of separate frames. Note this doesn't restore a state where
2357 * some expanded views in turn have tabbed views - the last "first tab" read
2358 * in will play the role of gatherer for all.
2360 for (AlignFrame fr : gatherToThisFrame.values())
2362 Desktop.instance.gatherViews(fr);
2365 restoreSplitFrames();
2367 if (errorMessage != null)
2375 * Try to reconstruct and display SplitFrame windows, where each contains
2376 * complementary dna and protein alignments. Done by pairing up AlignFrame
2377 * objects (created earlier) which have complementary viewport ids associated.
2379 protected void restoreSplitFrames()
2381 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2382 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2383 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2386 * Identify the DNA alignments
2388 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2391 AlignFrame af = candidate.getValue();
2392 if (af.getViewport().getAlignment().isNucleotide())
2394 dna.put(candidate.getKey().getId(), af);
2399 * Try to match up the protein complements
2401 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2404 AlignFrame af = candidate.getValue();
2405 if (!af.getViewport().getAlignment().isNucleotide())
2407 String complementId = candidate.getKey().getComplementId();
2408 // only non-null complements should be in the Map
2409 if (complementId != null && dna.containsKey(complementId))
2411 final AlignFrame dnaFrame = dna.get(complementId);
2412 SplitFrame sf = createSplitFrame(dnaFrame, af);
2413 addedToSplitFrames.add(dnaFrame);
2414 addedToSplitFrames.add(af);
2415 if (af.viewport.isGatherViewsHere())
2424 * Open any that we failed to pair up (which shouldn't happen!) as
2425 * standalone AlignFrame's.
2427 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2430 AlignFrame af = candidate.getValue();
2431 if (!addedToSplitFrames.contains(af))
2433 Viewport view = candidate.getKey();
2434 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2436 System.err.println("Failed to restore view " + view.getTitle()
2437 + " to split frame");
2442 * Gather back into tabbed views as flagged.
2444 for (SplitFrame sf : gatherTo)
2446 Desktop.instance.gatherViews(sf);
2449 splitFrameCandidates.clear();
2453 * Construct and display one SplitFrame holding DNA and protein alignments.
2456 * @param proteinFrame
2459 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2460 AlignFrame proteinFrame)
2462 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2463 String title = MessageManager.getString("label.linked_view_title");
2464 int width = (int) dnaFrame.getBounds().getWidth();
2465 int height = (int) (dnaFrame.getBounds().getHeight()
2466 + proteinFrame.getBounds().getHeight() + 50);
2469 * SplitFrame location is saved to both enclosed frames
2471 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2472 Desktop.addInternalFrame(splitFrame, title, width, height);
2475 * And compute cDNA consensus (couldn't do earlier with consensus as
2476 * mappings were not yet present)
2478 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2484 * check errorMessage for a valid error message and raise an error box in the
2485 * GUI or write the current errorMessage to stderr and then clear the error
2488 protected void reportErrors()
2490 reportErrors(false);
2493 protected void reportErrors(final boolean saving)
2495 if (errorMessage != null)
2497 final String finalErrorMessage = errorMessage;
2500 javax.swing.SwingUtilities.invokeLater(new Runnable()
2505 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2506 finalErrorMessage, "Error "
2507 + (saving ? "saving" : "loading")
2508 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2514 System.err.println("Problem loading Jalview file: " + errorMessage);
2517 errorMessage = null;
2520 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2523 * when set, local views will be updated from view stored in JalviewXML
2524 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2525 * sync if this is set to true.
2527 private final boolean updateLocalViews = false;
2530 * Returns the path to a temporary file holding the PDB file for the given PDB
2531 * id. The first time of asking, searches for a file of that name in the
2532 * Jalview project jar, and copies it to a new temporary file. Any repeat
2533 * requests just return the path to the file previously created.
2539 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2541 if (alreadyLoadedPDB.containsKey(pdbId))
2543 return alreadyLoadedPDB.get(pdbId).toString();
2546 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2547 if (tempFile != null)
2549 alreadyLoadedPDB.put(pdbId, tempFile);
2555 * Copies the jar entry of given name to a new temporary file and returns the
2556 * path to the file, or null if the entry is not found.
2559 * @param jarEntryName
2561 * a prefix for the temporary file name, must be at least three
2565 protected String copyJarEntry(jarInputStreamProvider jprovider,
2566 String jarEntryName, String prefix)
2568 BufferedReader in = null;
2569 PrintWriter out = null;
2573 JarInputStream jin = jprovider.getJarInputStream();
2575 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2576 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2577 * FileInputStream(jprovider)); }
2580 JarEntry entry = null;
2583 entry = jin.getNextJarEntry();
2584 } while (entry != null && !entry.getName().equals(jarEntryName));
2587 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2588 File outFile = File.createTempFile(prefix, ".tmp");
2589 outFile.deleteOnExit();
2590 out = new PrintWriter(new FileOutputStream(outFile));
2593 while ((data = in.readLine()) != null)
2598 String t = outFile.getAbsolutePath();
2603 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2605 } catch (Exception ex)
2607 ex.printStackTrace();
2615 } catch (IOException e)
2629 private class JvAnnotRow
2631 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2638 * persisted version of annotation row from which to take vis properties
2640 public jalview.datamodel.AlignmentAnnotation template;
2643 * original position of the annotation row in the alignment
2649 * Load alignment frame from jalview XML DOM object
2654 * filename source string
2655 * @param loadTreesAndStructures
2656 * when false only create Viewport
2658 * data source provider
2659 * @return alignment frame created from view stored in DOM
2661 AlignFrame loadFromObject(JalviewModel object, String file,
2662 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2664 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2665 Sequence[] vamsasSeq = vamsasSet.getSequence();
2667 JalviewModelSequence jms = object.getJalviewModelSequence();
2669 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2672 // ////////////////////////////////
2675 List<SequenceI> hiddenSeqs = null;
2676 jalview.datamodel.Sequence jseq;
2678 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2680 boolean multipleView = false;
2682 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2683 int vi = 0; // counter in vamsasSeq array
2684 for (int i = 0; i < jseqs.length; i++)
2686 String seqId = jseqs[i].getId();
2688 if (seqRefIds.get(seqId) != null)
2690 tmpseqs.add(seqRefIds.get(seqId));
2691 multipleView = true;
2695 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2696 vamsasSeq[vi].getSequence());
2697 jseq.setDescription(vamsasSeq[vi].getDescription());
2698 jseq.setStart(jseqs[i].getStart());
2699 jseq.setEnd(jseqs[i].getEnd());
2700 jseq.setVamsasId(uniqueSetSuffix + seqId);
2701 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2706 if (jseqs[i].getHidden())
2708 if (hiddenSeqs == null)
2710 hiddenSeqs = new ArrayList<SequenceI>();
2713 hiddenSeqs.add(seqRefIds.get(seqId));
2719 // Create the alignment object from the sequence set
2720 // ///////////////////////////////
2721 SequenceI[] orderedSeqs = tmpseqs
2722 .toArray(new SequenceI[tmpseqs.size()]);
2724 Alignment al = new Alignment(orderedSeqs);
2726 // / Add the alignment properties
2727 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2729 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2730 al.setProperty(ssp.getKey(), ssp.getValue());
2734 // SequenceFeatures are added to the DatasetSequence,
2735 // so we must create or recover the dataset before loading features
2736 // ///////////////////////////////
2737 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2739 // older jalview projects do not have a dataset id.
2740 al.setDataset(null);
2744 // recover dataset - passing on flag indicating if this a 'viewless'
2745 // sequence set (a.k.a. a stored dataset for the project)
2746 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2747 .getViewportCount() == 0);
2749 // ///////////////////////////////
2751 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2754 // load sequence features, database references and any associated PDB
2755 // structures for the alignment
2756 for (int i = 0; i < vamsasSeq.length; i++)
2758 if (jseqs[i].getFeaturesCount() > 0)
2760 Features[] features = jseqs[i].getFeatures();
2761 for (int f = 0; f < features.length; f++)
2763 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2764 features[f].getType(), features[f].getDescription(),
2765 features[f].getStatus(), features[f].getBegin(),
2766 features[f].getEnd(), features[f].getFeatureGroup());
2768 sf.setScore(features[f].getScore());
2769 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2771 OtherData keyValue = features[f].getOtherData(od);
2772 if (keyValue.getKey().startsWith("LINK"))
2774 sf.addLink(keyValue.getValue());
2778 sf.setValue(keyValue.getKey(), keyValue.getValue());
2783 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2786 if (vamsasSeq[i].getDBRefCount() > 0)
2788 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2790 if (jseqs[i].getPdbidsCount() > 0)
2792 Pdbids[] ids = jseqs[i].getPdbids();
2793 for (int p = 0; p < ids.length; p++)
2795 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2796 entry.setId(ids[p].getId());
2797 if (ids[p].getType() != null)
2799 if (ids[p].getType().equalsIgnoreCase("PDB"))
2801 entry.setType(PDBEntry.Type.PDB);
2805 entry.setType(PDBEntry.Type.FILE);
2808 if (ids[p].getFile() != null)
2810 if (!pdbloaded.containsKey(ids[p].getFile()))
2812 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2816 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2819 StructureSelectionManager.getStructureSelectionManager(
2820 Desktop.instance).registerPDBEntry(entry);
2821 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2825 } // end !multipleview
2827 // ///////////////////////////////
2828 // LOAD SEQUENCE MAPPINGS
2830 if (vamsasSet.getAlcodonFrameCount() > 0)
2832 // TODO Potentially this should only be done once for all views of an
2834 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2835 for (int i = 0; i < alc.length; i++)
2837 AlignedCodonFrame cf = new AlignedCodonFrame();
2838 if (alc[i].getAlcodMapCount() > 0)
2840 AlcodMap[] maps = alc[i].getAlcodMap();
2841 for (int m = 0; m < maps.length; m++)
2843 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2845 jalview.datamodel.Mapping mapping = null;
2846 // attach to dna sequence reference.
2847 if (maps[m].getMapping() != null)
2849 mapping = addMapping(maps[m].getMapping());
2853 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2858 frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
2863 al.addCodonFrame(cf);
2867 // ////////////////////////////////
2869 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2872 * store any annotations which forward reference a group's ID
2874 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2876 if (vamsasSet.getAnnotationCount() > 0)
2878 Annotation[] an = vamsasSet.getAnnotation();
2880 for (int i = 0; i < an.length; i++)
2882 Annotation annotation = an[i];
2885 * test if annotation is automatically calculated for this view only
2887 boolean autoForView = false;
2888 if (annotation.getLabel().equals("Quality")
2889 || annotation.getLabel().equals("Conservation")
2890 || annotation.getLabel().equals("Consensus"))
2892 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2894 if (!annotation.hasAutoCalculated())
2896 annotation.setAutoCalculated(true);
2900 || (annotation.hasAutoCalculated() && annotation
2901 .isAutoCalculated()))
2903 // remove ID - we don't recover annotation from other views for
2904 // view-specific annotation
2905 annotation.setId(null);
2908 // set visiblity for other annotation in this view
2909 String annotationId = annotation.getId();
2910 if (annotationId != null && annotationIds.containsKey(annotationId))
2912 AlignmentAnnotation jda = annotationIds.get(annotationId);
2913 // in principle Visible should always be true for annotation displayed
2914 // in multiple views
2915 if (annotation.hasVisible())
2917 jda.visible = annotation.getVisible();
2920 al.addAnnotation(jda);
2924 // Construct new annotation from model.
2925 AnnotationElement[] ae = annotation.getAnnotationElement();
2926 jalview.datamodel.Annotation[] anot = null;
2927 java.awt.Color firstColour = null;
2929 if (!annotation.getScoreOnly())
2931 anot = new jalview.datamodel.Annotation[al.getWidth()];
2932 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2934 anpos = ae[aa].getPosition();
2936 if (anpos >= anot.length)
2941 anot[anpos] = new jalview.datamodel.Annotation(
2943 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2944 (ae[aa].getSecondaryStructure() == null || ae[aa]
2945 .getSecondaryStructure().length() == 0) ? ' '
2946 : ae[aa].getSecondaryStructure().charAt(0),
2950 // JBPNote: Consider verifying dataflow for IO of secondary
2951 // structure annotation read from Stockholm files
2952 // this was added to try to ensure that
2953 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2955 // anot[ae[aa].getPosition()].displayCharacter = "";
2957 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2958 if (firstColour == null)
2960 firstColour = anot[anpos].colour;
2964 jalview.datamodel.AlignmentAnnotation jaa = null;
2966 if (annotation.getGraph())
2968 float llim = 0, hlim = 0;
2969 // if (autoForView || an[i].isAutoCalculated()) {
2972 jaa = new jalview.datamodel.AlignmentAnnotation(
2973 annotation.getLabel(), annotation.getDescription(), anot,
2974 llim, hlim, annotation.getGraphType());
2976 jaa.graphGroup = annotation.getGraphGroup();
2977 jaa._linecolour = firstColour;
2978 if (annotation.getThresholdLine() != null)
2980 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
2981 .getThresholdLine().getValue(), annotation
2982 .getThresholdLine().getLabel(), new java.awt.Color(
2983 annotation.getThresholdLine().getColour())));
2986 if (autoForView || annotation.isAutoCalculated())
2988 // Hardwire the symbol display line to ensure that labels for
2989 // histograms are displayed
2995 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2996 an[i].getDescription(), anot);
2997 jaa._linecolour = firstColour;
2999 // register new annotation
3000 if (an[i].getId() != null)
3002 annotationIds.put(an[i].getId(), jaa);
3003 jaa.annotationId = an[i].getId();
3005 // recover sequence association
3006 String sequenceRef = an[i].getSequenceRef();
3007 if (sequenceRef != null)
3009 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3010 SequenceI sequence = seqRefIds.get(sequenceRef);
3011 if (sequence == null)
3013 // in pre-2.9 projects sequence ref is to sequence name
3014 sequence = al.findName(sequenceRef);
3016 if (sequence != null)
3018 jaa.createSequenceMapping(sequence, 1, true);
3019 sequence.addAlignmentAnnotation(jaa);
3022 // and make a note of any group association
3023 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3025 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3026 .get(an[i].getGroupRef());
3029 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3030 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3035 if (an[i].hasScore())
3037 jaa.setScore(an[i].getScore());
3039 if (an[i].hasVisible())
3041 jaa.visible = an[i].getVisible();
3044 if (an[i].hasCentreColLabels())
3046 jaa.centreColLabels = an[i].getCentreColLabels();
3049 if (an[i].hasScaleColLabels())
3051 jaa.scaleColLabel = an[i].getScaleColLabels();
3053 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3055 // newer files have an 'autoCalculated' flag and store calculation
3056 // state in viewport properties
3057 jaa.autoCalculated = true; // means annotation will be marked for
3058 // update at end of load.
3060 if (an[i].hasGraphHeight())
3062 jaa.graphHeight = an[i].getGraphHeight();
3064 if (an[i].hasBelowAlignment())
3066 jaa.belowAlignment = an[i].isBelowAlignment();
3068 jaa.setCalcId(an[i].getCalcId());
3069 if (an[i].getPropertyCount() > 0)
3071 for (jalview.schemabinding.version2.Property prop : an[i]
3074 jaa.setProperty(prop.getName(), prop.getValue());
3077 if (jaa.autoCalculated)
3079 autoAlan.add(new JvAnnotRow(i, jaa));
3082 // if (!autoForView)
3084 // add autocalculated group annotation and any user created annotation
3086 al.addAnnotation(jaa);
3090 // ///////////////////////
3092 // Create alignment markup and styles for this view
3093 if (jms.getJGroupCount() > 0)
3095 JGroup[] groups = jms.getJGroup();
3096 boolean addAnnotSchemeGroup = false;
3097 for (int i = 0; i < groups.length; i++)
3099 JGroup jGroup = groups[i];
3100 ColourSchemeI cs = null;
3101 if (jGroup.getColour() != null)
3103 if (jGroup.getColour().startsWith("ucs"))
3105 cs = getUserColourScheme(jms, jGroup.getColour());
3107 else if (jGroup.getColour().equals("AnnotationColourGradient")
3108 && jGroup.getAnnotationColours() != null)
3110 addAnnotSchemeGroup = true;
3115 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3120 cs.setThreshold(jGroup.getPidThreshold(), true);
3124 Vector<SequenceI> seqs = new Vector<SequenceI>();
3126 for (int s = 0; s < jGroup.getSeqCount(); s++)
3128 String seqId = jGroup.getSeq(s) + "";
3129 SequenceI ts = seqRefIds.get(seqId);
3133 seqs.addElement(ts);
3137 if (seqs.size() < 1)
3142 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3143 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3144 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3146 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3148 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3149 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3150 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3151 .isShowUnconserved() : false);
3152 sg.thresholdTextColour = jGroup.getTextColThreshold();
3153 if (jGroup.hasShowConsensusHistogram())
3155 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3158 if (jGroup.hasShowSequenceLogo())
3160 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3162 if (jGroup.hasNormaliseSequenceLogo())
3164 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3166 if (jGroup.hasIgnoreGapsinConsensus())
3168 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3170 if (jGroup.getConsThreshold() != 0)
3172 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3173 "All", ResidueProperties.propHash, 3,
3174 sg.getSequences(null), 0, sg.getWidth() - 1);
3176 c.verdict(false, 25);
3177 sg.cs.setConservation(c);
3180 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3182 // re-instate unique group/annotation row reference
3183 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3187 for (AlignmentAnnotation jaa : jaal)
3190 if (jaa.autoCalculated)
3192 // match up and try to set group autocalc alignment row for this
3194 if (jaa.label.startsWith("Consensus for "))
3196 sg.setConsensus(jaa);
3198 // match up and try to set group autocalc alignment row for this
3200 if (jaa.label.startsWith("Conservation for "))
3202 sg.setConservationRow(jaa);
3209 if (addAnnotSchemeGroup)
3211 // reconstruct the annotation colourscheme
3212 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3213 null, al, jms, false);
3219 // only dataset in this model, so just return.
3222 // ///////////////////////////////
3225 // If we just load in the same jar file again, the sequenceSetId
3226 // will be the same, and we end up with multiple references
3227 // to the same sequenceSet. We must modify this id on load
3228 // so that each load of the file gives a unique id
3229 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3230 String viewId = (view.getId() == null ? null : view.getId()
3232 AlignFrame af = null;
3233 AlignViewport av = null;
3234 // now check to see if we really need to create a new viewport.
3235 if (multipleView && viewportsAdded.size() == 0)
3237 // We recovered an alignment for which a viewport already exists.
3238 // TODO: fix up any settings necessary for overlaying stored state onto
3239 // state recovered from another document. (may not be necessary).
3240 // we may need a binding from a viewport in memory to one recovered from
3242 // and then recover its containing af to allow the settings to be applied.
3243 // TODO: fix for vamsas demo
3245 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3247 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3248 if (seqsetobj != null)
3250 if (seqsetobj instanceof String)
3252 uniqueSeqSetId = (String) seqsetobj;
3254 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3260 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3266 * indicate that annotation colours are applied across all groups (pre
3267 * Jalview 2.8.1 behaviour)
3269 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3270 "2.8.1", object.getVersion());
3272 AlignmentPanel ap = null;
3273 boolean isnewview = true;
3276 // Check to see if this alignment already has a view id == viewId
3277 jalview.gui.AlignmentPanel views[] = Desktop
3278 .getAlignmentPanels(uniqueSeqSetId);
3279 if (views != null && views.length > 0)
3281 for (int v = 0; v < views.length; v++)
3283 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3285 // recover the existing alignpanel, alignframe, viewport
3286 af = views[v].alignFrame;
3289 // TODO: could even skip resetting view settings if we don't want to
3290 // change the local settings from other jalview processes
3299 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3300 uniqueSeqSetId, viewId, autoAlan);
3306 * Load any trees, PDB structures and viewers
3308 * Not done if flag is false (when this method is used for New View)
3310 if (loadTreesAndStructures)
3312 loadTrees(jms, view, af, av, ap);
3313 loadPDBStructures(jprovider, jseqs, af, ap);
3314 loadRnaViewers(jprovider, jseqs, ap);
3316 // and finally return.
3321 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3322 * panel is restored from separate jar entries, two (gapped and trimmed) per
3323 * sequence and secondary structure.
3325 * Currently each viewer shows just one sequence and structure (gapped and
3326 * trimmed), however this method is designed to support multiple sequences or
3327 * structures in viewers if wanted in future.
3333 private void loadRnaViewers(jarInputStreamProvider jprovider,
3334 JSeq[] jseqs, AlignmentPanel ap)
3337 * scan the sequences for references to viewers; create each one the first
3338 * time it is referenced, add Rna models to existing viewers
3340 for (JSeq jseq : jseqs)
3342 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3344 RnaViewer viewer = jseq.getRnaViewer(i);
3345 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3346 uniqueSetSuffix, ap);
3348 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3350 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3351 SequenceI seq = seqRefIds.get(jseq.getId());
3352 AlignmentAnnotation ann = this.annotationIds.get(ss
3353 .getAnnotationId());
3356 * add the structure to the Varna display (with session state copied
3357 * from the jar to a temporary file)
3359 boolean gapped = ss.isGapped();
3360 String rnaTitle = ss.getTitle();
3361 String sessionState = ss.getViewerState();
3362 String tempStateFile = copyJarEntry(jprovider, sessionState,
3364 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3365 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3367 appVarna.setInitialSelection(viewer.getSelectedRna());
3373 * Locate and return an already instantiated matching AppVarna, or create one
3377 * @param viewIdSuffix
3381 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3382 String viewIdSuffix, AlignmentPanel ap)
3385 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3386 * if load is repeated
3388 String postLoadId = viewer.getViewId() + viewIdSuffix;
3389 for (JInternalFrame frame : getAllFrames())
3391 if (frame instanceof AppVarna)
3393 AppVarna varna = (AppVarna) frame;
3394 if (postLoadId.equals(varna.getViewId()))
3396 // this viewer is already instantiated
3397 // could in future here add ap as another 'parent' of the
3398 // AppVarna window; currently just 1-to-many
3405 * viewer not found - make it
3407 RnaViewerModel model = new RnaViewerModel(postLoadId,
3408 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3409 viewer.getWidth(), viewer.getHeight(),
3410 viewer.getDividerLocation());
3411 AppVarna varna = new AppVarna(model, ap);
3417 * Load any saved trees
3425 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3426 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3428 // TODO result of automated refactoring - are all these parameters needed?
3431 for (int t = 0; t < jms.getTreeCount(); t++)
3434 Tree tree = jms.getTree(t);
3436 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3439 tp = af.ShowNewickTree(
3440 new jalview.io.NewickFile(tree.getNewick()),
3441 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3442 tree.getXpos(), tree.getYpos());
3443 if (tree.getId() != null)
3445 // perhaps bind the tree id to something ?
3450 // update local tree attributes ?
3451 // TODO: should check if tp has been manipulated by user - if so its
3452 // settings shouldn't be modified
3453 tp.setTitle(tree.getTitle());
3454 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3455 .getWidth(), tree.getHeight()));
3456 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3459 tp.treeCanvas.av = av; // af.viewport;
3460 tp.treeCanvas.ap = ap; // af.alignPanel;
3465 warn("There was a problem recovering stored Newick tree: \n"
3466 + tree.getNewick());
3470 tp.fitToWindow.setState(tree.getFitToWindow());
3471 tp.fitToWindow_actionPerformed(null);
3473 if (tree.getFontName() != null)
3475 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3476 .getFontStyle(), tree.getFontSize()));
3480 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3481 .getFontStyle(), tree.getFontSize()));
3484 tp.showPlaceholders(tree.getMarkUnlinked());
3485 tp.showBootstrap(tree.getShowBootstrap());
3486 tp.showDistances(tree.getShowDistances());
3488 tp.treeCanvas.threshold = tree.getThreshold();
3490 if (tree.getCurrentTree())
3492 af.viewport.setCurrentTree(tp.getTree());
3496 } catch (Exception ex)
3498 ex.printStackTrace();
3503 * Load and link any saved structure viewers.
3510 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3511 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3514 * Run through all PDB ids on the alignment, and collect mappings between
3515 * distinct view ids and all sequences referring to that view.
3517 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3519 for (int i = 0; i < jseqs.length; i++)
3521 if (jseqs[i].getPdbidsCount() > 0)
3523 Pdbids[] ids = jseqs[i].getPdbids();
3524 for (int p = 0; p < ids.length; p++)
3526 final int structureStateCount = ids[p].getStructureStateCount();
3527 for (int s = 0; s < structureStateCount; s++)
3529 // check to see if we haven't already created this structure view
3530 final StructureState structureState = ids[p]
3531 .getStructureState(s);
3532 String sviewid = (structureState.getViewId() == null) ? null
3533 : structureState.getViewId() + uniqueSetSuffix;
3534 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3535 // Originally : ids[p].getFile()
3536 // : TODO: verify external PDB file recovery still works in normal
3537 // jalview project load
3538 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3539 jpdb.setId(ids[p].getId());
3541 int x = structureState.getXpos();
3542 int y = structureState.getYpos();
3543 int width = structureState.getWidth();
3544 int height = structureState.getHeight();
3546 // Probably don't need to do this anymore...
3547 // Desktop.desktop.getComponentAt(x, y);
3548 // TODO: NOW: check that this recovers the PDB file correctly.
3549 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3550 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3552 if (sviewid == null)
3554 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3557 if (!structureViewers.containsKey(sviewid))
3559 structureViewers.put(sviewid,
3560 new StructureViewerModel(x, y, width, height, false,
3561 false, true, structureState.getViewId(),
3562 structureState.getType()));
3563 // Legacy pre-2.7 conversion JAL-823 :
3564 // do not assume any view has to be linked for colour by
3568 // assemble String[] { pdb files }, String[] { id for each
3569 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3570 // seqs_file 2}, boolean[] {
3571 // linkAlignPanel,superposeWithAlignpanel}} from hash
3572 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3573 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3574 | (structureState.hasAlignwithAlignPanel() ? structureState
3575 .getAlignwithAlignPanel() : false));
3578 * Default colour by linked panel to false if not specified (e.g.
3579 * for pre-2.7 projects)
3581 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3582 colourWithAlignPanel |= (structureState
3583 .hasColourwithAlignPanel() ? structureState
3584 .getColourwithAlignPanel() : false);
3585 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3588 * Default colour by viewer to true if not specified (e.g. for
3591 boolean colourByViewer = jmoldat.isColourByViewer();
3592 colourByViewer &= structureState.hasColourByJmol() ? structureState
3593 .getColourByJmol() : true;
3594 jmoldat.setColourByViewer(colourByViewer);
3596 if (jmoldat.getStateData().length() < structureState
3597 .getContent().length())
3600 jmoldat.setStateData(structureState.getContent());
3603 if (ids[p].getFile() != null)
3605 File mapkey = new File(ids[p].getFile());
3606 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3607 if (seqstrmaps == null)
3609 jmoldat.getFileData().put(
3611 seqstrmaps = jmoldat.new StructureData(pdbFile,
3614 if (!seqstrmaps.getSeqList().contains(seq))
3616 seqstrmaps.getSeqList().add(seq);
3622 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");
3629 // Instantiate the associated structure views
3630 for (Entry<String, StructureViewerModel> entry : structureViewers
3635 createOrLinkStructureViewer(entry, af, ap, jprovider);
3636 } catch (Exception e)
3638 System.err.println("Error loading structure viewer: "
3640 // failed - try the next one
3652 protected void createOrLinkStructureViewer(
3653 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3654 AlignmentPanel ap, jarInputStreamProvider jprovider)
3656 final StructureViewerModel stateData = viewerData.getValue();
3659 * Search for any viewer windows already open from other alignment views
3660 * that exactly match the stored structure state
3662 StructureViewerBase comp = findMatchingViewer(viewerData);
3666 linkStructureViewer(ap, comp, stateData);
3671 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3672 * "viewer_"+stateData.viewId
3674 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3676 createChimeraViewer(viewerData, af, jprovider);
3681 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3683 createJmolViewer(viewerData, af, jprovider);
3688 * Create a new Chimera viewer.
3694 protected void createChimeraViewer(
3695 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3696 jarInputStreamProvider jprovider)
3698 StructureViewerModel data = viewerData.getValue();
3699 String chimeraSessionFile = data.getStateData();
3702 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3704 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3705 * 'uniquified' sviewid used to reconstruct the viewer here
3707 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3708 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3711 Set<Entry<File, StructureData>> fileData = data.getFileData()
3713 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3714 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3715 for (Entry<File, StructureData> pdb : fileData)
3717 String filePath = pdb.getValue().getFilePath();
3718 String pdbId = pdb.getValue().getPdbId();
3719 // pdbs.add(new PDBEntry(filePath, pdbId));
3720 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3721 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3722 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3726 boolean colourByChimera = data.isColourByViewer();
3727 boolean colourBySequence = data.isColourWithAlignPanel();
3729 // TODO use StructureViewer as a factory here, see JAL-1761
3730 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3731 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3733 String newViewId = viewerData.getKey();
3735 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3736 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3737 colourBySequence, newViewId);
3738 cvf.setSize(data.getWidth(), data.getHeight());
3739 cvf.setLocation(data.getX(), data.getY());
3743 * Create a new Jmol window. First parse the Jmol state to translate filenames
3744 * loaded into the view, and record the order in which files are shown in the
3745 * Jmol view, so we can add the sequence mappings in same order.
3751 protected void createJmolViewer(
3752 final Entry<String, StructureViewerModel> viewerData,
3753 AlignFrame af, jarInputStreamProvider jprovider)
3755 final StructureViewerModel svattrib = viewerData.getValue();
3756 String state = svattrib.getStateData();
3759 * Pre-2.9: state element value is the Jmol state string
3761 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3764 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3766 state = readJarEntry(jprovider,
3767 getViewerJarEntryName(svattrib.getViewId()));
3770 List<String> pdbfilenames = new ArrayList<String>();
3771 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3772 List<String> pdbids = new ArrayList<String>();
3773 StringBuilder newFileLoc = new StringBuilder(64);
3774 int cp = 0, ncp, ecp;
3775 Map<File, StructureData> oldFiles = svattrib.getFileData();
3776 while ((ncp = state.indexOf("load ", cp)) > -1)
3780 // look for next filename in load statement
3781 newFileLoc.append(state.substring(cp,
3782 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3783 String oldfilenam = state.substring(ncp,
3784 ecp = state.indexOf("\"", ncp));
3785 // recover the new mapping data for this old filename
3786 // have to normalize filename - since Jmol and jalview do
3788 // translation differently.
3789 StructureData filedat = oldFiles.get(new File(oldfilenam));
3790 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3791 pdbfilenames.add(filedat.getFilePath());
3792 pdbids.add(filedat.getPdbId());
3793 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3794 newFileLoc.append("\"");
3795 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3796 // look for next file statement.
3797 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3801 // just append rest of state
3802 newFileLoc.append(state.substring(cp));
3806 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3807 newFileLoc = new StringBuilder(state);
3808 newFileLoc.append("; load append ");
3809 for (File id : oldFiles.keySet())
3811 // add this and any other pdb files that should be present in
3813 StructureData filedat = oldFiles.get(id);
3814 newFileLoc.append(filedat.getFilePath());
3815 pdbfilenames.add(filedat.getFilePath());
3816 pdbids.add(filedat.getPdbId());
3817 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3818 newFileLoc.append(" \"");
3819 newFileLoc.append(filedat.getFilePath());
3820 newFileLoc.append("\"");
3823 newFileLoc.append(";");
3826 if (newFileLoc.length() == 0)
3830 int histbug = newFileLoc.indexOf("history = ");
3834 * change "history = [true|false];" to "history = [1|0];"
3837 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3838 String val = (diff == -1) ? null : newFileLoc
3839 .substring(histbug, diff);
3840 if (val != null && val.length() >= 4)
3842 if (val.contains("e")) // eh? what can it be?
3844 if (val.trim().equals("true"))
3852 newFileLoc.replace(histbug, diff, val);
3857 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3859 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3860 final SequenceI[][] sq = seqmaps
3861 .toArray(new SequenceI[seqmaps.size()][]);
3862 final String fileloc = newFileLoc.toString();
3863 final String sviewid = viewerData.getKey();
3864 final AlignFrame alf = af;
3865 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3866 svattrib.getWidth(), svattrib.getHeight());
3869 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3874 JalviewStructureDisplayI sview = null;
3877 sview = new StructureViewer(alf.alignPanel
3878 .getStructureSelectionManager()).createView(
3879 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3880 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3881 addNewStructureViewer(sview);
3882 } catch (OutOfMemoryError ex)
3884 new OOMWarning("restoring structure view for PDB id " + id,
3885 (OutOfMemoryError) ex.getCause());
3886 if (sview != null && sview.isVisible())
3888 sview.closeViewer(false);
3889 sview.setVisible(false);
3895 } catch (InvocationTargetException ex)
3897 warn("Unexpected error when opening Jmol view.", ex);
3899 } catch (InterruptedException e)
3901 // e.printStackTrace();
3907 * Generates a name for the entry in the project jar file to hold state
3908 * information for a structure viewer
3913 protected String getViewerJarEntryName(String viewId)
3915 return VIEWER_PREFIX + viewId;
3919 * Returns any open frame that matches given structure viewer data. The match
3920 * is based on the unique viewId, or (for older project versions) the frame's
3926 protected StructureViewerBase findMatchingViewer(
3927 Entry<String, StructureViewerModel> viewerData)
3929 final String sviewid = viewerData.getKey();
3930 final StructureViewerModel svattrib = viewerData.getValue();
3931 StructureViewerBase comp = null;
3932 JInternalFrame[] frames = getAllFrames();
3933 for (JInternalFrame frame : frames)
3935 if (frame instanceof StructureViewerBase)
3938 * Post jalview 2.4 schema includes structure view id
3941 && ((StructureViewerBase) frame).getViewId()
3944 comp = (StructureViewerBase) frame;
3945 break; // break added in 2.9
3948 * Otherwise test for matching position and size of viewer frame
3950 else if (frame.getX() == svattrib.getX()
3951 && frame.getY() == svattrib.getY()
3952 && frame.getHeight() == svattrib.getHeight()
3953 && frame.getWidth() == svattrib.getWidth())
3955 comp = (StructureViewerBase) frame;
3956 // no break in faint hope of an exact match on viewId
3964 * Link an AlignmentPanel to an existing structure viewer.
3969 * @param useinViewerSuperpos
3970 * @param usetoColourbyseq
3971 * @param viewerColouring
3973 protected void linkStructureViewer(AlignmentPanel ap,
3974 StructureViewerBase viewer, StructureViewerModel stateData)
3976 // NOTE: if the jalview project is part of a shared session then
3977 // view synchronization should/could be done here.
3979 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
3980 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
3981 final boolean viewerColouring = stateData.isColourByViewer();
3982 Map<File, StructureData> oldFiles = stateData.getFileData();
3985 * Add mapping for sequences in this view to an already open viewer
3987 final AAStructureBindingModel binding = viewer.getBinding();
3988 for (File id : oldFiles.keySet())
3990 // add this and any other pdb files that should be present in the
3992 StructureData filedat = oldFiles.get(id);
3993 String pdbFile = filedat.getFilePath();
3994 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3995 binding.getSsm().setMapping(seq, null, pdbFile,
3996 jalview.io.AppletFormatAdapter.FILE);
3997 binding.addSequenceForStructFile(pdbFile, seq);
3999 // and add the AlignmentPanel's reference to the view panel
4000 viewer.addAlignmentPanel(ap);
4001 if (useinViewerSuperpos)
4003 viewer.useAlignmentPanelForSuperposition(ap);
4007 viewer.excludeAlignmentPanelForSuperposition(ap);
4009 if (usetoColourbyseq)
4011 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4015 viewer.excludeAlignmentPanelForColourbyseq(ap);
4020 * Get all frames within the Desktop.
4024 protected JInternalFrame[] getAllFrames()
4026 JInternalFrame[] frames = null;
4027 // TODO is this necessary - is it safe - risk of hanging?
4032 frames = Desktop.desktop.getAllFrames();
4033 } catch (ArrayIndexOutOfBoundsException e)
4035 // occasional No such child exceptions are thrown here...
4039 } catch (InterruptedException f)
4043 } while (frames == null);
4050 * - minimum version we are comparing against
4052 * - version of data being processsed.
4053 * @return true if version is development/null or evaluates to the same or
4054 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
4056 public static boolean isVersionStringLaterThan(String supported,
4059 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4060 || version.equalsIgnoreCase("Test")
4061 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4063 System.err.println("Assuming project file with "
4064 + (version == null ? "null" : version)
4065 + " is compatible with Jalview version " + supported);
4070 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
4072 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
4074 // convert b to decimal to catch bugfix releases within a series
4075 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
4076 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
4079 float supportedVersionToken = Float.parseFloat(curT);
4080 float myVersiontoken = Float.parseFloat(fileT);
4081 if (supportedVersionToken > myVersiontoken)
4083 // current version is newer than the version that wrote the file
4086 if (supportedVersionToken < myVersiontoken)
4088 // current version is older than the version that wrote the file
4091 } catch (NumberFormatException nfe)
4094 .println("** WARNING: Version comparison failed for tokens ("
4098 + ")\n** Current: '"
4099 + supported + "' and Version: '" + version + "'");
4102 if (currentV.hasMoreElements())
4104 // fileV has no minor version but identical series to current
4111 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4113 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4115 if (newStructureViewers != null)
4117 sview.getBinding().setFinishedLoadingFromArchive(false);
4118 newStructureViewers.add(sview);
4122 protected void setLoadingFinishedForNewStructureViewers()
4124 if (newStructureViewers != null)
4126 for (JalviewStructureDisplayI sview : newStructureViewers)
4128 sview.getBinding().setFinishedLoadingFromArchive(true);
4130 newStructureViewers.clear();
4131 newStructureViewers = null;
4135 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4136 List<SequenceI> hiddenSeqs, Alignment al,
4137 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4138 String viewId, List<JvAnnotRow> autoAlan)
4140 AlignFrame af = null;
4141 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4142 uniqueSeqSetId, viewId);
4144 af.setFileName(file, "Jalview");
4146 for (int i = 0; i < JSEQ.length; i++)
4148 af.viewport.setSequenceColour(af.viewport.getAlignment()
4149 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4152 af.viewport.setGatherViewsHere(view.getGatheredViews());
4154 if (view.getSequenceSetId() != null)
4156 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4158 af.viewport.setSequenceSetId(uniqueSeqSetId);
4161 // propagate shared settings to this new view
4162 af.viewport.setHistoryList(av.getHistoryList());
4163 af.viewport.setRedoList(av.getRedoList());
4167 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4169 // TODO: check if this method can be called repeatedly without
4170 // side-effects if alignpanel already registered.
4171 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4173 // apply Hidden regions to view.
4174 if (hiddenSeqs != null)
4176 for (int s = 0; s < JSEQ.length; s++)
4178 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
4180 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4183 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
4185 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
4188 // jalview.datamodel.SequenceI[] hseqs = new
4189 // jalview.datamodel.SequenceI[hiddenSeqs
4192 // for (int s = 0; s < hiddenSeqs.size(); s++)
4194 // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
4197 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4199 af.viewport.hideSequence(hseqs);
4202 // recover view properties and display parameters
4203 if (view.getViewName() != null)
4205 af.viewport.viewName = view.getViewName();
4206 af.setInitialTabVisible();
4208 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4211 af.viewport.setShowAnnotation(view.getShowAnnotation());
4212 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4214 af.viewport.setColourText(view.getShowColourText());
4216 af.viewport.setConservationSelected(view.getConservationSelected());
4217 af.viewport.setShowJVSuffix(view.getShowFullId());
4218 af.viewport.setRightAlignIds(view.getRightAlignIds());
4219 af.viewport.setFont(
4220 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4221 .getFontSize()), true);
4222 ViewStyleI vs = af.viewport.getViewStyle();
4223 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4224 af.viewport.setViewStyle(vs);
4225 // TODO: allow custom charWidth/Heights to be restored by updating them
4226 // after setting font - which means set above to false
4227 af.viewport.setRenderGaps(view.getRenderGaps());
4228 af.viewport.setWrapAlignment(view.getWrapAlignment());
4229 af.viewport.setShowAnnotation(view.getShowAnnotation());
4231 af.viewport.setShowBoxes(view.getShowBoxes());
4233 af.viewport.setShowText(view.getShowText());
4235 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4236 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4237 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4238 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4239 .isShowUnconserved() : false);
4240 af.viewport.setStartRes(view.getStartRes());
4241 af.viewport.setStartSeq(view.getStartSeq());
4242 af.alignPanel.updateLayout();
4243 ColourSchemeI cs = null;
4244 // apply colourschemes
4245 if (view.getBgColour() != null)
4247 if (view.getBgColour().startsWith("ucs"))
4249 cs = getUserColourScheme(jms, view.getBgColour());
4251 else if (view.getBgColour().startsWith("Annotation"))
4253 AnnotationColours viewAnnColour = view.getAnnotationColours();
4254 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4261 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4266 cs.setThreshold(view.getPidThreshold(), true);
4267 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4271 af.viewport.setGlobalColourScheme(cs);
4272 af.viewport.setColourAppliesToAllGroups(false);
4274 if (view.getConservationSelected() && cs != null)
4276 cs.setConservationInc(view.getConsThreshold());
4279 af.changeColour(cs);
4281 af.viewport.setColourAppliesToAllGroups(true);
4283 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4285 if (view.hasCentreColumnLabels())
4287 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4289 if (view.hasIgnoreGapsinConsensus())
4291 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4294 if (view.hasFollowHighlight())
4296 af.viewport.setFollowHighlight(view.getFollowHighlight());
4298 if (view.hasFollowSelection())
4300 af.viewport.followSelection = view.getFollowSelection();
4302 if (view.hasShowConsensusHistogram())
4304 af.viewport.setShowConsensusHistogram(view
4305 .getShowConsensusHistogram());
4309 af.viewport.setShowConsensusHistogram(true);
4311 if (view.hasShowSequenceLogo())
4313 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4317 af.viewport.setShowSequenceLogo(false);
4319 if (view.hasNormaliseSequenceLogo())
4321 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4323 if (view.hasShowDbRefTooltip())
4325 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4327 if (view.hasShowNPfeatureTooltip())
4329 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4331 if (view.hasShowGroupConsensus())
4333 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4337 af.viewport.setShowGroupConsensus(false);
4339 if (view.hasShowGroupConservation())
4341 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4345 af.viewport.setShowGroupConservation(false);
4348 // recover featre settings
4349 if (jms.getFeatureSettings() != null)
4351 FeaturesDisplayed fdi;
4352 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4353 String[] renderOrder = new String[jms.getFeatureSettings()
4354 .getSettingCount()];
4355 Hashtable featureGroups = new Hashtable();
4356 Hashtable featureColours = new Hashtable();
4357 Hashtable featureOrder = new Hashtable();
4359 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4361 Setting setting = jms.getFeatureSettings().getSetting(fs);
4362 if (setting.hasMincolour())
4364 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
4365 new java.awt.Color(setting.getMincolour()),
4366 new java.awt.Color(setting.getColour()),
4367 setting.getMin(), setting.getMax()) : new GraduatedColor(
4368 new java.awt.Color(setting.getMincolour()),
4369 new java.awt.Color(setting.getColour()), 0, 1);
4370 if (setting.hasThreshold())
4372 gc.setThresh(setting.getThreshold());
4373 gc.setThreshType(setting.getThreshstate());
4375 gc.setAutoScaled(true); // default
4376 if (setting.hasAutoScale())
4378 gc.setAutoScaled(setting.getAutoScale());
4380 if (setting.hasColourByLabel())
4382 gc.setColourByLabel(setting.getColourByLabel());
4384 // and put in the feature colour table.
4385 featureColours.put(setting.getType(), gc);
4389 featureColours.put(setting.getType(),
4390 new java.awt.Color(setting.getColour()));
4392 renderOrder[fs] = setting.getType();
4393 if (setting.hasOrder())
4395 featureOrder.put(setting.getType(), setting.getOrder());
4399 featureOrder.put(setting.getType(), new Float(fs
4400 / jms.getFeatureSettings().getSettingCount()));
4402 if (setting.getDisplay())
4404 fdi.setVisible(setting.getType());
4407 Hashtable fgtable = new Hashtable();
4408 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4410 Group grp = jms.getFeatureSettings().getGroup(gs);
4411 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4413 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4414 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4415 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4416 FeatureRendererSettings frs = new FeatureRendererSettings(
4417 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4418 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4419 .transferSettings(frs);
4423 if (view.getHiddenColumnsCount() > 0)
4425 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4427 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4428 .getHiddenColumns(c).getEnd() // +1
4432 if (view.getCalcIdParam() != null)
4434 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4436 if (calcIdParam != null)
4438 if (recoverCalcIdParam(calcIdParam, af.viewport))
4443 warn("Couldn't recover parameters for "
4444 + calcIdParam.getCalcId());
4449 af.setMenusFromViewport(af.viewport);
4451 // TODO: we don't need to do this if the viewport is aready visible.
4453 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4454 * has a 'cdna/protein complement' view, in which case save it in order to
4455 * populate a SplitFrame once all views have been read in.
4457 String complementaryViewId = view.getComplementId();
4458 if (complementaryViewId == null)
4460 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4462 // recompute any autoannotation
4463 af.alignPanel.updateAnnotation(false, true);
4464 reorderAutoannotation(af, al, autoAlan);
4465 af.alignPanel.alignmentChanged();
4469 splitFrameCandidates.put(view, af);
4474 private ColourSchemeI constructAnnotationColour(
4475 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
4476 JalviewModelSequence jms, boolean checkGroupAnnColour)
4478 boolean propagateAnnColour = false;
4479 ColourSchemeI cs = null;
4480 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4481 if (checkGroupAnnColour && al.getGroups() != null
4482 && al.getGroups().size() > 0)
4484 // pre 2.8.1 behaviour
4485 // check to see if we should transfer annotation colours
4486 propagateAnnColour = true;
4487 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4489 if (sg.cs instanceof AnnotationColourGradient)
4491 propagateAnnColour = false;
4495 // int find annotation
4496 if (annAlignment.getAlignmentAnnotation() != null)
4498 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4500 if (annAlignment.getAlignmentAnnotation()[i].label
4501 .equals(viewAnnColour.getAnnotation()))
4503 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4505 annAlignment.getAlignmentAnnotation()[i]
4506 .setThreshold(new jalview.datamodel.GraphLine(
4507 viewAnnColour.getThreshold(), "Threshold",
4508 java.awt.Color.black)
4513 if (viewAnnColour.getColourScheme().equals("None"))
4515 cs = new AnnotationColourGradient(
4516 annAlignment.getAlignmentAnnotation()[i],
4517 new java.awt.Color(viewAnnColour.getMinColour()),
4518 new java.awt.Color(viewAnnColour.getMaxColour()),
4519 viewAnnColour.getAboveThreshold());
4521 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4523 cs = new AnnotationColourGradient(
4524 annAlignment.getAlignmentAnnotation()[i],
4525 getUserColourScheme(jms,
4526 viewAnnColour.getColourScheme()),
4527 viewAnnColour.getAboveThreshold());
4531 cs = new AnnotationColourGradient(
4532 annAlignment.getAlignmentAnnotation()[i],
4533 ColourSchemeProperty.getColour(al,
4534 viewAnnColour.getColourScheme()),
4535 viewAnnColour.getAboveThreshold());
4537 if (viewAnnColour.hasPerSequence())
4539 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4542 if (viewAnnColour.hasPredefinedColours())
4544 ((AnnotationColourGradient) cs)
4545 .setPredefinedColours(viewAnnColour
4546 .isPredefinedColours());
4548 if (propagateAnnColour && al.getGroups() != null)
4550 // Also use these settings for all the groups
4551 for (int g = 0; g < al.getGroups().size(); g++)
4553 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4561 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4562 * new AnnotationColourGradient(
4563 * annAlignment.getAlignmentAnnotation()[i], new
4564 * java.awt.Color(viewAnnColour. getMinColour()), new
4565 * java.awt.Color(viewAnnColour. getMaxColour()),
4566 * viewAnnColour.getAboveThreshold()); } else
4569 sg.cs = new AnnotationColourGradient(
4570 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4571 viewAnnColour.getAboveThreshold());
4572 if (cs instanceof AnnotationColourGradient)
4574 if (viewAnnColour.hasPerSequence())
4576 ((AnnotationColourGradient) cs)
4577 .setSeqAssociated(viewAnnColour.isPerSequence());
4579 if (viewAnnColour.hasPredefinedColours())
4581 ((AnnotationColourGradient) cs)
4582 .setPredefinedColours(viewAnnColour
4583 .isPredefinedColours());
4599 private void reorderAutoannotation(AlignFrame af, Alignment al,
4600 List<JvAnnotRow> autoAlan)
4602 // copy over visualization settings for autocalculated annotation in the
4604 if (al.getAlignmentAnnotation() != null)
4607 * Kludge for magic autoannotation names (see JAL-811)
4609 String[] magicNames = new String[] { "Consensus", "Quality",
4611 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4612 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4613 for (String nm : magicNames)
4615 visan.put(nm, nullAnnot);
4617 for (JvAnnotRow auan : autoAlan)
4619 visan.put(auan.template.label
4620 + (auan.template.getCalcId() == null ? "" : "\t"
4621 + auan.template.getCalcId()), auan);
4623 int hSize = al.getAlignmentAnnotation().length;
4624 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4625 // work through any autoCalculated annotation already on the view
4626 // removing it if it should be placed in a different location on the
4627 // annotation panel.
4628 List<String> remains = new ArrayList<String>(visan.keySet());
4629 for (int h = 0; h < hSize; h++)
4631 jalview.datamodel.AlignmentAnnotation jalan = al
4632 .getAlignmentAnnotation()[h];
4633 if (jalan.autoCalculated)
4636 JvAnnotRow valan = visan.get(k = jalan.label);
4637 if (jalan.getCalcId() != null)
4639 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4644 // delete the auto calculated row from the alignment
4645 al.deleteAnnotation(jalan, false);
4649 if (valan != nullAnnot)
4651 if (jalan != valan.template)
4653 // newly created autoannotation row instance
4654 // so keep a reference to the visible annotation row
4655 // and copy over all relevant attributes
4656 if (valan.template.graphHeight >= 0)
4659 jalan.graphHeight = valan.template.graphHeight;
4661 jalan.visible = valan.template.visible;
4663 reorder.add(new JvAnnotRow(valan.order, jalan));
4668 // Add any (possibly stale) autocalculated rows that were not appended to
4669 // the view during construction
4670 for (String other : remains)
4672 JvAnnotRow othera = visan.get(other);
4673 if (othera != nullAnnot && othera.template.getCalcId() != null
4674 && othera.template.getCalcId().length() > 0)
4676 reorder.add(othera);
4679 // now put the automatic annotation in its correct place
4680 int s = 0, srt[] = new int[reorder.size()];
4681 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4682 for (JvAnnotRow jvar : reorder)
4685 srt[s++] = jvar.order;
4688 jalview.util.QuickSort.sort(srt, rws);
4689 // and re-insert the annotation at its correct position
4690 for (JvAnnotRow jvar : rws)
4692 al.addAnnotation(jvar.template, jvar.order);
4694 af.alignPanel.adjustAnnotationHeight();
4698 Hashtable skipList = null;
4701 * TODO remove this method
4704 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4705 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4706 * throw new Error("Implementation Error. No skipList defined for this
4707 * Jalview2XML instance."); } return (AlignFrame)
4708 * skipList.get(view.getSequenceSetId()); }
4712 * Check if the Jalview view contained in object should be skipped or not.
4715 * @return true if view's sequenceSetId is a key in skipList
4717 private boolean skipViewport(JalviewModel object)
4719 if (skipList == null)
4724 if (skipList.containsKey(id = object.getJalviewModelSequence()
4725 .getViewport()[0].getSequenceSetId()))
4727 if (Cache.log != null && Cache.log.isDebugEnabled())
4729 Cache.log.debug("Skipping seuqence set id " + id);
4736 public void addToSkipList(AlignFrame af)
4738 if (skipList == null)
4740 skipList = new Hashtable();
4742 skipList.put(af.getViewport().getSequenceSetId(), af);
4745 public void clearSkipList()
4747 if (skipList != null)
4754 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4755 boolean ignoreUnrefed)
4757 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4758 Vector dseqs = null;
4761 // create a list of new dataset sequences
4762 dseqs = new Vector();
4764 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4766 Sequence vamsasSeq = vamsasSet.getSequence(i);
4767 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4769 // create a new dataset
4772 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4773 dseqs.copyInto(dsseqs);
4774 ds = new jalview.datamodel.Alignment(dsseqs);
4775 debug("Created new dataset " + vamsasSet.getDatasetId()
4776 + " for alignment " + System.identityHashCode(al));
4777 addDatasetRef(vamsasSet.getDatasetId(), ds);
4779 // set the dataset for the newly imported alignment.
4780 if (al.getDataset() == null && !ignoreUnrefed)
4789 * sequence definition to create/merge dataset sequence for
4793 * vector to add new dataset sequence to
4795 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4796 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4798 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4800 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4801 SequenceI dsq = null;
4802 if (sq != null && sq.getDatasetSequence() != null)
4804 dsq = sq.getDatasetSequence();
4806 if (sq == null && ignoreUnrefed)
4810 String sqid = vamsasSeq.getDsseqid();
4813 // need to create or add a new dataset sequence reference to this sequence
4816 dsq = seqRefIds.get(sqid);
4821 // make a new dataset sequence
4822 dsq = sq.createDatasetSequence();
4825 // make up a new dataset reference for this sequence
4826 sqid = seqHash(dsq);
4828 dsq.setVamsasId(uniqueSetSuffix + sqid);
4829 seqRefIds.put(sqid, dsq);
4834 dseqs.addElement(dsq);
4839 ds.addSequence(dsq);
4845 { // make this dataset sequence sq's dataset sequence
4846 sq.setDatasetSequence(dsq);
4847 // and update the current dataset alignment
4852 if (!dseqs.contains(dsq))
4859 if (ds.findIndex(dsq) < 0)
4861 ds.addSequence(dsq);
4868 // TODO: refactor this as a merge dataset sequence function
4869 // now check that sq (the dataset sequence) sequence really is the union of
4870 // all references to it
4871 // boolean pre = sq.getStart() < dsq.getStart();
4872 // boolean post = sq.getEnd() > dsq.getEnd();
4876 // StringBuffer sb = new StringBuffer();
4877 String newres = jalview.analysis.AlignSeq.extractGaps(
4878 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4879 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4880 && newres.length() > dsq.getLength())
4882 // Update with the longer sequence.
4886 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4887 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4888 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4889 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4891 dsq.setSequence(newres);
4893 // TODO: merges will never happen if we 'know' we have the real dataset
4894 // sequence - this should be detected when id==dssid
4896 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4897 // + (pre ? "prepended" : "") + " "
4898 // + (post ? "appended" : ""));
4904 * TODO use AlignmentI here and in related methods - needs
4905 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4907 Hashtable<String, Alignment> datasetIds = null;
4909 IdentityHashMap<Alignment, String> dataset2Ids = null;
4911 private Alignment getDatasetFor(String datasetId)
4913 if (datasetIds == null)
4915 datasetIds = new Hashtable<String, Alignment>();
4918 if (datasetIds.containsKey(datasetId))
4920 return datasetIds.get(datasetId);
4925 private void addDatasetRef(String datasetId, Alignment dataset)
4927 if (datasetIds == null)
4929 datasetIds = new Hashtable<String, Alignment>();
4931 datasetIds.put(datasetId, dataset);
4935 * make a new dataset ID for this jalview dataset alignment
4940 private String getDatasetIdRef(Alignment dataset)
4942 if (dataset.getDataset() != null)
4944 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4946 String datasetId = makeHashCode(dataset, null);
4947 if (datasetId == null)
4949 // make a new datasetId and record it
4950 if (dataset2Ids == null)
4952 dataset2Ids = new IdentityHashMap<Alignment, String>();
4956 datasetId = dataset2Ids.get(dataset);
4958 if (datasetId == null)
4960 datasetId = "ds" + dataset2Ids.size() + 1;
4961 dataset2Ids.put(dataset, datasetId);
4967 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4969 for (int d = 0; d < sequence.getDBRefCount(); d++)
4971 DBRef dr = sequence.getDBRef(d);
4972 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4973 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4974 .getVersion(), sequence.getDBRef(d).getAccessionId());
4975 if (dr.getMapping() != null)
4977 entry.setMap(addMapping(dr.getMapping()));
4979 datasetSequence.addDBRef(entry);
4983 private jalview.datamodel.Mapping addMapping(Mapping m)
4985 SequenceI dsto = null;
4986 // Mapping m = dr.getMapping();
4987 int fr[] = new int[m.getMapListFromCount() * 2];
4988 Enumeration f = m.enumerateMapListFrom();
4989 for (int _i = 0; f.hasMoreElements(); _i += 2)
4991 MapListFrom mf = (MapListFrom) f.nextElement();
4992 fr[_i] = mf.getStart();
4993 fr[_i + 1] = mf.getEnd();
4995 int fto[] = new int[m.getMapListToCount() * 2];
4996 f = m.enumerateMapListTo();
4997 for (int _i = 0; f.hasMoreElements(); _i += 2)
4999 MapListTo mf = (MapListTo) f.nextElement();
5000 fto[_i] = mf.getStart();
5001 fto[_i + 1] = mf.getEnd();
5003 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5004 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5005 if (m.getMappingChoice() != null)
5007 MappingChoice mc = m.getMappingChoice();
5008 if (mc.getDseqFor() != null)
5010 String dsfor = "" + mc.getDseqFor();
5011 if (seqRefIds.containsKey(dsfor))
5016 jmap.setTo(seqRefIds.get(dsfor));
5020 frefedSequence.add(new Object[] { dsfor, jmap });
5026 * local sequence definition
5028 Sequence ms = mc.getSequence();
5029 SequenceI djs = null;
5030 String sqid = ms.getDsseqid();
5031 if (sqid != null && sqid.length() > 0)
5034 * recover dataset sequence
5036 djs = seqRefIds.get(sqid);
5041 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5042 sqid = ((Object) ms).toString(); // make up a new hascode for
5043 // undefined dataset sequence hash
5044 // (unlikely to happen)
5050 * make a new dataset sequence and add it to refIds hash
5052 djs = new jalview.datamodel.Sequence(ms.getName(),
5054 djs.setStart(jmap.getMap().getToLowest());
5055 djs.setEnd(jmap.getMap().getToHighest());
5056 djs.setVamsasId(uniqueSetSuffix + sqid);
5058 seqRefIds.put(sqid, djs);
5061 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5070 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5071 boolean keepSeqRefs)
5074 JalviewModel jm = saveState(ap, null, null, null);
5079 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5083 uniqueSetSuffix = "";
5084 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5089 if (this.frefedSequence == null)
5091 frefedSequence = new Vector();
5094 viewportsAdded.clear();
5096 AlignFrame af = loadFromObject(jm, null, false, null);
5097 af.alignPanels.clear();
5098 af.closeMenuItem_actionPerformed(true);
5101 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5102 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5103 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5104 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5105 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5108 return af.alignPanel;
5112 * flag indicating if hashtables should be cleared on finalization TODO this
5113 * flag may not be necessary
5115 private final boolean _cleartables = true;
5117 private Hashtable jvids2vobj;
5122 * @see java.lang.Object#finalize()
5125 protected void finalize() throws Throwable
5127 // really make sure we have no buried refs left.
5132 this.seqRefIds = null;
5133 this.seqsToIds = null;
5137 private void warn(String msg)
5142 private void warn(String msg, Exception e)
5144 if (Cache.log != null)
5148 Cache.log.warn(msg, e);
5152 Cache.log.warn(msg);
5157 System.err.println("Warning: " + msg);
5160 e.printStackTrace();
5165 private void debug(String string)
5167 debug(string, null);
5170 private void debug(String msg, Exception e)
5172 if (Cache.log != null)
5176 Cache.log.debug(msg, e);
5180 Cache.log.debug(msg);
5185 System.err.println("Warning: " + msg);
5188 e.printStackTrace();
5194 * set the object to ID mapping tables used to write/recover objects and XML
5195 * ID strings for the jalview project. If external tables are provided then
5196 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5197 * object goes out of scope. - also populates the datasetIds hashtable with
5198 * alignment objects containing dataset sequences
5201 * Map from ID strings to jalview datamodel
5203 * Map from jalview datamodel to ID strings
5207 public void setObjectMappingTables(Hashtable vobj2jv,
5208 IdentityHashMap jv2vobj)
5210 this.jv2vobj = jv2vobj;
5211 this.vobj2jv = vobj2jv;
5212 Iterator ds = jv2vobj.keySet().iterator();
5214 while (ds.hasNext())
5216 Object jvobj = ds.next();
5217 id = jv2vobj.get(jvobj).toString();
5218 if (jvobj instanceof jalview.datamodel.Alignment)
5220 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5222 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5225 else if (jvobj instanceof jalview.datamodel.Sequence)
5227 // register sequence object so the XML parser can recover it.
5228 if (seqRefIds == null)
5230 seqRefIds = new HashMap<String, SequenceI>();
5232 if (seqsToIds == null)
5234 seqsToIds = new IdentityHashMap<SequenceI, String>();
5236 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5237 seqsToIds.put((SequenceI) jvobj, id);
5239 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5242 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5243 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5244 if (jvann.annotationId == null)
5246 jvann.annotationId = anid;
5248 if (!jvann.annotationId.equals(anid))
5250 // TODO verify that this is the correct behaviour
5251 this.warn("Overriding Annotation ID for " + anid
5252 + " from different id : " + jvann.annotationId);
5253 jvann.annotationId = anid;
5256 else if (jvobj instanceof String)
5258 if (jvids2vobj == null)
5260 jvids2vobj = new Hashtable();
5261 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5266 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5272 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5273 * objects created from the project archive. If string is null (default for
5274 * construction) then suffix will be set automatically.
5278 public void setUniqueSetSuffix(String string)
5280 uniqueSetSuffix = string;
5285 * uses skipList2 as the skipList for skipping views on sequence sets
5286 * associated with keys in the skipList
5290 public void setSkipList(Hashtable skipList2)
5292 skipList = skipList2;
5296 * Reads the jar entry of given name and returns its contents, or null if the
5297 * entry is not found.
5300 * @param jarEntryName
5303 protected String readJarEntry(jarInputStreamProvider jprovider,
5304 String jarEntryName)
5306 String result = null;
5307 BufferedReader in = null;
5312 * Reopen the jar input stream and traverse its entries to find a matching
5315 JarInputStream jin = jprovider.getJarInputStream();
5316 JarEntry entry = null;
5319 entry = jin.getNextJarEntry();
5320 } while (entry != null && !entry.getName().equals(jarEntryName));
5324 StringBuilder out = new StringBuilder(256);
5325 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5328 while ((data = in.readLine()) != null)
5332 result = out.toString();
5336 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5338 } catch (Exception ex)
5340 ex.printStackTrace();
5348 } catch (IOException e)
5359 * Returns an incrementing counter (0, 1, 2...)
5363 private synchronized int nextCounter()