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<Object[]> 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 = 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()
2184 setLoadingFinishedForNewStructureViewers();
2187 } catch (Exception x)
2189 System.err.println("Error loading alignment: " + x.getMessage());
2195 private jarInputStreamProvider createjarInputStreamProvider(
2196 final String file) throws MalformedURLException
2199 errorMessage = null;
2200 uniqueSetSuffix = null;
2202 viewportsAdded.clear();
2203 frefedSequence = null;
2205 if (file.startsWith("http://"))
2207 url = new URL(file);
2209 final URL _url = url;
2210 return new jarInputStreamProvider()
2214 public JarInputStream getJarInputStream() throws IOException
2218 return new JarInputStream(_url.openStream());
2222 return new JarInputStream(new FileInputStream(file));
2227 public String getFilename()
2235 * Recover jalview session from a jalview project archive. Caller may
2236 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2237 * themselves. Any null fields will be initialised with default values,
2238 * non-null fields are left alone.
2243 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2245 errorMessage = null;
2246 if (uniqueSetSuffix == null)
2248 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2250 if (seqRefIds == null)
2252 seqRefIds = new HashMap<String, SequenceI>();
2254 if (frefedSequence == null)
2256 frefedSequence = new Vector<Object[]>();
2259 AlignFrame af = null, _af = null;
2260 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2261 final String file = jprovider.getFilename();
2264 JarInputStream jin = null;
2265 JarEntry jarentry = null;
2270 jin = jprovider.getJarInputStream();
2271 for (int i = 0; i < entryCount; i++)
2273 jarentry = jin.getNextJarEntry();
2276 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2278 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2279 JalviewModel object = new JalviewModel();
2281 Unmarshaller unmar = new Unmarshaller(object);
2282 unmar.setValidation(false);
2283 object = (JalviewModel) unmar.unmarshal(in);
2284 if (true) // !skipViewport(object))
2286 _af = loadFromObject(object, file, true, jprovider);
2287 if (object.getJalviewModelSequence().getViewportCount() > 0)
2290 if (af.viewport.isGatherViewsHere())
2292 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2298 else if (jarentry != null)
2300 // Some other file here.
2303 } while (jarentry != null);
2304 resolveFrefedSequences();
2305 } catch (IOException ex)
2307 ex.printStackTrace();
2308 errorMessage = "Couldn't locate Jalview XML file : " + file;
2309 System.err.println("Exception whilst loading jalview XML file : "
2311 } catch (Exception ex)
2313 System.err.println("Parsing as Jalview Version 2 file failed.");
2314 ex.printStackTrace(System.err);
2315 if (attemptversion1parse)
2317 // Is Version 1 Jar file?
2320 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2321 } catch (Exception ex2)
2323 System.err.println("Exception whilst loading as jalviewXMLV1:");
2324 ex2.printStackTrace();
2328 if (Desktop.instance != null)
2330 Desktop.instance.stopLoading();
2334 System.out.println("Successfully loaded archive file");
2337 ex.printStackTrace();
2339 System.err.println("Exception whilst loading jalview XML file : "
2341 } catch (OutOfMemoryError e)
2343 // Don't use the OOM Window here
2344 errorMessage = "Out of memory loading jalview XML file";
2345 System.err.println("Out of memory whilst loading jalview XML file");
2346 e.printStackTrace();
2349 if (Desktop.instance != null)
2351 Desktop.instance.stopLoading();
2355 * Regather multiple views (with the same sequence set id) to the frame (if
2356 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2357 * views instead of separate frames. Note this doesn't restore a state where
2358 * some expanded views in turn have tabbed views - the last "first tab" read
2359 * in will play the role of gatherer for all.
2361 for (AlignFrame fr : gatherToThisFrame.values())
2363 Desktop.instance.gatherViews(fr);
2366 restoreSplitFrames();
2368 if (errorMessage != null)
2376 * Try to reconstruct and display SplitFrame windows, where each contains
2377 * complementary dna and protein alignments. Done by pairing up AlignFrame
2378 * objects (created earlier) which have complementary viewport ids associated.
2380 protected void restoreSplitFrames()
2382 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2383 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2384 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2387 * Identify the DNA alignments
2389 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2392 AlignFrame af = candidate.getValue();
2393 if (af.getViewport().getAlignment().isNucleotide())
2395 dna.put(candidate.getKey().getId(), af);
2400 * Try to match up the protein complements
2402 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2405 AlignFrame af = candidate.getValue();
2406 if (!af.getViewport().getAlignment().isNucleotide())
2408 String complementId = candidate.getKey().getComplementId();
2409 // only non-null complements should be in the Map
2410 if (complementId != null && dna.containsKey(complementId))
2412 final AlignFrame dnaFrame = dna.get(complementId);
2413 SplitFrame sf = createSplitFrame(dnaFrame, af);
2414 addedToSplitFrames.add(dnaFrame);
2415 addedToSplitFrames.add(af);
2416 if (af.viewport.isGatherViewsHere())
2425 * Open any that we failed to pair up (which shouldn't happen!) as
2426 * standalone AlignFrame's.
2428 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2431 AlignFrame af = candidate.getValue();
2432 if (!addedToSplitFrames.contains(af))
2434 Viewport view = candidate.getKey();
2435 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2437 System.err.println("Failed to restore view " + view.getTitle()
2438 + " to split frame");
2443 * Gather back into tabbed views as flagged.
2445 for (SplitFrame sf : gatherTo)
2447 Desktop.instance.gatherViews(sf);
2450 splitFrameCandidates.clear();
2454 * Construct and display one SplitFrame holding DNA and protein alignments.
2457 * @param proteinFrame
2460 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2461 AlignFrame proteinFrame)
2463 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2464 String title = MessageManager.getString("label.linked_view_title");
2465 int width = (int) dnaFrame.getBounds().getWidth();
2466 int height = (int) (dnaFrame.getBounds().getHeight()
2467 + proteinFrame.getBounds().getHeight() + 50);
2470 * SplitFrame location is saved to both enclosed frames
2472 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2473 Desktop.addInternalFrame(splitFrame, title, width, height);
2476 * And compute cDNA consensus (couldn't do earlier with consensus as
2477 * mappings were not yet present)
2479 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2485 * check errorMessage for a valid error message and raise an error box in the
2486 * GUI or write the current errorMessage to stderr and then clear the error
2489 protected void reportErrors()
2491 reportErrors(false);
2494 protected void reportErrors(final boolean saving)
2496 if (errorMessage != null)
2498 final String finalErrorMessage = errorMessage;
2501 javax.swing.SwingUtilities.invokeLater(new Runnable()
2506 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2507 finalErrorMessage, "Error "
2508 + (saving ? "saving" : "loading")
2509 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2515 System.err.println("Problem loading Jalview file: " + errorMessage);
2518 errorMessage = null;
2521 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2524 * when set, local views will be updated from view stored in JalviewXML
2525 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2526 * sync if this is set to true.
2528 private final boolean updateLocalViews = false;
2531 * Returns the path to a temporary file holding the PDB file for the given PDB
2532 * id. The first time of asking, searches for a file of that name in the
2533 * Jalview project jar, and copies it to a new temporary file. Any repeat
2534 * requests just return the path to the file previously created.
2540 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2542 if (alreadyLoadedPDB.containsKey(pdbId))
2544 return alreadyLoadedPDB.get(pdbId).toString();
2547 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2548 if (tempFile != null)
2550 alreadyLoadedPDB.put(pdbId, tempFile);
2556 * Copies the jar entry of given name to a new temporary file and returns the
2557 * path to the file, or null if the entry is not found.
2560 * @param jarEntryName
2562 * a prefix for the temporary file name, must be at least three
2566 protected String copyJarEntry(jarInputStreamProvider jprovider,
2567 String jarEntryName, String prefix)
2569 BufferedReader in = null;
2570 PrintWriter out = null;
2574 JarInputStream jin = jprovider.getJarInputStream();
2576 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2577 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2578 * FileInputStream(jprovider)); }
2581 JarEntry entry = null;
2584 entry = jin.getNextJarEntry();
2585 } while (entry != null && !entry.getName().equals(jarEntryName));
2588 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2589 File outFile = File.createTempFile(prefix, ".tmp");
2590 outFile.deleteOnExit();
2591 out = new PrintWriter(new FileOutputStream(outFile));
2594 while ((data = in.readLine()) != null)
2599 String t = outFile.getAbsolutePath();
2604 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2606 } catch (Exception ex)
2608 ex.printStackTrace();
2616 } catch (IOException e)
2630 private class JvAnnotRow
2632 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2639 * persisted version of annotation row from which to take vis properties
2641 public jalview.datamodel.AlignmentAnnotation template;
2644 * original position of the annotation row in the alignment
2650 * Load alignment frame from jalview XML DOM object
2655 * filename source string
2656 * @param loadTreesAndStructures
2657 * when false only create Viewport
2659 * data source provider
2660 * @return alignment frame created from view stored in DOM
2662 AlignFrame loadFromObject(JalviewModel object, String file,
2663 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2665 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2666 Sequence[] vamsasSeq = vamsasSet.getSequence();
2668 JalviewModelSequence jms = object.getJalviewModelSequence();
2670 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2673 // ////////////////////////////////
2676 List<SequenceI> hiddenSeqs = null;
2677 jalview.datamodel.Sequence jseq;
2679 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2681 boolean multipleView = false;
2683 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2684 int vi = 0; // counter in vamsasSeq array
2685 for (int i = 0; i < jseqs.length; i++)
2687 String seqId = jseqs[i].getId();
2689 if (seqRefIds.get(seqId) != null)
2691 tmpseqs.add(seqRefIds.get(seqId));
2692 multipleView = true;
2696 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2697 vamsasSeq[vi].getSequence());
2698 jseq.setDescription(vamsasSeq[vi].getDescription());
2699 jseq.setStart(jseqs[i].getStart());
2700 jseq.setEnd(jseqs[i].getEnd());
2701 jseq.setVamsasId(uniqueSetSuffix + seqId);
2702 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2707 if (jseqs[i].getHidden())
2709 if (hiddenSeqs == null)
2711 hiddenSeqs = new ArrayList<SequenceI>();
2714 hiddenSeqs.add(seqRefIds.get(seqId));
2720 // Create the alignment object from the sequence set
2721 // ///////////////////////////////
2722 SequenceI[] orderedSeqs = tmpseqs
2723 .toArray(new SequenceI[tmpseqs.size()]);
2725 Alignment al = new Alignment(orderedSeqs);
2727 // / Add the alignment properties
2728 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2730 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2731 al.setProperty(ssp.getKey(), ssp.getValue());
2735 // SequenceFeatures are added to the DatasetSequence,
2736 // so we must create or recover the dataset before loading features
2737 // ///////////////////////////////
2738 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2740 // older jalview projects do not have a dataset id.
2741 al.setDataset(null);
2745 // recover dataset - passing on flag indicating if this a 'viewless'
2746 // sequence set (a.k.a. a stored dataset for the project)
2747 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2748 .getViewportCount() == 0);
2750 // ///////////////////////////////
2752 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2755 // load sequence features, database references and any associated PDB
2756 // structures for the alignment
2757 for (int i = 0; i < vamsasSeq.length; i++)
2759 if (jseqs[i].getFeaturesCount() > 0)
2761 Features[] features = jseqs[i].getFeatures();
2762 for (int f = 0; f < features.length; f++)
2764 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2765 features[f].getType(), features[f].getDescription(),
2766 features[f].getStatus(), features[f].getBegin(),
2767 features[f].getEnd(), features[f].getFeatureGroup());
2769 sf.setScore(features[f].getScore());
2770 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2772 OtherData keyValue = features[f].getOtherData(od);
2773 if (keyValue.getKey().startsWith("LINK"))
2775 sf.addLink(keyValue.getValue());
2779 sf.setValue(keyValue.getKey(), keyValue.getValue());
2784 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2787 if (vamsasSeq[i].getDBRefCount() > 0)
2789 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2791 if (jseqs[i].getPdbidsCount() > 0)
2793 Pdbids[] ids = jseqs[i].getPdbids();
2794 for (int p = 0; p < ids.length; p++)
2796 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2797 entry.setId(ids[p].getId());
2798 if (ids[p].getType() != null)
2800 if (ids[p].getType().equalsIgnoreCase("PDB"))
2802 entry.setType(PDBEntry.Type.PDB);
2806 entry.setType(PDBEntry.Type.FILE);
2809 if (ids[p].getFile() != null)
2811 if (!pdbloaded.containsKey(ids[p].getFile()))
2813 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2817 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2820 StructureSelectionManager.getStructureSelectionManager(
2821 Desktop.instance).registerPDBEntry(entry);
2822 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2826 } // end !multipleview
2828 // ///////////////////////////////
2829 // LOAD SEQUENCE MAPPINGS
2831 if (vamsasSet.getAlcodonFrameCount() > 0)
2833 // TODO Potentially this should only be done once for all views of an
2835 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2836 for (int i = 0; i < alc.length; i++)
2838 AlignedCodonFrame cf = new AlignedCodonFrame();
2839 if (alc[i].getAlcodMapCount() > 0)
2841 AlcodMap[] maps = alc[i].getAlcodMap();
2842 for (int m = 0; m < maps.length; m++)
2844 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2846 jalview.datamodel.Mapping mapping = null;
2847 // attach to dna sequence reference.
2848 if (maps[m].getMapping() != null)
2850 mapping = addMapping(maps[m].getMapping());
2852 if (dnaseq != null && mapping.getTo() != null)
2854 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2859 frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
2864 al.addCodonFrame(cf);
2868 // ////////////////////////////////
2870 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2873 * store any annotations which forward reference a group's ID
2875 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2877 if (vamsasSet.getAnnotationCount() > 0)
2879 Annotation[] an = vamsasSet.getAnnotation();
2881 for (int i = 0; i < an.length; i++)
2883 Annotation annotation = an[i];
2886 * test if annotation is automatically calculated for this view only
2888 boolean autoForView = false;
2889 if (annotation.getLabel().equals("Quality")
2890 || annotation.getLabel().equals("Conservation")
2891 || annotation.getLabel().equals("Consensus"))
2893 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2895 if (!annotation.hasAutoCalculated())
2897 annotation.setAutoCalculated(true);
2901 || (annotation.hasAutoCalculated() && annotation
2902 .isAutoCalculated()))
2904 // remove ID - we don't recover annotation from other views for
2905 // view-specific annotation
2906 annotation.setId(null);
2909 // set visiblity for other annotation in this view
2910 String annotationId = annotation.getId();
2911 if (annotationId != null && annotationIds.containsKey(annotationId))
2913 AlignmentAnnotation jda = annotationIds.get(annotationId);
2914 // in principle Visible should always be true for annotation displayed
2915 // in multiple views
2916 if (annotation.hasVisible())
2918 jda.visible = annotation.getVisible();
2921 al.addAnnotation(jda);
2925 // Construct new annotation from model.
2926 AnnotationElement[] ae = annotation.getAnnotationElement();
2927 jalview.datamodel.Annotation[] anot = null;
2928 java.awt.Color firstColour = null;
2930 if (!annotation.getScoreOnly())
2932 anot = new jalview.datamodel.Annotation[al.getWidth()];
2933 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2935 anpos = ae[aa].getPosition();
2937 if (anpos >= anot.length)
2942 anot[anpos] = new jalview.datamodel.Annotation(
2944 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2945 (ae[aa].getSecondaryStructure() == null || ae[aa]
2946 .getSecondaryStructure().length() == 0) ? ' '
2947 : ae[aa].getSecondaryStructure().charAt(0),
2951 // JBPNote: Consider verifying dataflow for IO of secondary
2952 // structure annotation read from Stockholm files
2953 // this was added to try to ensure that
2954 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2956 // anot[ae[aa].getPosition()].displayCharacter = "";
2958 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2959 if (firstColour == null)
2961 firstColour = anot[anpos].colour;
2965 jalview.datamodel.AlignmentAnnotation jaa = null;
2967 if (annotation.getGraph())
2969 float llim = 0, hlim = 0;
2970 // if (autoForView || an[i].isAutoCalculated()) {
2973 jaa = new jalview.datamodel.AlignmentAnnotation(
2974 annotation.getLabel(), annotation.getDescription(), anot,
2975 llim, hlim, annotation.getGraphType());
2977 jaa.graphGroup = annotation.getGraphGroup();
2978 jaa._linecolour = firstColour;
2979 if (annotation.getThresholdLine() != null)
2981 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
2982 .getThresholdLine().getValue(), annotation
2983 .getThresholdLine().getLabel(), new java.awt.Color(
2984 annotation.getThresholdLine().getColour())));
2987 if (autoForView || annotation.isAutoCalculated())
2989 // Hardwire the symbol display line to ensure that labels for
2990 // histograms are displayed
2996 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2997 an[i].getDescription(), anot);
2998 jaa._linecolour = firstColour;
3000 // register new annotation
3001 if (an[i].getId() != null)
3003 annotationIds.put(an[i].getId(), jaa);
3004 jaa.annotationId = an[i].getId();
3006 // recover sequence association
3007 String sequenceRef = an[i].getSequenceRef();
3008 if (sequenceRef != null)
3010 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3011 SequenceI sequence = seqRefIds.get(sequenceRef);
3012 if (sequence == null)
3014 // in pre-2.9 projects sequence ref is to sequence name
3015 sequence = al.findName(sequenceRef);
3017 if (sequence != null)
3019 jaa.createSequenceMapping(sequence, 1, true);
3020 sequence.addAlignmentAnnotation(jaa);
3023 // and make a note of any group association
3024 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3026 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3027 .get(an[i].getGroupRef());
3030 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3031 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3036 if (an[i].hasScore())
3038 jaa.setScore(an[i].getScore());
3040 if (an[i].hasVisible())
3042 jaa.visible = an[i].getVisible();
3045 if (an[i].hasCentreColLabels())
3047 jaa.centreColLabels = an[i].getCentreColLabels();
3050 if (an[i].hasScaleColLabels())
3052 jaa.scaleColLabel = an[i].getScaleColLabels();
3054 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3056 // newer files have an 'autoCalculated' flag and store calculation
3057 // state in viewport properties
3058 jaa.autoCalculated = true; // means annotation will be marked for
3059 // update at end of load.
3061 if (an[i].hasGraphHeight())
3063 jaa.graphHeight = an[i].getGraphHeight();
3065 if (an[i].hasBelowAlignment())
3067 jaa.belowAlignment = an[i].isBelowAlignment();
3069 jaa.setCalcId(an[i].getCalcId());
3070 if (an[i].getPropertyCount() > 0)
3072 for (jalview.schemabinding.version2.Property prop : an[i]
3075 jaa.setProperty(prop.getName(), prop.getValue());
3078 if (jaa.autoCalculated)
3080 autoAlan.add(new JvAnnotRow(i, jaa));
3083 // if (!autoForView)
3085 // add autocalculated group annotation and any user created annotation
3087 al.addAnnotation(jaa);
3091 // ///////////////////////
3093 // Create alignment markup and styles for this view
3094 if (jms.getJGroupCount() > 0)
3096 JGroup[] groups = jms.getJGroup();
3097 boolean addAnnotSchemeGroup = false;
3098 for (int i = 0; i < groups.length; i++)
3100 JGroup jGroup = groups[i];
3101 ColourSchemeI cs = null;
3102 if (jGroup.getColour() != null)
3104 if (jGroup.getColour().startsWith("ucs"))
3106 cs = getUserColourScheme(jms, jGroup.getColour());
3108 else if (jGroup.getColour().equals("AnnotationColourGradient")
3109 && jGroup.getAnnotationColours() != null)
3111 addAnnotSchemeGroup = true;
3116 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3121 cs.setThreshold(jGroup.getPidThreshold(), true);
3125 Vector<SequenceI> seqs = new Vector<SequenceI>();
3127 for (int s = 0; s < jGroup.getSeqCount(); s++)
3129 String seqId = jGroup.getSeq(s) + "";
3130 SequenceI ts = seqRefIds.get(seqId);
3134 seqs.addElement(ts);
3138 if (seqs.size() < 1)
3143 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3144 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3145 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3147 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3149 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3150 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3151 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3152 .isShowUnconserved() : false);
3153 sg.thresholdTextColour = jGroup.getTextColThreshold();
3154 if (jGroup.hasShowConsensusHistogram())
3156 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3159 if (jGroup.hasShowSequenceLogo())
3161 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3163 if (jGroup.hasNormaliseSequenceLogo())
3165 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3167 if (jGroup.hasIgnoreGapsinConsensus())
3169 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3171 if (jGroup.getConsThreshold() != 0)
3173 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3174 "All", ResidueProperties.propHash, 3,
3175 sg.getSequences(null), 0, sg.getWidth() - 1);
3177 c.verdict(false, 25);
3178 sg.cs.setConservation(c);
3181 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3183 // re-instate unique group/annotation row reference
3184 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3188 for (AlignmentAnnotation jaa : jaal)
3191 if (jaa.autoCalculated)
3193 // match up and try to set group autocalc alignment row for this
3195 if (jaa.label.startsWith("Consensus for "))
3197 sg.setConsensus(jaa);
3199 // match up and try to set group autocalc alignment row for this
3201 if (jaa.label.startsWith("Conservation for "))
3203 sg.setConservationRow(jaa);
3210 if (addAnnotSchemeGroup)
3212 // reconstruct the annotation colourscheme
3213 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3214 null, al, jms, false);
3220 // only dataset in this model, so just return.
3223 // ///////////////////////////////
3226 // If we just load in the same jar file again, the sequenceSetId
3227 // will be the same, and we end up with multiple references
3228 // to the same sequenceSet. We must modify this id on load
3229 // so that each load of the file gives a unique id
3230 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3231 String viewId = (view.getId() == null ? null : view.getId()
3233 AlignFrame af = null;
3234 AlignViewport av = null;
3235 // now check to see if we really need to create a new viewport.
3236 if (multipleView && viewportsAdded.size() == 0)
3238 // We recovered an alignment for which a viewport already exists.
3239 // TODO: fix up any settings necessary for overlaying stored state onto
3240 // state recovered from another document. (may not be necessary).
3241 // we may need a binding from a viewport in memory to one recovered from
3243 // and then recover its containing af to allow the settings to be applied.
3244 // TODO: fix for vamsas demo
3246 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3248 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3249 if (seqsetobj != null)
3251 if (seqsetobj instanceof String)
3253 uniqueSeqSetId = (String) seqsetobj;
3255 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3261 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3267 * indicate that annotation colours are applied across all groups (pre
3268 * Jalview 2.8.1 behaviour)
3270 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3271 "2.8.1", object.getVersion());
3273 AlignmentPanel ap = null;
3274 boolean isnewview = true;
3277 // Check to see if this alignment already has a view id == viewId
3278 jalview.gui.AlignmentPanel views[] = Desktop
3279 .getAlignmentPanels(uniqueSeqSetId);
3280 if (views != null && views.length > 0)
3282 for (int v = 0; v < views.length; v++)
3284 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3286 // recover the existing alignpanel, alignframe, viewport
3287 af = views[v].alignFrame;
3290 // TODO: could even skip resetting view settings if we don't want to
3291 // change the local settings from other jalview processes
3300 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3301 uniqueSeqSetId, viewId, autoAlan);
3307 * Load any trees, PDB structures and viewers
3309 * Not done if flag is false (when this method is used for New View)
3311 if (loadTreesAndStructures)
3313 loadTrees(jms, view, af, av, ap);
3314 loadPDBStructures(jprovider, jseqs, af, ap);
3315 loadRnaViewers(jprovider, jseqs, ap);
3317 // and finally return.
3322 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3323 * panel is restored from separate jar entries, two (gapped and trimmed) per
3324 * sequence and secondary structure.
3326 * Currently each viewer shows just one sequence and structure (gapped and
3327 * trimmed), however this method is designed to support multiple sequences or
3328 * structures in viewers if wanted in future.
3334 private void loadRnaViewers(jarInputStreamProvider jprovider,
3335 JSeq[] jseqs, AlignmentPanel ap)
3338 * scan the sequences for references to viewers; create each one the first
3339 * time it is referenced, add Rna models to existing viewers
3341 for (JSeq jseq : jseqs)
3343 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3345 RnaViewer viewer = jseq.getRnaViewer(i);
3346 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3347 uniqueSetSuffix, ap);
3349 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3351 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3352 SequenceI seq = seqRefIds.get(jseq.getId());
3353 AlignmentAnnotation ann = this.annotationIds.get(ss
3354 .getAnnotationId());
3357 * add the structure to the Varna display (with session state copied
3358 * from the jar to a temporary file)
3360 boolean gapped = ss.isGapped();
3361 String rnaTitle = ss.getTitle();
3362 String sessionState = ss.getViewerState();
3363 String tempStateFile = copyJarEntry(jprovider, sessionState,
3365 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3366 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3368 appVarna.setInitialSelection(viewer.getSelectedRna());
3374 * Locate and return an already instantiated matching AppVarna, or create one
3378 * @param viewIdSuffix
3382 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3383 String viewIdSuffix, AlignmentPanel ap)
3386 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3387 * if load is repeated
3389 String postLoadId = viewer.getViewId() + viewIdSuffix;
3390 for (JInternalFrame frame : getAllFrames())
3392 if (frame instanceof AppVarna)
3394 AppVarna varna = (AppVarna) frame;
3395 if (postLoadId.equals(varna.getViewId()))
3397 // this viewer is already instantiated
3398 // could in future here add ap as another 'parent' of the
3399 // AppVarna window; currently just 1-to-many
3406 * viewer not found - make it
3408 RnaViewerModel model = new RnaViewerModel(postLoadId,
3409 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3410 viewer.getWidth(), viewer.getHeight(),
3411 viewer.getDividerLocation());
3412 AppVarna varna = new AppVarna(model, ap);
3418 * Load any saved trees
3426 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3427 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3429 // TODO result of automated refactoring - are all these parameters needed?
3432 for (int t = 0; t < jms.getTreeCount(); t++)
3435 Tree tree = jms.getTree(t);
3437 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3440 tp = af.ShowNewickTree(
3441 new jalview.io.NewickFile(tree.getNewick()),
3442 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3443 tree.getXpos(), tree.getYpos());
3444 if (tree.getId() != null)
3446 // perhaps bind the tree id to something ?
3451 // update local tree attributes ?
3452 // TODO: should check if tp has been manipulated by user - if so its
3453 // settings shouldn't be modified
3454 tp.setTitle(tree.getTitle());
3455 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3456 .getWidth(), tree.getHeight()));
3457 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3460 tp.treeCanvas.av = av; // af.viewport;
3461 tp.treeCanvas.ap = ap; // af.alignPanel;
3466 warn("There was a problem recovering stored Newick tree: \n"
3467 + tree.getNewick());
3471 tp.fitToWindow.setState(tree.getFitToWindow());
3472 tp.fitToWindow_actionPerformed(null);
3474 if (tree.getFontName() != null)
3476 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3477 .getFontStyle(), tree.getFontSize()));
3481 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3482 .getFontStyle(), tree.getFontSize()));
3485 tp.showPlaceholders(tree.getMarkUnlinked());
3486 tp.showBootstrap(tree.getShowBootstrap());
3487 tp.showDistances(tree.getShowDistances());
3489 tp.treeCanvas.threshold = tree.getThreshold();
3491 if (tree.getCurrentTree())
3493 af.viewport.setCurrentTree(tp.getTree());
3497 } catch (Exception ex)
3499 ex.printStackTrace();
3504 * Load and link any saved structure viewers.
3511 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3512 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3515 * Run through all PDB ids on the alignment, and collect mappings between
3516 * distinct view ids and all sequences referring to that view.
3518 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3520 for (int i = 0; i < jseqs.length; i++)
3522 if (jseqs[i].getPdbidsCount() > 0)
3524 Pdbids[] ids = jseqs[i].getPdbids();
3525 for (int p = 0; p < ids.length; p++)
3527 final int structureStateCount = ids[p].getStructureStateCount();
3528 for (int s = 0; s < structureStateCount; s++)
3530 // check to see if we haven't already created this structure view
3531 final StructureState structureState = ids[p]
3532 .getStructureState(s);
3533 String sviewid = (structureState.getViewId() == null) ? null
3534 : structureState.getViewId() + uniqueSetSuffix;
3535 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3536 // Originally : ids[p].getFile()
3537 // : TODO: verify external PDB file recovery still works in normal
3538 // jalview project load
3539 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3540 jpdb.setId(ids[p].getId());
3542 int x = structureState.getXpos();
3543 int y = structureState.getYpos();
3544 int width = structureState.getWidth();
3545 int height = structureState.getHeight();
3547 // Probably don't need to do this anymore...
3548 // Desktop.desktop.getComponentAt(x, y);
3549 // TODO: NOW: check that this recovers the PDB file correctly.
3550 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3551 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3553 if (sviewid == null)
3555 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3558 if (!structureViewers.containsKey(sviewid))
3560 structureViewers.put(sviewid,
3561 new StructureViewerModel(x, y, width, height, false,
3562 false, true, structureState.getViewId(),
3563 structureState.getType()));
3564 // Legacy pre-2.7 conversion JAL-823 :
3565 // do not assume any view has to be linked for colour by
3569 // assemble String[] { pdb files }, String[] { id for each
3570 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3571 // seqs_file 2}, boolean[] {
3572 // linkAlignPanel,superposeWithAlignpanel}} from hash
3573 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3574 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3575 | (structureState.hasAlignwithAlignPanel() ? structureState
3576 .getAlignwithAlignPanel() : false));
3579 * Default colour by linked panel to false if not specified (e.g.
3580 * for pre-2.7 projects)
3582 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3583 colourWithAlignPanel |= (structureState
3584 .hasColourwithAlignPanel() ? structureState
3585 .getColourwithAlignPanel() : false);
3586 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3589 * Default colour by viewer to true if not specified (e.g. for
3592 boolean colourByViewer = jmoldat.isColourByViewer();
3593 colourByViewer &= structureState.hasColourByJmol() ? structureState
3594 .getColourByJmol() : true;
3595 jmoldat.setColourByViewer(colourByViewer);
3597 if (jmoldat.getStateData().length() < structureState
3598 .getContent().length())
3601 jmoldat.setStateData(structureState.getContent());
3604 if (ids[p].getFile() != null)
3606 File mapkey = new File(ids[p].getFile());
3607 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3608 if (seqstrmaps == null)
3610 jmoldat.getFileData().put(
3612 seqstrmaps = jmoldat.new StructureData(pdbFile,
3615 if (!seqstrmaps.getSeqList().contains(seq))
3617 seqstrmaps.getSeqList().add(seq);
3623 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");
3630 // Instantiate the associated structure views
3631 for (Entry<String, StructureViewerModel> entry : structureViewers
3636 createOrLinkStructureViewer(entry, af, ap, jprovider);
3637 } catch (Exception e)
3639 System.err.println("Error loading structure viewer: "
3641 // failed - try the next one
3653 protected void createOrLinkStructureViewer(
3654 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3655 AlignmentPanel ap, jarInputStreamProvider jprovider)
3657 final StructureViewerModel stateData = viewerData.getValue();
3660 * Search for any viewer windows already open from other alignment views
3661 * that exactly match the stored structure state
3663 StructureViewerBase comp = findMatchingViewer(viewerData);
3667 linkStructureViewer(ap, comp, stateData);
3672 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3673 * "viewer_"+stateData.viewId
3675 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3677 createChimeraViewer(viewerData, af, jprovider);
3682 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3684 createJmolViewer(viewerData, af, jprovider);
3689 * Create a new Chimera viewer.
3695 protected void createChimeraViewer(
3696 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3697 jarInputStreamProvider jprovider)
3699 StructureViewerModel data = viewerData.getValue();
3700 String chimeraSessionFile = data.getStateData();
3703 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3705 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3706 * 'uniquified' sviewid used to reconstruct the viewer here
3708 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3709 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3712 Set<Entry<File, StructureData>> fileData = data.getFileData()
3714 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3715 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3716 for (Entry<File, StructureData> pdb : fileData)
3718 String filePath = pdb.getValue().getFilePath();
3719 String pdbId = pdb.getValue().getPdbId();
3720 // pdbs.add(new PDBEntry(filePath, pdbId));
3721 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3722 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3723 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3727 boolean colourByChimera = data.isColourByViewer();
3728 boolean colourBySequence = data.isColourWithAlignPanel();
3730 // TODO use StructureViewer as a factory here, see JAL-1761
3731 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3732 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3734 String newViewId = viewerData.getKey();
3736 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3737 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3738 colourBySequence, newViewId);
3739 cvf.setSize(data.getWidth(), data.getHeight());
3740 cvf.setLocation(data.getX(), data.getY());
3744 * Create a new Jmol window. First parse the Jmol state to translate filenames
3745 * loaded into the view, and record the order in which files are shown in the
3746 * Jmol view, so we can add the sequence mappings in same order.
3752 protected void createJmolViewer(
3753 final Entry<String, StructureViewerModel> viewerData,
3754 AlignFrame af, jarInputStreamProvider jprovider)
3756 final StructureViewerModel svattrib = viewerData.getValue();
3757 String state = svattrib.getStateData();
3760 * Pre-2.9: state element value is the Jmol state string
3762 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3765 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3767 state = readJarEntry(jprovider,
3768 getViewerJarEntryName(svattrib.getViewId()));
3771 List<String> pdbfilenames = new ArrayList<String>();
3772 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3773 List<String> pdbids = new ArrayList<String>();
3774 StringBuilder newFileLoc = new StringBuilder(64);
3775 int cp = 0, ncp, ecp;
3776 Map<File, StructureData> oldFiles = svattrib.getFileData();
3777 while ((ncp = state.indexOf("load ", cp)) > -1)
3781 // look for next filename in load statement
3782 newFileLoc.append(state.substring(cp,
3783 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3784 String oldfilenam = state.substring(ncp,
3785 ecp = state.indexOf("\"", ncp));
3786 // recover the new mapping data for this old filename
3787 // have to normalize filename - since Jmol and jalview do
3789 // translation differently.
3790 StructureData filedat = oldFiles.get(new File(oldfilenam));
3791 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3792 pdbfilenames.add(filedat.getFilePath());
3793 pdbids.add(filedat.getPdbId());
3794 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3795 newFileLoc.append("\"");
3796 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3797 // look for next file statement.
3798 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3802 // just append rest of state
3803 newFileLoc.append(state.substring(cp));
3807 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3808 newFileLoc = new StringBuilder(state);
3809 newFileLoc.append("; load append ");
3810 for (File id : oldFiles.keySet())
3812 // add this and any other pdb files that should be present in
3814 StructureData filedat = oldFiles.get(id);
3815 newFileLoc.append(filedat.getFilePath());
3816 pdbfilenames.add(filedat.getFilePath());
3817 pdbids.add(filedat.getPdbId());
3818 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3819 newFileLoc.append(" \"");
3820 newFileLoc.append(filedat.getFilePath());
3821 newFileLoc.append("\"");
3824 newFileLoc.append(";");
3827 if (newFileLoc.length() == 0)
3831 int histbug = newFileLoc.indexOf("history = ");
3835 * change "history = [true|false];" to "history = [1|0];"
3838 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3839 String val = (diff == -1) ? null : newFileLoc
3840 .substring(histbug, diff);
3841 if (val != null && val.length() >= 4)
3843 if (val.contains("e")) // eh? what can it be?
3845 if (val.trim().equals("true"))
3853 newFileLoc.replace(histbug, diff, val);
3858 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3860 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3861 final SequenceI[][] sq = seqmaps
3862 .toArray(new SequenceI[seqmaps.size()][]);
3863 final String fileloc = newFileLoc.toString();
3864 final String sviewid = viewerData.getKey();
3865 final AlignFrame alf = af;
3866 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3867 svattrib.getWidth(), svattrib.getHeight());
3870 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3875 JalviewStructureDisplayI sview = null;
3878 sview = new StructureViewer(alf.alignPanel
3879 .getStructureSelectionManager()).createView(
3880 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3881 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3882 addNewStructureViewer(sview);
3883 } catch (OutOfMemoryError ex)
3885 new OOMWarning("restoring structure view for PDB id " + id,
3886 (OutOfMemoryError) ex.getCause());
3887 if (sview != null && sview.isVisible())
3889 sview.closeViewer(false);
3890 sview.setVisible(false);
3896 } catch (InvocationTargetException ex)
3898 warn("Unexpected error when opening Jmol view.", ex);
3900 } catch (InterruptedException e)
3902 // e.printStackTrace();
3908 * Generates a name for the entry in the project jar file to hold state
3909 * information for a structure viewer
3914 protected String getViewerJarEntryName(String viewId)
3916 return VIEWER_PREFIX + viewId;
3920 * Returns any open frame that matches given structure viewer data. The match
3921 * is based on the unique viewId, or (for older project versions) the frame's
3927 protected StructureViewerBase findMatchingViewer(
3928 Entry<String, StructureViewerModel> viewerData)
3930 final String sviewid = viewerData.getKey();
3931 final StructureViewerModel svattrib = viewerData.getValue();
3932 StructureViewerBase comp = null;
3933 JInternalFrame[] frames = getAllFrames();
3934 for (JInternalFrame frame : frames)
3936 if (frame instanceof StructureViewerBase)
3939 * Post jalview 2.4 schema includes structure view id
3942 && ((StructureViewerBase) frame).getViewId()
3945 comp = (StructureViewerBase) frame;
3946 break; // break added in 2.9
3949 * Otherwise test for matching position and size of viewer frame
3951 else if (frame.getX() == svattrib.getX()
3952 && frame.getY() == svattrib.getY()
3953 && frame.getHeight() == svattrib.getHeight()
3954 && frame.getWidth() == svattrib.getWidth())
3956 comp = (StructureViewerBase) frame;
3957 // no break in faint hope of an exact match on viewId
3965 * Link an AlignmentPanel to an existing structure viewer.
3970 * @param useinViewerSuperpos
3971 * @param usetoColourbyseq
3972 * @param viewerColouring
3974 protected void linkStructureViewer(AlignmentPanel ap,
3975 StructureViewerBase viewer, StructureViewerModel stateData)
3977 // NOTE: if the jalview project is part of a shared session then
3978 // view synchronization should/could be done here.
3980 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
3981 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
3982 final boolean viewerColouring = stateData.isColourByViewer();
3983 Map<File, StructureData> oldFiles = stateData.getFileData();
3986 * Add mapping for sequences in this view to an already open viewer
3988 final AAStructureBindingModel binding = viewer.getBinding();
3989 for (File id : oldFiles.keySet())
3991 // add this and any other pdb files that should be present in the
3993 StructureData filedat = oldFiles.get(id);
3994 String pdbFile = filedat.getFilePath();
3995 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3996 binding.getSsm().setMapping(seq, null, pdbFile,
3997 jalview.io.AppletFormatAdapter.FILE);
3998 binding.addSequenceForStructFile(pdbFile, seq);
4000 // and add the AlignmentPanel's reference to the view panel
4001 viewer.addAlignmentPanel(ap);
4002 if (useinViewerSuperpos)
4004 viewer.useAlignmentPanelForSuperposition(ap);
4008 viewer.excludeAlignmentPanelForSuperposition(ap);
4010 if (usetoColourbyseq)
4012 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4016 viewer.excludeAlignmentPanelForColourbyseq(ap);
4021 * Get all frames within the Desktop.
4025 protected JInternalFrame[] getAllFrames()
4027 JInternalFrame[] frames = null;
4028 // TODO is this necessary - is it safe - risk of hanging?
4033 frames = Desktop.desktop.getAllFrames();
4034 } catch (ArrayIndexOutOfBoundsException e)
4036 // occasional No such child exceptions are thrown here...
4040 } catch (InterruptedException f)
4044 } while (frames == null);
4051 * - minimum version we are comparing against
4053 * - version of data being processsed.
4054 * @return true if version is development/null or evaluates to the same or
4055 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
4057 public static boolean isVersionStringLaterThan(String supported,
4060 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4061 || version.equalsIgnoreCase("Test")
4062 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4064 System.err.println("Assuming project file with "
4065 + (version == null ? "null" : version)
4066 + " is compatible with Jalview version " + supported);
4071 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
4073 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
4075 // convert b to decimal to catch bugfix releases within a series
4076 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
4077 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
4080 float supportedVersionToken = Float.parseFloat(curT);
4081 float myVersiontoken = Float.parseFloat(fileT);
4082 if (supportedVersionToken > myVersiontoken)
4084 // current version is newer than the version that wrote the file
4087 if (supportedVersionToken < myVersiontoken)
4089 // current version is older than the version that wrote the file
4092 } catch (NumberFormatException nfe)
4095 .println("** WARNING: Version comparison failed for tokens ("
4099 + ")\n** Current: '"
4100 + supported + "' and Version: '" + version + "'");
4103 if (currentV.hasMoreElements())
4105 // fileV has no minor version but identical series to current
4112 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4114 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4116 if (newStructureViewers != null)
4118 sview.getBinding().setFinishedLoadingFromArchive(false);
4119 newStructureViewers.add(sview);
4123 protected void setLoadingFinishedForNewStructureViewers()
4125 if (newStructureViewers != null)
4127 for (JalviewStructureDisplayI sview : newStructureViewers)
4129 sview.getBinding().setFinishedLoadingFromArchive(true);
4131 newStructureViewers.clear();
4132 newStructureViewers = null;
4136 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4137 List<SequenceI> hiddenSeqs, Alignment al,
4138 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4139 String viewId, List<JvAnnotRow> autoAlan)
4141 AlignFrame af = null;
4142 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4143 uniqueSeqSetId, viewId);
4145 af.setFileName(file, "Jalview");
4147 for (int i = 0; i < JSEQ.length; i++)
4149 af.viewport.setSequenceColour(af.viewport.getAlignment()
4150 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4153 af.viewport.setGatherViewsHere(view.getGatheredViews());
4155 if (view.getSequenceSetId() != null)
4157 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4159 af.viewport.setSequenceSetId(uniqueSeqSetId);
4162 // propagate shared settings to this new view
4163 af.viewport.setHistoryList(av.getHistoryList());
4164 af.viewport.setRedoList(av.getRedoList());
4168 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4170 // TODO: check if this method can be called repeatedly without
4171 // side-effects if alignpanel already registered.
4172 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4174 // apply Hidden regions to view.
4175 if (hiddenSeqs != null)
4177 for (int s = 0; s < JSEQ.length; s++)
4179 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
4181 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4184 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
4186 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
4189 // jalview.datamodel.SequenceI[] hseqs = new
4190 // jalview.datamodel.SequenceI[hiddenSeqs
4193 // for (int s = 0; s < hiddenSeqs.size(); s++)
4195 // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
4198 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4200 af.viewport.hideSequence(hseqs);
4203 // recover view properties and display parameters
4204 if (view.getViewName() != null)
4206 af.viewport.viewName = view.getViewName();
4207 af.setInitialTabVisible();
4209 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4212 af.viewport.setShowAnnotation(view.getShowAnnotation());
4213 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4215 af.viewport.setColourText(view.getShowColourText());
4217 af.viewport.setConservationSelected(view.getConservationSelected());
4218 af.viewport.setShowJVSuffix(view.getShowFullId());
4219 af.viewport.setRightAlignIds(view.getRightAlignIds());
4220 af.viewport.setFont(
4221 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4222 .getFontSize()), true);
4223 ViewStyleI vs = af.viewport.getViewStyle();
4224 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4225 af.viewport.setViewStyle(vs);
4226 // TODO: allow custom charWidth/Heights to be restored by updating them
4227 // after setting font - which means set above to false
4228 af.viewport.setRenderGaps(view.getRenderGaps());
4229 af.viewport.setWrapAlignment(view.getWrapAlignment());
4230 af.viewport.setShowAnnotation(view.getShowAnnotation());
4232 af.viewport.setShowBoxes(view.getShowBoxes());
4234 af.viewport.setShowText(view.getShowText());
4236 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4237 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4238 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4239 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4240 .isShowUnconserved() : false);
4241 af.viewport.setStartRes(view.getStartRes());
4242 af.viewport.setStartSeq(view.getStartSeq());
4243 af.alignPanel.updateLayout();
4244 ColourSchemeI cs = null;
4245 // apply colourschemes
4246 if (view.getBgColour() != null)
4248 if (view.getBgColour().startsWith("ucs"))
4250 cs = getUserColourScheme(jms, view.getBgColour());
4252 else if (view.getBgColour().startsWith("Annotation"))
4254 AnnotationColours viewAnnColour = view.getAnnotationColours();
4255 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4262 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4267 cs.setThreshold(view.getPidThreshold(), true);
4268 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4272 af.viewport.setGlobalColourScheme(cs);
4273 af.viewport.setColourAppliesToAllGroups(false);
4275 if (view.getConservationSelected() && cs != null)
4277 cs.setConservationInc(view.getConsThreshold());
4280 af.changeColour(cs);
4282 af.viewport.setColourAppliesToAllGroups(true);
4284 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4286 if (view.hasCentreColumnLabels())
4288 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4290 if (view.hasIgnoreGapsinConsensus())
4292 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4295 if (view.hasFollowHighlight())
4297 af.viewport.setFollowHighlight(view.getFollowHighlight());
4299 if (view.hasFollowSelection())
4301 af.viewport.followSelection = view.getFollowSelection();
4303 if (view.hasShowConsensusHistogram())
4305 af.viewport.setShowConsensusHistogram(view
4306 .getShowConsensusHistogram());
4310 af.viewport.setShowConsensusHistogram(true);
4312 if (view.hasShowSequenceLogo())
4314 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4318 af.viewport.setShowSequenceLogo(false);
4320 if (view.hasNormaliseSequenceLogo())
4322 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4324 if (view.hasShowDbRefTooltip())
4326 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4328 if (view.hasShowNPfeatureTooltip())
4330 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4332 if (view.hasShowGroupConsensus())
4334 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4338 af.viewport.setShowGroupConsensus(false);
4340 if (view.hasShowGroupConservation())
4342 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4346 af.viewport.setShowGroupConservation(false);
4349 // recover featre settings
4350 if (jms.getFeatureSettings() != null)
4352 FeaturesDisplayed fdi;
4353 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4354 String[] renderOrder = new String[jms.getFeatureSettings()
4355 .getSettingCount()];
4356 Hashtable featureGroups = new Hashtable();
4357 Hashtable featureColours = new Hashtable();
4358 Hashtable featureOrder = new Hashtable();
4360 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4362 Setting setting = jms.getFeatureSettings().getSetting(fs);
4363 if (setting.hasMincolour())
4365 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
4366 new java.awt.Color(setting.getMincolour()),
4367 new java.awt.Color(setting.getColour()),
4368 setting.getMin(), setting.getMax()) : new GraduatedColor(
4369 new java.awt.Color(setting.getMincolour()),
4370 new java.awt.Color(setting.getColour()), 0, 1);
4371 if (setting.hasThreshold())
4373 gc.setThresh(setting.getThreshold());
4374 gc.setThreshType(setting.getThreshstate());
4376 gc.setAutoScaled(true); // default
4377 if (setting.hasAutoScale())
4379 gc.setAutoScaled(setting.getAutoScale());
4381 if (setting.hasColourByLabel())
4383 gc.setColourByLabel(setting.getColourByLabel());
4385 // and put in the feature colour table.
4386 featureColours.put(setting.getType(), gc);
4390 featureColours.put(setting.getType(),
4391 new java.awt.Color(setting.getColour()));
4393 renderOrder[fs] = setting.getType();
4394 if (setting.hasOrder())
4396 featureOrder.put(setting.getType(), setting.getOrder());
4400 featureOrder.put(setting.getType(), new Float(fs
4401 / jms.getFeatureSettings().getSettingCount()));
4403 if (setting.getDisplay())
4405 fdi.setVisible(setting.getType());
4408 Hashtable fgtable = new Hashtable();
4409 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4411 Group grp = jms.getFeatureSettings().getGroup(gs);
4412 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4414 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4415 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4416 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4417 FeatureRendererSettings frs = new FeatureRendererSettings(
4418 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4419 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4420 .transferSettings(frs);
4424 if (view.getHiddenColumnsCount() > 0)
4426 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4428 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4429 .getHiddenColumns(c).getEnd() // +1
4433 if (view.getCalcIdParam() != null)
4435 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4437 if (calcIdParam != null)
4439 if (recoverCalcIdParam(calcIdParam, af.viewport))
4444 warn("Couldn't recover parameters for "
4445 + calcIdParam.getCalcId());
4450 af.setMenusFromViewport(af.viewport);
4452 // TODO: we don't need to do this if the viewport is aready visible.
4454 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4455 * has a 'cdna/protein complement' view, in which case save it in order to
4456 * populate a SplitFrame once all views have been read in.
4458 String complementaryViewId = view.getComplementId();
4459 if (complementaryViewId == null)
4461 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4463 // recompute any autoannotation
4464 af.alignPanel.updateAnnotation(false, true);
4465 reorderAutoannotation(af, al, autoAlan);
4466 af.alignPanel.alignmentChanged();
4470 splitFrameCandidates.put(view, af);
4475 private ColourSchemeI constructAnnotationColour(
4476 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
4477 JalviewModelSequence jms, boolean checkGroupAnnColour)
4479 boolean propagateAnnColour = false;
4480 ColourSchemeI cs = null;
4481 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4482 if (checkGroupAnnColour && al.getGroups() != null
4483 && al.getGroups().size() > 0)
4485 // pre 2.8.1 behaviour
4486 // check to see if we should transfer annotation colours
4487 propagateAnnColour = true;
4488 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4490 if (sg.cs instanceof AnnotationColourGradient)
4492 propagateAnnColour = false;
4496 // int find annotation
4497 if (annAlignment.getAlignmentAnnotation() != null)
4499 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4501 if (annAlignment.getAlignmentAnnotation()[i].label
4502 .equals(viewAnnColour.getAnnotation()))
4504 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4506 annAlignment.getAlignmentAnnotation()[i]
4507 .setThreshold(new jalview.datamodel.GraphLine(
4508 viewAnnColour.getThreshold(), "Threshold",
4509 java.awt.Color.black)
4514 if (viewAnnColour.getColourScheme().equals("None"))
4516 cs = new AnnotationColourGradient(
4517 annAlignment.getAlignmentAnnotation()[i],
4518 new java.awt.Color(viewAnnColour.getMinColour()),
4519 new java.awt.Color(viewAnnColour.getMaxColour()),
4520 viewAnnColour.getAboveThreshold());
4522 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4524 cs = new AnnotationColourGradient(
4525 annAlignment.getAlignmentAnnotation()[i],
4526 getUserColourScheme(jms,
4527 viewAnnColour.getColourScheme()),
4528 viewAnnColour.getAboveThreshold());
4532 cs = new AnnotationColourGradient(
4533 annAlignment.getAlignmentAnnotation()[i],
4534 ColourSchemeProperty.getColour(al,
4535 viewAnnColour.getColourScheme()),
4536 viewAnnColour.getAboveThreshold());
4538 if (viewAnnColour.hasPerSequence())
4540 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4543 if (viewAnnColour.hasPredefinedColours())
4545 ((AnnotationColourGradient) cs)
4546 .setPredefinedColours(viewAnnColour
4547 .isPredefinedColours());
4549 if (propagateAnnColour && al.getGroups() != null)
4551 // Also use these settings for all the groups
4552 for (int g = 0; g < al.getGroups().size(); g++)
4554 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4562 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4563 * new AnnotationColourGradient(
4564 * annAlignment.getAlignmentAnnotation()[i], new
4565 * java.awt.Color(viewAnnColour. getMinColour()), new
4566 * java.awt.Color(viewAnnColour. getMaxColour()),
4567 * viewAnnColour.getAboveThreshold()); } else
4570 sg.cs = new AnnotationColourGradient(
4571 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4572 viewAnnColour.getAboveThreshold());
4573 if (cs instanceof AnnotationColourGradient)
4575 if (viewAnnColour.hasPerSequence())
4577 ((AnnotationColourGradient) cs)
4578 .setSeqAssociated(viewAnnColour.isPerSequence());
4580 if (viewAnnColour.hasPredefinedColours())
4582 ((AnnotationColourGradient) cs)
4583 .setPredefinedColours(viewAnnColour
4584 .isPredefinedColours());
4600 private void reorderAutoannotation(AlignFrame af, Alignment al,
4601 List<JvAnnotRow> autoAlan)
4603 // copy over visualization settings for autocalculated annotation in the
4605 if (al.getAlignmentAnnotation() != null)
4608 * Kludge for magic autoannotation names (see JAL-811)
4610 String[] magicNames = new String[] { "Consensus", "Quality",
4612 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4613 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4614 for (String nm : magicNames)
4616 visan.put(nm, nullAnnot);
4618 for (JvAnnotRow auan : autoAlan)
4620 visan.put(auan.template.label
4621 + (auan.template.getCalcId() == null ? "" : "\t"
4622 + auan.template.getCalcId()), auan);
4624 int hSize = al.getAlignmentAnnotation().length;
4625 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4626 // work through any autoCalculated annotation already on the view
4627 // removing it if it should be placed in a different location on the
4628 // annotation panel.
4629 List<String> remains = new ArrayList<String>(visan.keySet());
4630 for (int h = 0; h < hSize; h++)
4632 jalview.datamodel.AlignmentAnnotation jalan = al
4633 .getAlignmentAnnotation()[h];
4634 if (jalan.autoCalculated)
4637 JvAnnotRow valan = visan.get(k = jalan.label);
4638 if (jalan.getCalcId() != null)
4640 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4645 // delete the auto calculated row from the alignment
4646 al.deleteAnnotation(jalan, false);
4650 if (valan != nullAnnot)
4652 if (jalan != valan.template)
4654 // newly created autoannotation row instance
4655 // so keep a reference to the visible annotation row
4656 // and copy over all relevant attributes
4657 if (valan.template.graphHeight >= 0)
4660 jalan.graphHeight = valan.template.graphHeight;
4662 jalan.visible = valan.template.visible;
4664 reorder.add(new JvAnnotRow(valan.order, jalan));
4669 // Add any (possibly stale) autocalculated rows that were not appended to
4670 // the view during construction
4671 for (String other : remains)
4673 JvAnnotRow othera = visan.get(other);
4674 if (othera != nullAnnot && othera.template.getCalcId() != null
4675 && othera.template.getCalcId().length() > 0)
4677 reorder.add(othera);
4680 // now put the automatic annotation in its correct place
4681 int s = 0, srt[] = new int[reorder.size()];
4682 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4683 for (JvAnnotRow jvar : reorder)
4686 srt[s++] = jvar.order;
4689 jalview.util.QuickSort.sort(srt, rws);
4690 // and re-insert the annotation at its correct position
4691 for (JvAnnotRow jvar : rws)
4693 al.addAnnotation(jvar.template, jvar.order);
4695 af.alignPanel.adjustAnnotationHeight();
4699 Hashtable skipList = null;
4702 * TODO remove this method
4705 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4706 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4707 * throw new Error("Implementation Error. No skipList defined for this
4708 * Jalview2XML instance."); } return (AlignFrame)
4709 * skipList.get(view.getSequenceSetId()); }
4713 * Check if the Jalview view contained in object should be skipped or not.
4716 * @return true if view's sequenceSetId is a key in skipList
4718 private boolean skipViewport(JalviewModel object)
4720 if (skipList == null)
4725 if (skipList.containsKey(id = object.getJalviewModelSequence()
4726 .getViewport()[0].getSequenceSetId()))
4728 if (Cache.log != null && Cache.log.isDebugEnabled())
4730 Cache.log.debug("Skipping seuqence set id " + id);
4737 public void addToSkipList(AlignFrame af)
4739 if (skipList == null)
4741 skipList = new Hashtable();
4743 skipList.put(af.getViewport().getSequenceSetId(), af);
4746 public void clearSkipList()
4748 if (skipList != null)
4755 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4756 boolean ignoreUnrefed)
4758 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4759 Vector dseqs = null;
4762 // create a list of new dataset sequences
4763 dseqs = new Vector();
4765 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4767 Sequence vamsasSeq = vamsasSet.getSequence(i);
4768 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4770 // create a new dataset
4773 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4774 dseqs.copyInto(dsseqs);
4775 ds = new jalview.datamodel.Alignment(dsseqs);
4776 debug("Created new dataset " + vamsasSet.getDatasetId()
4777 + " for alignment " + System.identityHashCode(al));
4778 addDatasetRef(vamsasSet.getDatasetId(), ds);
4780 // set the dataset for the newly imported alignment.
4781 if (al.getDataset() == null && !ignoreUnrefed)
4790 * sequence definition to create/merge dataset sequence for
4794 * vector to add new dataset sequence to
4796 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4797 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4799 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4801 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4802 SequenceI dsq = null;
4803 if (sq != null && sq.getDatasetSequence() != null)
4805 dsq = sq.getDatasetSequence();
4807 if (sq == null && ignoreUnrefed)
4811 String sqid = vamsasSeq.getDsseqid();
4814 // need to create or add a new dataset sequence reference to this sequence
4817 dsq = seqRefIds.get(sqid);
4822 // make a new dataset sequence
4823 dsq = sq.createDatasetSequence();
4826 // make up a new dataset reference for this sequence
4827 sqid = seqHash(dsq);
4829 dsq.setVamsasId(uniqueSetSuffix + sqid);
4830 seqRefIds.put(sqid, dsq);
4835 dseqs.addElement(dsq);
4840 ds.addSequence(dsq);
4846 { // make this dataset sequence sq's dataset sequence
4847 sq.setDatasetSequence(dsq);
4848 // and update the current dataset alignment
4853 if (!dseqs.contains(dsq))
4860 if (ds.findIndex(dsq) < 0)
4862 ds.addSequence(dsq);
4869 // TODO: refactor this as a merge dataset sequence function
4870 // now check that sq (the dataset sequence) sequence really is the union of
4871 // all references to it
4872 // boolean pre = sq.getStart() < dsq.getStart();
4873 // boolean post = sq.getEnd() > dsq.getEnd();
4877 // StringBuffer sb = new StringBuffer();
4878 String newres = jalview.analysis.AlignSeq.extractGaps(
4879 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4880 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4881 && newres.length() > dsq.getLength())
4883 // Update with the longer sequence.
4887 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4888 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4889 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4890 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4892 dsq.setSequence(newres);
4894 // TODO: merges will never happen if we 'know' we have the real dataset
4895 // sequence - this should be detected when id==dssid
4897 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4898 // + (pre ? "prepended" : "") + " "
4899 // + (post ? "appended" : ""));
4905 * TODO use AlignmentI here and in related methods - needs
4906 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4908 Hashtable<String, Alignment> datasetIds = null;
4910 IdentityHashMap<Alignment, String> dataset2Ids = null;
4912 private Alignment getDatasetFor(String datasetId)
4914 if (datasetIds == null)
4916 datasetIds = new Hashtable<String, Alignment>();
4919 if (datasetIds.containsKey(datasetId))
4921 return datasetIds.get(datasetId);
4926 private void addDatasetRef(String datasetId, Alignment dataset)
4928 if (datasetIds == null)
4930 datasetIds = new Hashtable<String, Alignment>();
4932 datasetIds.put(datasetId, dataset);
4936 * make a new dataset ID for this jalview dataset alignment
4941 private String getDatasetIdRef(Alignment dataset)
4943 if (dataset.getDataset() != null)
4945 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4947 String datasetId = makeHashCode(dataset, null);
4948 if (datasetId == null)
4950 // make a new datasetId and record it
4951 if (dataset2Ids == null)
4953 dataset2Ids = new IdentityHashMap<Alignment, String>();
4957 datasetId = dataset2Ids.get(dataset);
4959 if (datasetId == null)
4961 datasetId = "ds" + dataset2Ids.size() + 1;
4962 dataset2Ids.put(dataset, datasetId);
4968 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4970 for (int d = 0; d < sequence.getDBRefCount(); d++)
4972 DBRef dr = sequence.getDBRef(d);
4973 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4974 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4975 .getVersion(), sequence.getDBRef(d).getAccessionId());
4976 if (dr.getMapping() != null)
4978 entry.setMap(addMapping(dr.getMapping()));
4980 datasetSequence.addDBRef(entry);
4984 private jalview.datamodel.Mapping addMapping(Mapping m)
4986 SequenceI dsto = null;
4987 // Mapping m = dr.getMapping();
4988 int fr[] = new int[m.getMapListFromCount() * 2];
4989 Enumeration f = m.enumerateMapListFrom();
4990 for (int _i = 0; f.hasMoreElements(); _i += 2)
4992 MapListFrom mf = (MapListFrom) f.nextElement();
4993 fr[_i] = mf.getStart();
4994 fr[_i + 1] = mf.getEnd();
4996 int fto[] = new int[m.getMapListToCount() * 2];
4997 f = m.enumerateMapListTo();
4998 for (int _i = 0; f.hasMoreElements(); _i += 2)
5000 MapListTo mf = (MapListTo) f.nextElement();
5001 fto[_i] = mf.getStart();
5002 fto[_i + 1] = mf.getEnd();
5004 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5005 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5006 if (m.getMappingChoice() != null)
5008 MappingChoice mc = m.getMappingChoice();
5009 if (mc.getDseqFor() != null)
5011 String dsfor = "" + mc.getDseqFor();
5012 if (seqRefIds.containsKey(dsfor))
5017 jmap.setTo(seqRefIds.get(dsfor));
5021 frefedSequence.add(new Object[] { dsfor, jmap });
5027 * local sequence definition
5029 Sequence ms = mc.getSequence();
5030 SequenceI djs = null;
5031 String sqid = ms.getDsseqid();
5032 if (sqid != null && sqid.length() > 0)
5035 * recover dataset sequence
5037 djs = seqRefIds.get(sqid);
5042 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5043 sqid = ((Object) ms).toString(); // make up a new hascode for
5044 // undefined dataset sequence hash
5045 // (unlikely to happen)
5051 * make a new dataset sequence and add it to refIds hash
5053 djs = new jalview.datamodel.Sequence(ms.getName(),
5055 djs.setStart(jmap.getMap().getToLowest());
5056 djs.setEnd(jmap.getMap().getToHighest());
5057 djs.setVamsasId(uniqueSetSuffix + sqid);
5059 seqRefIds.put(sqid, djs);
5062 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5071 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5072 boolean keepSeqRefs)
5075 JalviewModel jm = saveState(ap, null, null, null);
5080 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5084 uniqueSetSuffix = "";
5085 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5090 if (this.frefedSequence == null)
5092 frefedSequence = new Vector<Object[]>();
5095 viewportsAdded.clear();
5097 AlignFrame af = loadFromObject(jm, null, false, null);
5098 af.alignPanels.clear();
5099 af.closeMenuItem_actionPerformed(true);
5102 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5103 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5104 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5105 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5106 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5109 return af.alignPanel;
5113 * flag indicating if hashtables should be cleared on finalization TODO this
5114 * flag may not be necessary
5116 private final boolean _cleartables = true;
5118 private Hashtable jvids2vobj;
5123 * @see java.lang.Object#finalize()
5126 protected void finalize() throws Throwable
5128 // really make sure we have no buried refs left.
5133 this.seqRefIds = null;
5134 this.seqsToIds = null;
5138 private void warn(String msg)
5143 private void warn(String msg, Exception e)
5145 if (Cache.log != null)
5149 Cache.log.warn(msg, e);
5153 Cache.log.warn(msg);
5158 System.err.println("Warning: " + msg);
5161 e.printStackTrace();
5166 private void debug(String string)
5168 debug(string, null);
5171 private void debug(String msg, Exception e)
5173 if (Cache.log != null)
5177 Cache.log.debug(msg, e);
5181 Cache.log.debug(msg);
5186 System.err.println("Warning: " + msg);
5189 e.printStackTrace();
5195 * set the object to ID mapping tables used to write/recover objects and XML
5196 * ID strings for the jalview project. If external tables are provided then
5197 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5198 * object goes out of scope. - also populates the datasetIds hashtable with
5199 * alignment objects containing dataset sequences
5202 * Map from ID strings to jalview datamodel
5204 * Map from jalview datamodel to ID strings
5208 public void setObjectMappingTables(Hashtable vobj2jv,
5209 IdentityHashMap jv2vobj)
5211 this.jv2vobj = jv2vobj;
5212 this.vobj2jv = vobj2jv;
5213 Iterator ds = jv2vobj.keySet().iterator();
5215 while (ds.hasNext())
5217 Object jvobj = ds.next();
5218 id = jv2vobj.get(jvobj).toString();
5219 if (jvobj instanceof jalview.datamodel.Alignment)
5221 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5223 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5226 else if (jvobj instanceof jalview.datamodel.Sequence)
5228 // register sequence object so the XML parser can recover it.
5229 if (seqRefIds == null)
5231 seqRefIds = new HashMap<String, SequenceI>();
5233 if (seqsToIds == null)
5235 seqsToIds = new IdentityHashMap<SequenceI, String>();
5237 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5238 seqsToIds.put((SequenceI) jvobj, id);
5240 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5243 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5244 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5245 if (jvann.annotationId == null)
5247 jvann.annotationId = anid;
5249 if (!jvann.annotationId.equals(anid))
5251 // TODO verify that this is the correct behaviour
5252 this.warn("Overriding Annotation ID for " + anid
5253 + " from different id : " + jvann.annotationId);
5254 jvann.annotationId = anid;
5257 else if (jvobj instanceof String)
5259 if (jvids2vobj == null)
5261 jvids2vobj = new Hashtable();
5262 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5267 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5273 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5274 * objects created from the project archive. If string is null (default for
5275 * construction) then suffix will be set automatically.
5279 public void setUniqueSetSuffix(String string)
5281 uniqueSetSuffix = string;
5286 * uses skipList2 as the skipList for skipping views on sequence sets
5287 * associated with keys in the skipList
5291 public void setSkipList(Hashtable skipList2)
5293 skipList = skipList2;
5297 * Reads the jar entry of given name and returns its contents, or null if the
5298 * entry is not found.
5301 * @param jarEntryName
5304 protected String readJarEntry(jarInputStreamProvider jprovider,
5305 String jarEntryName)
5307 String result = null;
5308 BufferedReader in = null;
5313 * Reopen the jar input stream and traverse its entries to find a matching
5316 JarInputStream jin = jprovider.getJarInputStream();
5317 JarEntry entry = null;
5320 entry = jin.getNextJarEntry();
5321 } while (entry != null && !entry.getName().equals(jarEntryName));
5325 StringBuilder out = new StringBuilder(256);
5326 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5329 while ((data = in.readLine()) != null)
5333 result = out.toString();
5337 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5339 } catch (Exception ex)
5341 ex.printStackTrace();
5349 } catch (IOException e)
5360 * Returns an incrementing counter (0, 1, 2...)
5364 private synchronized int nextCounter()