2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.analysis.Conservation;
24 import jalview.api.FeatureColourI;
25 import jalview.api.ViewStyleI;
26 import jalview.api.structures.JalviewStructureDisplayI;
27 import jalview.bin.Cache;
28 import jalview.datamodel.AlignedCodonFrame;
29 import jalview.datamodel.Alignment;
30 import jalview.datamodel.AlignmentAnnotation;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.RnaViewerModel;
34 import jalview.datamodel.SequenceGroup;
35 import jalview.datamodel.SequenceI;
36 import jalview.datamodel.StructureViewerModel;
37 import jalview.datamodel.StructureViewerModel.StructureData;
38 import jalview.ext.varna.RnaModel;
39 import jalview.gui.StructureViewer.ViewerType;
40 import jalview.schemabinding.version2.AlcodMap;
41 import jalview.schemabinding.version2.AlcodonFrame;
42 import jalview.schemabinding.version2.Annotation;
43 import jalview.schemabinding.version2.AnnotationColours;
44 import jalview.schemabinding.version2.AnnotationElement;
45 import jalview.schemabinding.version2.CalcIdParam;
46 import jalview.schemabinding.version2.DBRef;
47 import jalview.schemabinding.version2.Features;
48 import jalview.schemabinding.version2.Group;
49 import jalview.schemabinding.version2.HiddenColumns;
50 import jalview.schemabinding.version2.JGroup;
51 import jalview.schemabinding.version2.JSeq;
52 import jalview.schemabinding.version2.JalviewModel;
53 import jalview.schemabinding.version2.JalviewModelSequence;
54 import jalview.schemabinding.version2.MapListFrom;
55 import jalview.schemabinding.version2.MapListTo;
56 import jalview.schemabinding.version2.Mapping;
57 import jalview.schemabinding.version2.MappingChoice;
58 import jalview.schemabinding.version2.OtherData;
59 import jalview.schemabinding.version2.PdbentryItem;
60 import jalview.schemabinding.version2.Pdbids;
61 import jalview.schemabinding.version2.Property;
62 import jalview.schemabinding.version2.RnaViewer;
63 import jalview.schemabinding.version2.SecondaryStructure;
64 import jalview.schemabinding.version2.Sequence;
65 import jalview.schemabinding.version2.SequenceSet;
66 import jalview.schemabinding.version2.SequenceSetProperties;
67 import jalview.schemabinding.version2.Setting;
68 import jalview.schemabinding.version2.StructureState;
69 import jalview.schemabinding.version2.ThresholdLine;
70 import jalview.schemabinding.version2.Tree;
71 import jalview.schemabinding.version2.UserColours;
72 import jalview.schemabinding.version2.Viewport;
73 import jalview.schemes.AnnotationColourGradient;
74 import jalview.schemes.ColourSchemeI;
75 import jalview.schemes.ColourSchemeProperty;
76 import jalview.schemes.FeatureColour;
77 import jalview.schemes.ResidueColourScheme;
78 import jalview.schemes.ResidueProperties;
79 import jalview.schemes.UserColourScheme;
80 import jalview.structure.StructureSelectionManager;
81 import jalview.structures.models.AAStructureBindingModel;
82 import jalview.util.MessageManager;
83 import jalview.util.Platform;
84 import jalview.util.StringUtils;
85 import jalview.util.jarInputStreamProvider;
86 import jalview.viewmodel.AlignmentViewport;
87 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
88 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
89 import jalview.ws.jws2.Jws2Discoverer;
90 import jalview.ws.jws2.dm.AAConSettings;
91 import jalview.ws.jws2.jabaws2.Jws2Instance;
92 import jalview.ws.params.ArgumentI;
93 import jalview.ws.params.AutoCalcSetting;
94 import jalview.ws.params.WsParamSetI;
96 import java.awt.Color;
97 import java.awt.Rectangle;
98 import java.io.BufferedReader;
99 import java.io.DataInputStream;
100 import java.io.DataOutputStream;
102 import java.io.FileInputStream;
103 import java.io.FileOutputStream;
104 import java.io.IOException;
105 import java.io.InputStreamReader;
106 import java.io.OutputStreamWriter;
107 import java.io.PrintWriter;
108 import java.lang.reflect.InvocationTargetException;
109 import java.net.MalformedURLException;
111 import java.util.ArrayList;
112 import java.util.Arrays;
113 import java.util.Enumeration;
114 import java.util.HashMap;
115 import java.util.HashSet;
116 import java.util.Hashtable;
117 import java.util.IdentityHashMap;
118 import java.util.Iterator;
119 import java.util.LinkedHashMap;
120 import java.util.List;
121 import java.util.Map;
122 import java.util.Map.Entry;
123 import java.util.Set;
124 import java.util.Vector;
125 import java.util.jar.JarEntry;
126 import java.util.jar.JarInputStream;
127 import java.util.jar.JarOutputStream;
129 import javax.swing.JInternalFrame;
130 import javax.swing.JOptionPane;
131 import javax.swing.SwingUtilities;
133 import org.exolab.castor.xml.Marshaller;
134 import org.exolab.castor.xml.Unmarshaller;
137 * Write out the current jalview desktop state as a Jalview XML stream.
139 * Note: the vamsas objects referred to here are primitive versions of the
140 * VAMSAS project schema elements - they are not the same and most likely never
144 * @version $Revision: 1.134 $
146 public class Jalview2XML
148 private static final String VIEWER_PREFIX = "viewer_";
150 private static final String RNA_PREFIX = "rna_";
152 private static final String UTF_8 = "UTF-8";
154 // use this with nextCounter() to make unique names for entities
155 private int counter = 0;
158 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
159 * of sequence objects are created.
161 IdentityHashMap<SequenceI, String> seqsToIds = null;
164 * jalview XML Sequence ID to jalview sequence object reference (both dataset
165 * and alignment sequences. Populated as XML reps of sequence objects are
168 Map<String, SequenceI> seqRefIds = null;
170 Map<String, SequenceI> incompleteSeqs = null;
172 List<SeqFref> frefedSequence = null;
174 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
177 * Map of reconstructed AlignFrame objects that appear to have come from
178 * SplitFrame objects (have a dna/protein complement view).
180 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
183 * Map from displayed rna structure models to their saved session state jar
186 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
189 * create/return unique hash string for sq
192 * @return new or existing unique string for sq
194 String seqHash(SequenceI sq)
196 if (seqsToIds == null)
200 if (seqsToIds.containsKey(sq))
202 return seqsToIds.get(sq);
206 // create sequential key
207 String key = "sq" + (seqsToIds.size() + 1);
208 key = makeHashCode(sq, key); // check we don't have an external reference
210 seqsToIds.put(sq, key);
219 if (seqRefIds != null)
223 if (seqsToIds != null)
227 if (incompleteSeqs != null)
229 incompleteSeqs.clear();
237 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
238 // seqRefIds = new Hashtable();
239 // seqsToIds = new IdentityHashMap();
245 if (seqsToIds == null)
247 seqsToIds = new IdentityHashMap<SequenceI, String>();
249 if (seqRefIds == null)
251 seqRefIds = new HashMap<String, SequenceI>();
253 if (incompleteSeqs == null)
255 incompleteSeqs = new HashMap<String, SequenceI>();
257 if (frefedSequence == null)
259 frefedSequence = new ArrayList<SeqFref>();
267 public Jalview2XML(boolean raiseGUI)
269 this.raiseGUI = raiseGUI;
273 * base class for resolving forward references to sequences by their ID
278 abstract class SeqFref
284 public SeqFref(String _sref, String type)
290 public String getSref()
295 public SequenceI getSrefSeq()
297 return seqRefIds.get(sref);
300 public boolean isResolvable()
302 return seqRefIds.get(sref) != null;
305 public SequenceI getSrefDatasetSeq()
307 SequenceI sq = seqRefIds.get(sref);
310 while (sq.getDatasetSequence() != null)
312 sq = sq.getDatasetSequence();
319 * @return true if the forward reference was fully resolved
321 abstract boolean resolve();
324 public String toString()
326 return type + " reference to " + sref;
331 * create forward reference for a mapping
337 public SeqFref newMappingRef(final String sref,
338 final jalview.datamodel.Mapping _jmap)
340 SeqFref fref = new SeqFref(sref, "Mapping")
342 public jalview.datamodel.Mapping jmap = _jmap;
347 SequenceI seq = getSrefDatasetSeq();
359 public SeqFref newAlcodMapRef(final String sref,
360 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
363 SeqFref fref = new SeqFref(sref, "Codon Frame")
365 AlignedCodonFrame cf = _cf;
367 public jalview.datamodel.Mapping mp = _jmap;
370 public boolean isResolvable()
372 return super.isResolvable() && mp.getTo() != null;
378 SequenceI seq = getSrefDatasetSeq();
383 cf.addMap(seq, mp.getTo(), mp.getMap());
390 public void resolveFrefedSequences()
392 Iterator<SeqFref> nextFref = frefedSequence.iterator();
393 int toresolve = frefedSequence.size();
394 int unresolved = 0, failedtoresolve = 0;
395 while (nextFref.hasNext())
397 SeqFref ref = nextFref.next();
398 if (ref.isResolvable())
410 } catch (Exception x)
413 .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
426 System.err.println("Jalview Project Import: There were " + unresolved
427 + " forward references left unresolved on the stack.");
429 if (failedtoresolve > 0)
431 System.err.println("SERIOUS! " + failedtoresolve
432 + " resolvable forward references failed to resolve.");
434 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
436 System.err.println("Jalview Project Import: There are "
437 + incompleteSeqs.size()
438 + " sequences which may have incomplete metadata.");
439 if (incompleteSeqs.size() < 10)
441 for (SequenceI s : incompleteSeqs.values())
443 System.err.println(s.toString());
449 .println("Too many to report. Skipping output of incomplete sequences.");
455 * This maintains a map of viewports, the key being the seqSetId. Important to
456 * set historyItem and redoList for multiple views
458 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
460 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
462 String uniqueSetSuffix = "";
465 * List of pdbfiles added to Jar
467 List<String> pdbfiles = null;
469 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
470 public void saveState(File statefile)
472 FileOutputStream fos = null;
475 fos = new FileOutputStream(statefile);
476 JarOutputStream jout = new JarOutputStream(fos);
479 } catch (Exception e)
481 // TODO: inform user of the problem - they need to know if their data was
483 if (errorMessage == null)
485 errorMessage = "Couldn't write Jalview Archive to output file '"
486 + statefile + "' - See console error log for details";
490 errorMessage += "(output file was '" + statefile + "')";
500 } catch (IOException e)
510 * Writes a jalview project archive to the given Jar output stream.
514 public void saveState(JarOutputStream jout)
516 AlignFrame[] frames = Desktop.getAlignFrames();
522 saveAllFrames(Arrays.asList(frames), jout);
526 * core method for storing state for a set of AlignFrames.
529 * - frames involving all data to be exported (including containing
532 * - project output stream
534 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
536 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
539 * ensure cached data is clear before starting
541 // todo tidy up seqRefIds, seqsToIds initialisation / reset
543 splitFrameCandidates.clear();
548 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
549 // //////////////////////////////////////////////////
551 List<String> shortNames = new ArrayList<String>();
552 List<String> viewIds = new ArrayList<String>();
555 for (int i = frames.size() - 1; i > -1; i--)
557 AlignFrame af = frames.get(i);
561 .containsKey(af.getViewport().getSequenceSetId()))
566 String shortName = makeFilename(af, shortNames);
568 int ap, apSize = af.alignPanels.size();
570 for (ap = 0; ap < apSize; ap++)
572 AlignmentPanel apanel = af.alignPanels.get(ap);
573 String fileName = apSize == 1 ? shortName : ap + shortName;
574 if (!fileName.endsWith(".xml"))
576 fileName = fileName + ".xml";
579 saveState(apanel, fileName, jout, viewIds);
581 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
583 if (!dsses.containsKey(dssid))
585 dsses.put(dssid, af);
590 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
596 } catch (Exception foo)
601 } catch (Exception ex)
603 // TODO: inform user of the problem - they need to know if their data was
605 if (errorMessage == null)
607 errorMessage = "Couldn't write Jalview Archive - see error output for details";
609 ex.printStackTrace();
614 * Generates a distinct file name, based on the title of the AlignFrame, by
615 * appending _n for increasing n until an unused name is generated. The new
616 * name (without its extension) is added to the list.
620 * @return the generated name, with .xml extension
622 protected String makeFilename(AlignFrame af, List<String> namesUsed)
624 String shortName = af.getTitle();
626 if (shortName.indexOf(File.separatorChar) > -1)
628 shortName = shortName.substring(shortName
629 .lastIndexOf(File.separatorChar) + 1);
634 while (namesUsed.contains(shortName))
636 if (shortName.endsWith("_" + (count - 1)))
638 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
641 shortName = shortName.concat("_" + count);
645 namesUsed.add(shortName);
647 if (!shortName.endsWith(".xml"))
649 shortName = shortName + ".xml";
654 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
655 public boolean saveAlignment(AlignFrame af, String jarFile,
660 FileOutputStream fos = new FileOutputStream(jarFile);
661 JarOutputStream jout = new JarOutputStream(fos);
662 List<AlignFrame> frames = new ArrayList<AlignFrame>();
664 // resolve splitframes
665 if (af.getViewport().getCodingComplement() != null)
667 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
673 saveAllFrames(frames, jout);
677 } catch (Exception foo)
683 } catch (Exception ex)
685 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
686 ex.printStackTrace();
691 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
692 String fileName, JarOutputStream jout)
695 for (String dssids : dsses.keySet())
697 AlignFrame _af = dsses.get(dssids);
698 String jfileName = fileName + " Dataset for " + _af.getTitle();
699 if (!jfileName.endsWith(".xml"))
701 jfileName = jfileName + ".xml";
703 saveState(_af.alignPanel, jfileName, true, jout, null);
708 * create a JalviewModel from an alignment view and marshall it to a
712 * panel to create jalview model for
714 * name of alignment panel written to output stream
721 public JalviewModel saveState(AlignmentPanel ap, String fileName,
722 JarOutputStream jout, List<String> viewIds)
724 return saveState(ap, fileName, false, jout, viewIds);
728 * create a JalviewModel from an alignment view and marshall it to a
732 * panel to create jalview model for
734 * name of alignment panel written to output stream
736 * when true, only write the dataset for the alignment, not the data
737 * associated with the view.
743 public JalviewModel saveState(AlignmentPanel ap, String fileName,
744 boolean storeDS, JarOutputStream jout, List<String> viewIds)
748 viewIds = new ArrayList<String>();
753 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
755 AlignViewport av = ap.av;
757 JalviewModel object = new JalviewModel();
758 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
760 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
761 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
762 "Development Build"));
765 * rjal is full height alignment, jal is actual alignment with full metadata
766 * but excludes hidden sequences.
768 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
770 if (av.hasHiddenRows())
772 rjal = jal.getHiddenSequences().getFullAlignment();
775 SequenceSet vamsasSet = new SequenceSet();
777 JalviewModelSequence jms = new JalviewModelSequence();
779 vamsasSet.setGapChar(jal.getGapCharacter() + "");
781 if (jal.getDataset() != null)
783 // dataset id is the dataset's hashcode
784 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
787 // switch jal and the dataset
788 jal = jal.getDataset();
792 if (jal.getProperties() != null)
794 Enumeration en = jal.getProperties().keys();
795 while (en.hasMoreElements())
797 String key = en.nextElement().toString();
798 SequenceSetProperties ssp = new SequenceSetProperties();
800 ssp.setValue(jal.getProperties().get(key).toString());
801 vamsasSet.addSequenceSetProperties(ssp);
806 Set<String> calcIdSet = new HashSet<String>();
807 // record the set of vamsas sequence XML POJO we create.
808 HashMap<String, Sequence> vamsasSetIds = new HashMap<String, Sequence>();
810 for (final SequenceI jds : rjal.getSequences())
812 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
813 : jds.getDatasetSequence();
814 String id = seqHash(jds);
815 if (vamsasSetIds.get(id) == null)
817 if (seqRefIds.get(id) != null && !storeDS)
819 // This happens for two reasons: 1. multiple views are being
821 // 2. the hashCode has collided with another sequence's code. This
823 // HAPPEN! (PF00072.15.stk does this)
824 // JBPNote: Uncomment to debug writing out of files that do not read
825 // back in due to ArrayOutOfBoundExceptions.
826 // System.err.println("vamsasSeq backref: "+id+"");
827 // System.err.println(jds.getName()+"
828 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
829 // System.err.println("Hashcode: "+seqHash(jds));
830 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
831 // System.err.println(rsq.getName()+"
832 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
833 // System.err.println("Hashcode: "+seqHash(rsq));
837 vamsasSeq = createVamsasSequence(id, jds);
838 vamsasSet.addSequence(vamsasSeq);
839 vamsasSetIds.put(id, vamsasSeq);
840 seqRefIds.put(id, jds);
844 jseq.setStart(jds.getStart());
845 jseq.setEnd(jds.getEnd());
846 jseq.setColour(av.getSequenceColour(jds).getRGB());
848 jseq.setId(id); // jseq id should be a string not a number
851 // Store any sequences this sequence represents
852 if (av.hasHiddenRows())
854 // use rjal, contains the full height alignment
855 jseq.setHidden(av.getAlignment().getHiddenSequences()
858 if (av.isHiddenRepSequence(jds))
860 jalview.datamodel.SequenceI[] reps = av
861 .getRepresentedSequences(jds).getSequencesInOrder(rjal);
863 for (int h = 0; h < reps.length; h++)
867 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
872 // mark sequence as reference - if it is the reference for this view
875 jseq.setViewreference(jds == jal.getSeqrep());
879 // TODO: omit sequence features from each alignment view's XML dump if we
880 // are storing dataset
881 if (jds.getSequenceFeatures() != null)
883 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
885 while (index < sf.length)
887 Features features = new Features();
889 features.setBegin(sf[index].getBegin());
890 features.setEnd(sf[index].getEnd());
891 features.setDescription(sf[index].getDescription());
892 features.setType(sf[index].getType());
893 features.setFeatureGroup(sf[index].getFeatureGroup());
894 features.setScore(sf[index].getScore());
895 if (sf[index].links != null)
897 for (int l = 0; l < sf[index].links.size(); l++)
899 OtherData keyValue = new OtherData();
900 keyValue.setKey("LINK_" + l);
901 keyValue.setValue(sf[index].links.elementAt(l).toString());
902 features.addOtherData(keyValue);
905 if (sf[index].otherDetails != null)
908 Iterator<String> keys = sf[index].otherDetails.keySet()
910 while (keys.hasNext())
913 OtherData keyValue = new OtherData();
914 keyValue.setKey(key);
915 keyValue.setValue(sf[index].otherDetails.get(key).toString());
916 features.addOtherData(keyValue);
920 jseq.addFeatures(features);
925 if (jdatasq.getAllPDBEntries() != null)
927 Enumeration en = jdatasq.getAllPDBEntries().elements();
928 while (en.hasMoreElements())
930 Pdbids pdb = new Pdbids();
931 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
934 String pdbId = entry.getId();
936 pdb.setType(entry.getType());
939 * Store any structure views associated with this sequence. This
940 * section copes with duplicate entries in the project, so a dataset
941 * only view *should* be coped with sensibly.
943 // This must have been loaded, is it still visible?
944 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
945 String matchedFile = null;
946 for (int f = frames.length - 1; f > -1; f--)
948 if (frames[f] instanceof StructureViewerBase)
950 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
951 matchedFile = saveStructureState(ap, jds, pdb, entry,
952 viewIds, matchedFile, viewFrame);
954 * Only store each structure viewer's state once in the project
955 * jar. First time through only (storeDS==false)
957 String viewId = viewFrame.getViewId();
958 if (!storeDS && !viewIds.contains(viewId))
963 String viewerState = viewFrame.getStateInfo();
964 writeJarEntry(jout, getViewerJarEntryName(viewId),
965 viewerState.getBytes());
966 } catch (IOException e)
968 System.err.println("Error saving viewer state: "
975 if (matchedFile != null || entry.getFile() != null)
977 if (entry.getFile() != null)
980 matchedFile = entry.getFile();
982 pdb.setFile(matchedFile); // entry.getFile());
983 if (pdbfiles == null)
985 pdbfiles = new ArrayList<String>();
988 if (!pdbfiles.contains(pdbId))
991 copyFileToJar(jout, matchedFile, pdbId);
995 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
997 PdbentryItem item = new PdbentryItem();
998 Hashtable properties = entry.getProperty();
999 Enumeration en2 = properties.keys();
1000 while (en2.hasMoreElements())
1002 Property prop = new Property();
1003 String key = en2.nextElement().toString();
1005 prop.setValue(properties.get(key).toString());
1006 item.addProperty(prop);
1008 pdb.addPdbentryItem(item);
1011 jseq.addPdbids(pdb);
1015 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1020 if (!storeDS && av.hasHiddenRows())
1022 jal = av.getAlignment();
1026 if (storeDS && jal.getCodonFrames() != null)
1028 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1029 for (AlignedCodonFrame acf : jac)
1031 AlcodonFrame alc = new AlcodonFrame();
1032 if (acf.getProtMappings() != null
1033 && acf.getProtMappings().length > 0)
1035 boolean hasMap = false;
1036 SequenceI[] dnas = acf.getdnaSeqs();
1037 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1038 for (int m = 0; m < pmaps.length; m++)
1040 AlcodMap alcmap = new AlcodMap();
1041 alcmap.setDnasq(seqHash(dnas[m]));
1042 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1044 alc.addAlcodMap(alcmap);
1049 vamsasSet.addAlcodonFrame(alc);
1052 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1054 // AlcodonFrame alc = new AlcodonFrame();
1055 // vamsasSet.addAlcodonFrame(alc);
1056 // for (int p = 0; p < acf.aaWidth; p++)
1058 // Alcodon cmap = new Alcodon();
1059 // if (acf.codons[p] != null)
1061 // // Null codons indicate a gapped column in the translated peptide
1063 // cmap.setPos1(acf.codons[p][0]);
1064 // cmap.setPos2(acf.codons[p][1]);
1065 // cmap.setPos3(acf.codons[p][2]);
1067 // alc.addAlcodon(cmap);
1069 // if (acf.getProtMappings() != null
1070 // && acf.getProtMappings().length > 0)
1072 // SequenceI[] dnas = acf.getdnaSeqs();
1073 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1074 // for (int m = 0; m < pmaps.length; m++)
1076 // AlcodMap alcmap = new AlcodMap();
1077 // alcmap.setDnasq(seqHash(dnas[m]));
1078 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1080 // alc.addAlcodMap(alcmap);
1087 // /////////////////////////////////
1088 if (!storeDS && av.currentTree != null)
1090 // FIND ANY ASSOCIATED TREES
1091 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1092 if (Desktop.desktop != null)
1094 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1096 for (int t = 0; t < frames.length; t++)
1098 if (frames[t] instanceof TreePanel)
1100 TreePanel tp = (TreePanel) frames[t];
1102 if (tp.treeCanvas.av.getAlignment() == jal)
1104 Tree tree = new Tree();
1105 tree.setTitle(tp.getTitle());
1106 tree.setCurrentTree((av.currentTree == tp.getTree()));
1107 tree.setNewick(tp.getTree().toString());
1108 tree.setThreshold(tp.treeCanvas.threshold);
1110 tree.setFitToWindow(tp.fitToWindow.getState());
1111 tree.setFontName(tp.getTreeFont().getName());
1112 tree.setFontSize(tp.getTreeFont().getSize());
1113 tree.setFontStyle(tp.getTreeFont().getStyle());
1114 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1116 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1117 tree.setShowDistances(tp.distanceMenu.getState());
1119 tree.setHeight(tp.getHeight());
1120 tree.setWidth(tp.getWidth());
1121 tree.setXpos(tp.getX());
1122 tree.setYpos(tp.getY());
1123 tree.setId(makeHashCode(tp, null));
1133 * store forward refs from an annotationRow to any groups
1135 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1138 for (SequenceI sq : jal.getSequences())
1140 // Store annotation on dataset sequences only
1141 AlignmentAnnotation[] aa = sq.getAnnotation();
1142 if (aa != null && aa.length > 0)
1144 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1151 if (jal.getAlignmentAnnotation() != null)
1153 // Store the annotation shown on the alignment.
1154 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1155 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1160 if (jal.getGroups() != null)
1162 JGroup[] groups = new JGroup[jal.getGroups().size()];
1164 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1166 JGroup jGroup = new JGroup();
1167 groups[++i] = jGroup;
1169 jGroup.setStart(sg.getStartRes());
1170 jGroup.setEnd(sg.getEndRes());
1171 jGroup.setName(sg.getName());
1172 if (groupRefs.containsKey(sg))
1174 // group has references so set its ID field
1175 jGroup.setId(groupRefs.get(sg));
1179 if (sg.cs.conservationApplied())
1181 jGroup.setConsThreshold(sg.cs.getConservationInc());
1183 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1185 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1189 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1192 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1194 jGroup.setColour("AnnotationColourGradient");
1195 jGroup.setAnnotationColours(constructAnnotationColours(
1196 (jalview.schemes.AnnotationColourGradient) sg.cs,
1199 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1201 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1205 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1208 jGroup.setPidThreshold(sg.cs.getThreshold());
1211 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1212 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1213 jGroup.setDisplayText(sg.getDisplayText());
1214 jGroup.setColourText(sg.getColourText());
1215 jGroup.setTextCol1(sg.textColour.getRGB());
1216 jGroup.setTextCol2(sg.textColour2.getRGB());
1217 jGroup.setTextColThreshold(sg.thresholdTextColour);
1218 jGroup.setShowUnconserved(sg.getShowNonconserved());
1219 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1220 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1221 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1222 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1223 for (SequenceI seq : sg.getSequences())
1225 jGroup.addSeq(seqHash(seq));
1229 jms.setJGroup(groups);
1233 // /////////SAVE VIEWPORT
1234 Viewport view = new Viewport();
1235 view.setTitle(ap.alignFrame.getTitle());
1236 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1237 av.getSequenceSetId()));
1238 view.setId(av.getViewId());
1239 if (av.getCodingComplement() != null)
1241 view.setComplementId(av.getCodingComplement().getViewId());
1243 view.setViewName(av.viewName);
1244 view.setGatheredViews(av.isGatherViewsHere());
1246 Rectangle size = ap.av.getExplodedGeometry();
1247 Rectangle position = size;
1250 size = ap.alignFrame.getBounds();
1251 if (av.getCodingComplement() != null)
1253 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1261 view.setXpos(position.x);
1262 view.setYpos(position.y);
1264 view.setWidth(size.width);
1265 view.setHeight(size.height);
1267 view.setStartRes(av.startRes);
1268 view.setStartSeq(av.startSeq);
1270 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1272 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1275 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1277 AnnotationColours ac = constructAnnotationColours(
1278 (jalview.schemes.AnnotationColourGradient) av
1279 .getGlobalColourScheme(),
1282 view.setAnnotationColours(ac);
1283 view.setBgColour("AnnotationColourGradient");
1287 view.setBgColour(ColourSchemeProperty.getColourName(av
1288 .getGlobalColourScheme()));
1291 ColourSchemeI cs = av.getGlobalColourScheme();
1295 if (cs.conservationApplied())
1297 view.setConsThreshold(cs.getConservationInc());
1298 if (cs instanceof jalview.schemes.UserColourScheme)
1300 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1304 if (cs instanceof ResidueColourScheme)
1306 view.setPidThreshold(cs.getThreshold());
1310 view.setConservationSelected(av.getConservationSelected());
1311 view.setPidSelected(av.getAbovePIDThreshold());
1312 view.setFontName(av.font.getName());
1313 view.setFontSize(av.font.getSize());
1314 view.setFontStyle(av.font.getStyle());
1315 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1316 view.setRenderGaps(av.isRenderGaps());
1317 view.setShowAnnotation(av.isShowAnnotation());
1318 view.setShowBoxes(av.getShowBoxes());
1319 view.setShowColourText(av.getColourText());
1320 view.setShowFullId(av.getShowJVSuffix());
1321 view.setRightAlignIds(av.isRightAlignIds());
1322 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1323 view.setShowText(av.getShowText());
1324 view.setShowUnconserved(av.getShowUnconserved());
1325 view.setWrapAlignment(av.getWrapAlignment());
1326 view.setTextCol1(av.getTextColour().getRGB());
1327 view.setTextCol2(av.getTextColour2().getRGB());
1328 view.setTextColThreshold(av.getThresholdTextColour());
1329 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1330 view.setShowSequenceLogo(av.isShowSequenceLogo());
1331 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1332 view.setShowGroupConsensus(av.isShowGroupConsensus());
1333 view.setShowGroupConservation(av.isShowGroupConservation());
1334 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1335 view.setShowDbRefTooltip(av.isShowDBRefs());
1336 view.setFollowHighlight(av.isFollowHighlight());
1337 view.setFollowSelection(av.followSelection);
1338 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1339 if (av.getFeaturesDisplayed() != null)
1341 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1343 String[] renderOrder = ap.getSeqPanel().seqCanvas
1344 .getFeatureRenderer().getRenderOrder()
1345 .toArray(new String[0]);
1347 Vector<String> settingsAdded = new Vector<String>();
1348 if (renderOrder != null)
1350 for (String featureType : renderOrder)
1352 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1353 .getFeatureRenderer().getFeatureStyle(featureType);
1354 Setting setting = new Setting();
1355 setting.setType(featureType);
1356 if (!fcol.isSimpleColour())
1358 setting.setColour(fcol.getMaxColour().getRGB());
1359 setting.setMincolour(fcol.getMinColour().getRGB());
1360 setting.setMin(fcol.getMin());
1361 setting.setMax(fcol.getMax());
1362 setting.setColourByLabel(fcol.isColourByLabel());
1363 setting.setAutoScale(fcol.isAutoScaled());
1364 setting.setThreshold(fcol.getThreshold());
1365 // -1 = No threshold, 0 = Below, 1 = Above
1366 setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
1367 .isBelowThreshold() ? 0 : -1));
1371 setting.setColour(fcol.getColour().getRGB());
1374 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1376 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1377 .getOrder(featureType);
1380 setting.setOrder(rorder);
1382 fs.addSetting(setting);
1383 settingsAdded.addElement(featureType);
1387 // is groups actually supposed to be a map here ?
1388 Iterator<String> en = ap.getSeqPanel().seqCanvas
1389 .getFeatureRenderer().getFeatureGroups().iterator();
1390 Vector<String> groupsAdded = new Vector<String>();
1391 while (en.hasNext())
1393 String grp = en.next();
1394 if (groupsAdded.contains(grp))
1398 Group g = new Group();
1400 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1401 .getFeatureRenderer().checkGroupVisibility(grp, false))
1404 groupsAdded.addElement(grp);
1406 jms.setFeatureSettings(fs);
1409 if (av.hasHiddenColumns())
1411 if (av.getColumnSelection() == null
1412 || av.getColumnSelection().getHiddenColumns() == null)
1414 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1418 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1421 int[] region = av.getColumnSelection().getHiddenColumns()
1423 HiddenColumns hc = new HiddenColumns();
1424 hc.setStart(region[0]);
1425 hc.setEnd(region[1]);
1426 view.addHiddenColumns(hc);
1430 if (calcIdSet.size() > 0)
1432 for (String calcId : calcIdSet)
1434 if (calcId.trim().length() > 0)
1436 CalcIdParam cidp = createCalcIdParam(calcId, av);
1437 // Some calcIds have no parameters.
1440 view.addCalcIdParam(cidp);
1446 jms.addViewport(view);
1448 object.setJalviewModelSequence(jms);
1449 object.getVamsasModel().addSequenceSet(vamsasSet);
1451 if (jout != null && fileName != null)
1453 // We may not want to write the object to disk,
1454 // eg we can copy the alignViewport to a new view object
1455 // using save and then load
1458 System.out.println("Writing jar entry " + fileName);
1459 JarEntry entry = new JarEntry(fileName);
1460 jout.putNextEntry(entry);
1461 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1463 Marshaller marshaller = new Marshaller(pout);
1464 marshaller.marshal(object);
1467 } catch (Exception ex)
1469 // TODO: raise error in GUI if marshalling failed.
1470 ex.printStackTrace();
1477 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1478 * for each viewer, with
1480 * <li>viewer geometry (position, size, split pane divider location)</li>
1481 * <li>index of the selected structure in the viewer (currently shows gapped
1483 * <li>the id of the annotation holding RNA secondary structure</li>
1484 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1486 * Varna viewer state is also written out (in native Varna XML) to separate
1487 * project jar entries. A separate entry is written for each RNA structure
1488 * displayed, with the naming convention
1490 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1498 * @param storeDataset
1500 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1501 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1502 boolean storeDataset)
1504 if (Desktop.desktop == null)
1508 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1509 for (int f = frames.length - 1; f > -1; f--)
1511 if (frames[f] instanceof AppVarna)
1513 AppVarna varna = (AppVarna) frames[f];
1515 * link the sequence to every viewer that is showing it and is linked to
1516 * its alignment panel
1518 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1520 String viewId = varna.getViewId();
1521 RnaViewer rna = new RnaViewer();
1522 rna.setViewId(viewId);
1523 rna.setTitle(varna.getTitle());
1524 rna.setXpos(varna.getX());
1525 rna.setYpos(varna.getY());
1526 rna.setWidth(varna.getWidth());
1527 rna.setHeight(varna.getHeight());
1528 rna.setDividerLocation(varna.getDividerLocation());
1529 rna.setSelectedRna(varna.getSelectedIndex());
1530 jseq.addRnaViewer(rna);
1533 * Store each Varna panel's state once in the project per sequence.
1534 * First time through only (storeDataset==false)
1536 // boolean storeSessions = false;
1537 // String sequenceViewId = viewId + seqsToIds.get(jds);
1538 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1540 // viewIds.add(sequenceViewId);
1541 // storeSessions = true;
1543 for (RnaModel model : varna.getModels())
1545 if (model.seq == jds)
1548 * VARNA saves each view (sequence or alignment secondary
1549 * structure, gapped or trimmed) as a separate XML file
1551 String jarEntryName = rnaSessions.get(model);
1552 if (jarEntryName == null)
1555 String varnaStateFile = varna.getStateInfo(model.rna);
1556 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1557 copyFileToJar(jout, varnaStateFile, jarEntryName);
1558 rnaSessions.put(model, jarEntryName);
1560 SecondaryStructure ss = new SecondaryStructure();
1561 String annotationId = varna.getAnnotation(jds).annotationId;
1562 ss.setAnnotationId(annotationId);
1563 ss.setViewerState(jarEntryName);
1564 ss.setGapped(model.gapped);
1565 ss.setTitle(model.title);
1566 rna.addSecondaryStructure(ss);
1575 * Copy the contents of a file to a new entry added to the output jar
1579 * @param jarEntryName
1581 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1582 String jarEntryName)
1584 DataInputStream dis = null;
1587 File file = new File(infilePath);
1588 if (file.exists() && jout != null)
1590 dis = new DataInputStream(new FileInputStream(file));
1591 byte[] data = new byte[(int) file.length()];
1592 dis.readFully(data);
1593 writeJarEntry(jout, jarEntryName, data);
1595 } catch (Exception ex)
1597 ex.printStackTrace();
1605 } catch (IOException e)
1614 * Write the data to a new entry of given name in the output jar file
1617 * @param jarEntryName
1619 * @throws IOException
1621 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1622 byte[] data) throws IOException
1626 System.out.println("Writing jar entry " + jarEntryName);
1627 jout.putNextEntry(new JarEntry(jarEntryName));
1628 DataOutputStream dout = new DataOutputStream(jout);
1629 dout.write(data, 0, data.length);
1636 * Save the state of a structure viewer
1641 * the archive XML element under which to save the state
1644 * @param matchedFile
1648 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1649 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1650 String matchedFile, StructureViewerBase viewFrame)
1652 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1655 * Look for any bindings for this viewer to the PDB file of interest
1656 * (including part matches excluding chain id)
1658 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1660 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1661 final String pdbId = pdbentry.getId();
1662 if (!pdbId.equals(entry.getId())
1663 && !(entry.getId().length() > 4 && entry.getId()
1664 .toLowerCase().startsWith(pdbId.toLowerCase())))
1667 * not interested in a binding to a different PDB entry here
1671 if (matchedFile == null)
1673 matchedFile = pdbentry.getFile();
1675 else if (!matchedFile.equals(pdbentry.getFile()))
1678 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1679 + pdbentry.getFile());
1683 // can get at it if the ID
1684 // match is ambiguous (e.g.
1687 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1689 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1690 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1692 StructureState state = new StructureState();
1693 state.setVisible(true);
1694 state.setXpos(viewFrame.getX());
1695 state.setYpos(viewFrame.getY());
1696 state.setWidth(viewFrame.getWidth());
1697 state.setHeight(viewFrame.getHeight());
1698 final String viewId = viewFrame.getViewId();
1699 state.setViewId(viewId);
1700 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1701 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1702 state.setColourByJmol(viewFrame.isColouredByViewer());
1703 state.setType(viewFrame.getViewerType().toString());
1704 pdb.addStructureState(state);
1711 private AnnotationColours constructAnnotationColours(
1712 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1713 JalviewModelSequence jms)
1715 AnnotationColours ac = new AnnotationColours();
1716 ac.setAboveThreshold(acg.getAboveThreshold());
1717 ac.setThreshold(acg.getAnnotationThreshold());
1718 ac.setAnnotation(acg.getAnnotation());
1719 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1721 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1726 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1730 ac.setMaxColour(acg.getMaxColour().getRGB());
1731 ac.setMinColour(acg.getMinColour().getRGB());
1732 ac.setPerSequence(acg.isSeqAssociated());
1733 ac.setPredefinedColours(acg.isPredefinedColours());
1737 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1738 IdentityHashMap<SequenceGroup, String> groupRefs,
1739 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1740 SequenceSet vamsasSet)
1743 for (int i = 0; i < aa.length; i++)
1745 Annotation an = new Annotation();
1747 AlignmentAnnotation annotation = aa[i];
1748 if (annotation.annotationId != null)
1750 annotationIds.put(annotation.annotationId, annotation);
1753 an.setId(annotation.annotationId);
1755 an.setVisible(annotation.visible);
1757 an.setDescription(annotation.description);
1759 if (annotation.sequenceRef != null)
1761 // 2.9 JAL-1781 xref on sequence id rather than name
1762 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1764 if (annotation.groupRef != null)
1766 String groupIdr = groupRefs.get(annotation.groupRef);
1767 if (groupIdr == null)
1769 // make a locally unique String
1771 annotation.groupRef,
1772 groupIdr = ("" + System.currentTimeMillis()
1773 + annotation.groupRef.getName() + groupRefs
1776 an.setGroupRef(groupIdr.toString());
1779 // store all visualization attributes for annotation
1780 an.setGraphHeight(annotation.graphHeight);
1781 an.setCentreColLabels(annotation.centreColLabels);
1782 an.setScaleColLabels(annotation.scaleColLabel);
1783 an.setShowAllColLabels(annotation.showAllColLabels);
1784 an.setBelowAlignment(annotation.belowAlignment);
1786 if (annotation.graph > 0)
1789 an.setGraphType(annotation.graph);
1790 an.setGraphGroup(annotation.graphGroup);
1791 if (annotation.getThreshold() != null)
1793 ThresholdLine line = new ThresholdLine();
1794 line.setLabel(annotation.getThreshold().label);
1795 line.setValue(annotation.getThreshold().value);
1796 line.setColour(annotation.getThreshold().colour.getRGB());
1797 an.setThresholdLine(line);
1805 an.setLabel(annotation.label);
1807 if (annotation == av.getAlignmentQualityAnnot()
1808 || annotation == av.getAlignmentConservationAnnotation()
1809 || annotation == av.getAlignmentConsensusAnnotation()
1810 || annotation.autoCalculated)
1812 // new way of indicating autocalculated annotation -
1813 an.setAutoCalculated(annotation.autoCalculated);
1815 if (annotation.hasScore())
1817 an.setScore(annotation.getScore());
1820 if (annotation.getCalcId() != null)
1822 calcIdSet.add(annotation.getCalcId());
1823 an.setCalcId(annotation.getCalcId());
1825 if (annotation.hasProperties())
1827 for (String pr : annotation.getProperties())
1829 Property prop = new Property();
1831 prop.setValue(annotation.getProperty(pr));
1832 an.addProperty(prop);
1836 AnnotationElement ae;
1837 if (annotation.annotations != null)
1839 an.setScoreOnly(false);
1840 for (int a = 0; a < annotation.annotations.length; a++)
1842 if ((annotation == null) || (annotation.annotations[a] == null))
1847 ae = new AnnotationElement();
1848 if (annotation.annotations[a].description != null)
1850 ae.setDescription(annotation.annotations[a].description);
1852 if (annotation.annotations[a].displayCharacter != null)
1854 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1857 if (!Float.isNaN(annotation.annotations[a].value))
1859 ae.setValue(annotation.annotations[a].value);
1863 if (annotation.annotations[a].secondaryStructure > ' ')
1865 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1869 if (annotation.annotations[a].colour != null
1870 && annotation.annotations[a].colour != java.awt.Color.black)
1872 ae.setColour(annotation.annotations[a].colour.getRGB());
1875 an.addAnnotationElement(ae);
1876 if (annotation.autoCalculated)
1878 // only write one non-null entry into the annotation row -
1879 // sufficient to get the visualization attributes necessary to
1887 an.setScoreOnly(true);
1889 if (!storeDS || (storeDS && !annotation.autoCalculated))
1891 // skip autocalculated annotation - these are only provided for
1893 vamsasSet.addAnnotation(an);
1899 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1901 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1902 if (settings != null)
1904 CalcIdParam vCalcIdParam = new CalcIdParam();
1905 vCalcIdParam.setCalcId(calcId);
1906 vCalcIdParam.addServiceURL(settings.getServiceURI());
1907 // generic URI allowing a third party to resolve another instance of the
1908 // service used for this calculation
1909 for (String urls : settings.getServiceURLs())
1911 vCalcIdParam.addServiceURL(urls);
1913 vCalcIdParam.setVersion("1.0");
1914 if (settings.getPreset() != null)
1916 WsParamSetI setting = settings.getPreset();
1917 vCalcIdParam.setName(setting.getName());
1918 vCalcIdParam.setDescription(setting.getDescription());
1922 vCalcIdParam.setName("");
1923 vCalcIdParam.setDescription("Last used parameters");
1925 // need to be able to recover 1) settings 2) user-defined presets or
1926 // recreate settings from preset 3) predefined settings provided by
1927 // service - or settings that can be transferred (or discarded)
1928 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1930 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1931 // todo - decide if updateImmediately is needed for any projects.
1933 return vCalcIdParam;
1938 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1941 if (calcIdParam.getVersion().equals("1.0"))
1943 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1944 .getPreferredServiceFor(calcIdParam.getServiceURL());
1945 if (service != null)
1947 WsParamSetI parmSet = null;
1950 parmSet = service.getParamStore().parseServiceParameterFile(
1951 calcIdParam.getName(), calcIdParam.getDescription(),
1952 calcIdParam.getServiceURL(),
1953 calcIdParam.getParameters().replace("|\\n|", "\n"));
1954 } catch (IOException x)
1956 warn("Couldn't parse parameter data for "
1957 + calcIdParam.getCalcId(), x);
1960 List<ArgumentI> argList = null;
1961 if (calcIdParam.getName().length() > 0)
1963 parmSet = service.getParamStore()
1964 .getPreset(calcIdParam.getName());
1965 if (parmSet != null)
1967 // TODO : check we have a good match with settings in AACon -
1968 // otherwise we'll need to create a new preset
1973 argList = parmSet.getArguments();
1976 AAConSettings settings = new AAConSettings(
1977 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1978 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1979 calcIdParam.isNeedsUpdate());
1984 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1988 throw new Error(MessageManager.formatMessage(
1989 "error.unsupported_version_calcIdparam",
1990 new Object[] { calcIdParam.toString() }));
1994 * External mapping between jalview objects and objects yielding a valid and
1995 * unique object ID string. This is null for normal Jalview project IO, but
1996 * non-null when a jalview project is being read or written as part of a
1999 IdentityHashMap jv2vobj = null;
2002 * Construct a unique ID for jvobj using either existing bindings or if none
2003 * exist, the result of the hashcode call for the object.
2006 * jalview data object
2007 * @return unique ID for referring to jvobj
2009 private String makeHashCode(Object jvobj, String altCode)
2011 if (jv2vobj != null)
2013 Object id = jv2vobj.get(jvobj);
2016 return id.toString();
2018 // check string ID mappings
2019 if (jvids2vobj != null && jvobj instanceof String)
2021 id = jvids2vobj.get(jvobj);
2025 return id.toString();
2027 // give up and warn that something has gone wrong
2028 warn("Cannot find ID for object in external mapping : " + jvobj);
2034 * return local jalview object mapped to ID, if it exists
2038 * @return null or object bound to idcode
2040 private Object retrieveExistingObj(String idcode)
2042 if (idcode != null && vobj2jv != null)
2044 return vobj2jv.get(idcode);
2050 * binding from ID strings from external mapping table to jalview data model
2053 private Hashtable vobj2jv;
2055 private Sequence createVamsasSequence(String id, SequenceI jds)
2057 return createVamsasSequence(true, id, jds, null);
2060 private Sequence createVamsasSequence(boolean recurse, String id,
2061 SequenceI jds, SequenceI parentseq)
2063 Sequence vamsasSeq = new Sequence();
2064 vamsasSeq.setId(id);
2065 vamsasSeq.setName(jds.getName());
2066 vamsasSeq.setSequence(jds.getSequenceAsString());
2067 vamsasSeq.setDescription(jds.getDescription());
2068 jalview.datamodel.DBRefEntry[] dbrefs = null;
2069 if (jds.getDatasetSequence() != null)
2071 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2075 // seqId==dsseqid so we can tell which sequences really are
2076 // dataset sequences only
2077 vamsasSeq.setDsseqid(id);
2078 dbrefs = jds.getDBRefs();
2079 if (parentseq == null)
2086 for (int d = 0; d < dbrefs.length; d++)
2088 DBRef dbref = new DBRef();
2089 dbref.setSource(dbrefs[d].getSource());
2090 dbref.setVersion(dbrefs[d].getVersion());
2091 dbref.setAccessionId(dbrefs[d].getAccessionId());
2092 if (dbrefs[d].hasMap())
2094 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2096 dbref.setMapping(mp);
2098 vamsasSeq.addDBRef(dbref);
2104 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2105 SequenceI parentseq, SequenceI jds, boolean recurse)
2108 if (jmp.getMap() != null)
2112 jalview.util.MapList mlst = jmp.getMap();
2113 List<int[]> r = mlst.getFromRanges();
2114 for (int[] range : r)
2116 MapListFrom mfrom = new MapListFrom();
2117 mfrom.setStart(range[0]);
2118 mfrom.setEnd(range[1]);
2119 mp.addMapListFrom(mfrom);
2121 r = mlst.getToRanges();
2122 for (int[] range : r)
2124 MapListTo mto = new MapListTo();
2125 mto.setStart(range[0]);
2126 mto.setEnd(range[1]);
2127 mp.addMapListTo(mto);
2129 mp.setMapFromUnit(mlst.getFromRatio());
2130 mp.setMapToUnit(mlst.getToRatio());
2131 if (jmp.getTo() != null)
2133 MappingChoice mpc = new MappingChoice();
2135 // check/create ID for the sequence referenced by getTo()
2138 SequenceI ps = null;
2139 if (parentseq != jmp.getTo()
2140 && parentseq.getDatasetSequence() != jmp.getTo())
2142 // chaining dbref rather than a handshaking one
2143 jmpid = seqHash(ps = jmp.getTo());
2147 jmpid = seqHash(ps = parentseq);
2149 mpc.setDseqFor(jmpid);
2150 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2152 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2153 seqRefIds.put(mpc.getDseqFor(), ps);
2157 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2160 mp.setMappingChoice(mpc);
2166 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2167 List<UserColourScheme> userColours, JalviewModelSequence jms)
2170 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2171 boolean newucs = false;
2172 if (!userColours.contains(ucs))
2174 userColours.add(ucs);
2177 id = "ucs" + userColours.indexOf(ucs);
2180 // actually create the scheme's entry in the XML model
2181 java.awt.Color[] colours = ucs.getColours();
2182 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2183 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2185 for (int i = 0; i < colours.length; i++)
2187 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2188 col.setName(ResidueProperties.aa[i]);
2189 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2190 jbucs.addColour(col);
2192 if (ucs.getLowerCaseColours() != null)
2194 colours = ucs.getLowerCaseColours();
2195 for (int i = 0; i < colours.length; i++)
2197 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2198 col.setName(ResidueProperties.aa[i].toLowerCase());
2199 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2200 jbucs.addColour(col);
2205 uc.setUserColourScheme(jbucs);
2206 jms.addUserColours(uc);
2212 jalview.schemes.UserColourScheme getUserColourScheme(
2213 JalviewModelSequence jms, String id)
2215 UserColours[] uc = jms.getUserColours();
2216 UserColours colours = null;
2218 for (int i = 0; i < uc.length; i++)
2220 if (uc[i].getId().equals(id))
2228 java.awt.Color[] newColours = new java.awt.Color[24];
2230 for (int i = 0; i < 24; i++)
2232 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2233 .getUserColourScheme().getColour(i).getRGB(), 16));
2236 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2239 if (colours.getUserColourScheme().getColourCount() > 24)
2241 newColours = new java.awt.Color[23];
2242 for (int i = 0; i < 23; i++)
2244 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2245 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2247 ucs.setLowerCaseColours(newColours);
2254 * contains last error message (if any) encountered by XML loader.
2256 String errorMessage = null;
2259 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2260 * exceptions are raised during project XML parsing
2262 public boolean attemptversion1parse = true;
2265 * Load a jalview project archive from a jar file
2268 * - HTTP URL or filename
2270 public AlignFrame loadJalviewAlign(final String file)
2273 jalview.gui.AlignFrame af = null;
2277 // create list to store references for any new Jmol viewers created
2278 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2279 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2280 // Workaround is to make sure caller implements the JarInputStreamProvider
2282 // so we can re-open the jar input stream for each entry.
2284 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2285 af = loadJalviewAlign(jprovider);
2287 } catch (MalformedURLException e)
2289 errorMessage = "Invalid URL format for '" + file + "'";
2295 SwingUtilities.invokeAndWait(new Runnable()
2300 setLoadingFinishedForNewStructureViewers();
2303 } catch (Exception x)
2305 System.err.println("Error loading alignment: " + x.getMessage());
2311 private jarInputStreamProvider createjarInputStreamProvider(
2312 final String file) throws MalformedURLException
2315 errorMessage = null;
2316 uniqueSetSuffix = null;
2318 viewportsAdded.clear();
2319 frefedSequence = null;
2321 if (file.startsWith("http://"))
2323 url = new URL(file);
2325 final URL _url = url;
2326 return new jarInputStreamProvider()
2330 public JarInputStream getJarInputStream() throws IOException
2334 return new JarInputStream(_url.openStream());
2338 return new JarInputStream(new FileInputStream(file));
2343 public String getFilename()
2351 * Recover jalview session from a jalview project archive. Caller may
2352 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2353 * themselves. Any null fields will be initialised with default values,
2354 * non-null fields are left alone.
2359 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2361 errorMessage = null;
2362 if (uniqueSetSuffix == null)
2364 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2366 if (seqRefIds == null)
2370 AlignFrame af = null, _af = null;
2371 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2372 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2373 final String file = jprovider.getFilename();
2376 JarInputStream jin = null;
2377 JarEntry jarentry = null;
2382 jin = jprovider.getJarInputStream();
2383 for (int i = 0; i < entryCount; i++)
2385 jarentry = jin.getNextJarEntry();
2388 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2390 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2391 JalviewModel object = new JalviewModel();
2393 Unmarshaller unmar = new Unmarshaller(object);
2394 unmar.setValidation(false);
2395 object = (JalviewModel) unmar.unmarshal(in);
2396 if (true) // !skipViewport(object))
2398 _af = loadFromObject(object, file, true, jprovider);
2400 && object.getJalviewModelSequence().getViewportCount() > 0)
2404 // store a reference to the first view
2407 if (_af.viewport.isGatherViewsHere())
2409 // if this is a gathered view, keep its reference since
2410 // after gathering views, only this frame will remain
2412 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2414 // Save dataset to register mappings once all resolved
2415 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2416 af.viewport.getAlignment().getDataset());
2421 else if (jarentry != null)
2423 // Some other file here.
2426 } while (jarentry != null);
2427 resolveFrefedSequences();
2428 } catch (IOException ex)
2430 ex.printStackTrace();
2431 errorMessage = "Couldn't locate Jalview XML file : " + file;
2432 System.err.println("Exception whilst loading jalview XML file : "
2434 } catch (Exception ex)
2436 System.err.println("Parsing as Jalview Version 2 file failed.");
2437 ex.printStackTrace(System.err);
2438 if (attemptversion1parse)
2440 // Is Version 1 Jar file?
2443 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2444 } catch (Exception ex2)
2446 System.err.println("Exception whilst loading as jalviewXMLV1:");
2447 ex2.printStackTrace();
2451 if (Desktop.instance != null)
2453 Desktop.instance.stopLoading();
2457 System.out.println("Successfully loaded archive file");
2460 ex.printStackTrace();
2462 System.err.println("Exception whilst loading jalview XML file : "
2464 } catch (OutOfMemoryError e)
2466 // Don't use the OOM Window here
2467 errorMessage = "Out of memory loading jalview XML file";
2468 System.err.println("Out of memory whilst loading jalview XML file");
2469 e.printStackTrace();
2473 * Regather multiple views (with the same sequence set id) to the frame (if
2474 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2475 * views instead of separate frames. Note this doesn't restore a state where
2476 * some expanded views in turn have tabbed views - the last "first tab" read
2477 * in will play the role of gatherer for all.
2479 for (AlignFrame fr : gatherToThisFrame.values())
2481 Desktop.instance.gatherViews(fr);
2484 restoreSplitFrames();
2485 for (AlignmentI ds : importedDatasets.keySet())
2487 if (ds.getCodonFrames() != null)
2489 StructureSelectionManager.getStructureSelectionManager(
2490 Desktop.instance).registerMappings(ds.getCodonFrames());
2493 if (errorMessage != null)
2498 if (Desktop.instance != null)
2500 Desktop.instance.stopLoading();
2507 * Try to reconstruct and display SplitFrame windows, where each contains
2508 * complementary dna and protein alignments. Done by pairing up AlignFrame
2509 * objects (created earlier) which have complementary viewport ids associated.
2511 protected void restoreSplitFrames()
2513 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2514 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2515 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2518 * Identify the DNA alignments
2520 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2523 AlignFrame af = candidate.getValue();
2524 if (af.getViewport().getAlignment().isNucleotide())
2526 dna.put(candidate.getKey().getId(), af);
2531 * Try to match up the protein complements
2533 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2536 AlignFrame af = candidate.getValue();
2537 if (!af.getViewport().getAlignment().isNucleotide())
2539 String complementId = candidate.getKey().getComplementId();
2540 // only non-null complements should be in the Map
2541 if (complementId != null && dna.containsKey(complementId))
2543 final AlignFrame dnaFrame = dna.get(complementId);
2544 SplitFrame sf = createSplitFrame(dnaFrame, af);
2545 addedToSplitFrames.add(dnaFrame);
2546 addedToSplitFrames.add(af);
2547 if (af.viewport.isGatherViewsHere())
2556 * Open any that we failed to pair up (which shouldn't happen!) as
2557 * standalone AlignFrame's.
2559 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2562 AlignFrame af = candidate.getValue();
2563 if (!addedToSplitFrames.contains(af))
2565 Viewport view = candidate.getKey();
2566 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2568 System.err.println("Failed to restore view " + view.getTitle()
2569 + " to split frame");
2574 * Gather back into tabbed views as flagged.
2576 for (SplitFrame sf : gatherTo)
2578 Desktop.instance.gatherViews(sf);
2581 splitFrameCandidates.clear();
2585 * Construct and display one SplitFrame holding DNA and protein alignments.
2588 * @param proteinFrame
2591 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2592 AlignFrame proteinFrame)
2594 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2595 String title = MessageManager.getString("label.linked_view_title");
2596 int width = (int) dnaFrame.getBounds().getWidth();
2597 int height = (int) (dnaFrame.getBounds().getHeight()
2598 + proteinFrame.getBounds().getHeight() + 50);
2601 * SplitFrame location is saved to both enclosed frames
2603 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2604 Desktop.addInternalFrame(splitFrame, title, width, height);
2607 * And compute cDNA consensus (couldn't do earlier with consensus as
2608 * mappings were not yet present)
2610 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2616 * check errorMessage for a valid error message and raise an error box in the
2617 * GUI or write the current errorMessage to stderr and then clear the error
2620 protected void reportErrors()
2622 reportErrors(false);
2625 protected void reportErrors(final boolean saving)
2627 if (errorMessage != null)
2629 final String finalErrorMessage = errorMessage;
2632 javax.swing.SwingUtilities.invokeLater(new Runnable()
2637 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2638 finalErrorMessage, "Error "
2639 + (saving ? "saving" : "loading")
2640 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2646 System.err.println("Problem loading Jalview file: " + errorMessage);
2649 errorMessage = null;
2652 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2655 * when set, local views will be updated from view stored in JalviewXML
2656 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2657 * sync if this is set to true.
2659 private final boolean updateLocalViews = false;
2662 * Returns the path to a temporary file holding the PDB file for the given PDB
2663 * id. The first time of asking, searches for a file of that name in the
2664 * Jalview project jar, and copies it to a new temporary file. Any repeat
2665 * requests just return the path to the file previously created.
2671 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2674 if (alreadyLoadedPDB.containsKey(pdbId))
2676 return alreadyLoadedPDB.get(pdbId).toString();
2679 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2681 if (tempFile != null)
2683 alreadyLoadedPDB.put(pdbId, tempFile);
2689 * Copies the jar entry of given name to a new temporary file and returns the
2690 * path to the file, or null if the entry is not found.
2693 * @param jarEntryName
2695 * a prefix for the temporary file name, must be at least three
2698 * null or original file - so new file can be given the same suffix
2702 protected String copyJarEntry(jarInputStreamProvider jprovider,
2703 String jarEntryName, String prefix, String origFile)
2705 BufferedReader in = null;
2706 PrintWriter out = null;
2707 String suffix = ".tmp";
2708 if (origFile == null)
2710 origFile = jarEntryName;
2712 int sfpos = origFile.lastIndexOf(".");
2713 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2715 suffix = "." + origFile.substring(sfpos + 1);
2719 JarInputStream jin = jprovider.getJarInputStream();
2721 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2722 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2723 * FileInputStream(jprovider)); }
2726 JarEntry entry = null;
2729 entry = jin.getNextJarEntry();
2730 } while (entry != null && !entry.getName().equals(jarEntryName));
2733 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2734 File outFile = File.createTempFile(prefix, suffix);
2735 outFile.deleteOnExit();
2736 out = new PrintWriter(new FileOutputStream(outFile));
2739 while ((data = in.readLine()) != null)
2744 String t = outFile.getAbsolutePath();
2749 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2751 } catch (Exception ex)
2753 ex.printStackTrace();
2761 } catch (IOException e)
2775 private class JvAnnotRow
2777 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2784 * persisted version of annotation row from which to take vis properties
2786 public jalview.datamodel.AlignmentAnnotation template;
2789 * original position of the annotation row in the alignment
2795 * Load alignment frame from jalview XML DOM object
2800 * filename source string
2801 * @param loadTreesAndStructures
2802 * when false only create Viewport
2804 * data source provider
2805 * @return alignment frame created from view stored in DOM
2807 AlignFrame loadFromObject(JalviewModel object, String file,
2808 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2810 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2811 Sequence[] vamsasSeq = vamsasSet.getSequence();
2813 JalviewModelSequence jms = object.getJalviewModelSequence();
2815 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2818 // ////////////////////////////////
2821 List<SequenceI> hiddenSeqs = null;
2823 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2825 boolean multipleView = false;
2826 SequenceI referenceseqForView = null;
2827 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2828 int vi = 0; // counter in vamsasSeq array
2829 for (int i = 0; i < jseqs.length; i++)
2831 String seqId = jseqs[i].getId();
2833 SequenceI tmpSeq = seqRefIds.get(seqId);
2836 if (!incompleteSeqs.containsKey(seqId))
2838 // may not need this check, but keep it for at least 2.9,1 release
2839 if (tmpSeq.getStart() != jseqs[i].getStart()
2840 || tmpSeq.getEnd() != jseqs[i].getEnd())
2843 .println("Warning JAL-2154 regression: updating start/end for sequence "
2844 + tmpSeq.toString() + " to " + jseqs[i]);
2849 incompleteSeqs.remove(seqId);
2851 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2853 // most likely we are reading a dataset XML document so
2854 // update from vamsasSeq section of XML for this sequence
2855 tmpSeq.setName(vamsasSeq[vi].getName());
2856 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2857 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2862 // reading multiple views, so vamsasSeq set is a subset of JSeq
2863 multipleView = true;
2865 tmpSeq.setStart(jseqs[i].getStart());
2866 tmpSeq.setEnd(jseqs[i].getEnd());
2867 tmpseqs.add(tmpSeq);
2871 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2872 vamsasSeq[vi].getSequence());
2873 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2874 tmpSeq.setStart(jseqs[i].getStart());
2875 tmpSeq.setEnd(jseqs[i].getEnd());
2876 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2877 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2878 tmpseqs.add(tmpSeq);
2882 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2884 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2887 if (jseqs[i].getHidden())
2889 if (hiddenSeqs == null)
2891 hiddenSeqs = new ArrayList<SequenceI>();
2894 hiddenSeqs.add(tmpSeq);
2899 // Create the alignment object from the sequence set
2900 // ///////////////////////////////
2901 SequenceI[] orderedSeqs = tmpseqs
2902 .toArray(new SequenceI[tmpseqs.size()]);
2904 AlignmentI al = null;
2905 // so we must create or recover the dataset alignment before going further
2906 // ///////////////////////////////
2907 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2909 // older jalview projects do not have a dataset - so creat alignment and
2911 al = new Alignment(orderedSeqs);
2912 al.setDataset(null);
2916 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2919 // we are importing a dataset record, so
2920 // recover reference to an alignment already materialsed as dataset
2921 al = getDatasetFor(vamsasSet.getDatasetId());
2925 // materialse the alignment
2926 al = new Alignment(orderedSeqs);
2930 addDatasetRef(vamsasSet.getDatasetId(), al);
2933 // finally, verify all data in vamsasSet is actually present in al
2934 // passing on flag indicating if it is actually a stored dataset
2935 recoverDatasetFor(vamsasSet, al, isdsal);
2938 if (referenceseqForView != null)
2940 al.setSeqrep(referenceseqForView);
2942 // / Add the alignment properties
2943 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2945 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2946 al.setProperty(ssp.getKey(), ssp.getValue());
2949 // ///////////////////////////////
2951 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2954 // load sequence features, database references and any associated PDB
2955 // structures for the alignment
2957 // prior to 2.10, this part would only be executed the first time a
2958 // sequence was encountered, but not afterwards.
2959 // now, for 2.10 projects, this is also done if the xml doc includes
2960 // dataset sequences not actually present in any particular view.
2962 for (int i = 0; i < vamsasSeq.length; i++)
2964 if (jseqs[i].getFeaturesCount() > 0)
2966 Features[] features = jseqs[i].getFeatures();
2967 for (int f = 0; f < features.length; f++)
2969 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2970 features[f].getType(), features[f].getDescription(),
2971 features[f].getStatus(), features[f].getBegin(),
2972 features[f].getEnd(), features[f].getFeatureGroup());
2974 sf.setScore(features[f].getScore());
2975 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2977 OtherData keyValue = features[f].getOtherData(od);
2978 if (keyValue.getKey().startsWith("LINK"))
2980 sf.addLink(keyValue.getValue());
2984 sf.setValue(keyValue.getKey(), keyValue.getValue());
2988 // adds feature to datasequence's feature set (since Jalview 2.10)
2989 al.getSequenceAt(i).addSequenceFeature(sf);
2992 if (vamsasSeq[i].getDBRefCount() > 0)
2994 // adds dbrefs to datasequence's set (since Jalview 2.10)
2996 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
2997 : al.getSequenceAt(i).getDatasetSequence(),
3000 if (jseqs[i].getPdbidsCount() > 0)
3002 Pdbids[] ids = jseqs[i].getPdbids();
3003 for (int p = 0; p < ids.length; p++)
3005 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
3006 entry.setId(ids[p].getId());
3007 if (ids[p].getType() != null)
3009 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3011 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3015 entry.setType(PDBEntry.Type.FILE);
3018 if (ids[p].getFile() != null)
3020 if (!pdbloaded.containsKey(ids[p].getFile()))
3022 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3027 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3030 if (ids[p].getPdbentryItem() != null)
3032 entry.setProperty(new Hashtable());
3033 for (PdbentryItem item : ids[p].getPdbentryItem())
3035 for (Property pr : item.getProperty())
3037 entry.getProperty().put(pr.getName(), pr.getValue());
3041 StructureSelectionManager.getStructureSelectionManager(
3042 Desktop.instance).registerPDBEntry(entry);
3043 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3044 if (al.getSequenceAt(i).getDatasetSequence() != null)
3046 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3050 al.getSequenceAt(i).addPDBId(entry);
3055 } // end !multipleview
3057 // ///////////////////////////////
3058 // LOAD SEQUENCE MAPPINGS
3060 if (vamsasSet.getAlcodonFrameCount() > 0)
3062 // TODO Potentially this should only be done once for all views of an
3064 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3065 for (int i = 0; i < alc.length; i++)
3067 AlignedCodonFrame cf = new AlignedCodonFrame();
3068 if (alc[i].getAlcodMapCount() > 0)
3070 AlcodMap[] maps = alc[i].getAlcodMap();
3071 for (int m = 0; m < maps.length; m++)
3073 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3075 jalview.datamodel.Mapping mapping = null;
3076 // attach to dna sequence reference.
3077 if (maps[m].getMapping() != null)
3079 mapping = addMapping(maps[m].getMapping());
3080 if (dnaseq != null && mapping.getTo() != null)
3082 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3087 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3092 al.addCodonFrame(cf);
3097 // ////////////////////////////////
3099 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3102 * store any annotations which forward reference a group's ID
3104 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3106 if (vamsasSet.getAnnotationCount() > 0)
3108 Annotation[] an = vamsasSet.getAnnotation();
3110 for (int i = 0; i < an.length; i++)
3112 Annotation annotation = an[i];
3115 * test if annotation is automatically calculated for this view only
3117 boolean autoForView = false;
3118 if (annotation.getLabel().equals("Quality")
3119 || annotation.getLabel().equals("Conservation")
3120 || annotation.getLabel().equals("Consensus"))
3122 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3124 if (!annotation.hasAutoCalculated())
3126 annotation.setAutoCalculated(true);
3130 || (annotation.hasAutoCalculated() && annotation
3131 .isAutoCalculated()))
3133 // remove ID - we don't recover annotation from other views for
3134 // view-specific annotation
3135 annotation.setId(null);
3138 // set visiblity for other annotation in this view
3139 String annotationId = annotation.getId();
3140 if (annotationId != null && annotationIds.containsKey(annotationId))
3142 AlignmentAnnotation jda = annotationIds.get(annotationId);
3143 // in principle Visible should always be true for annotation displayed
3144 // in multiple views
3145 if (annotation.hasVisible())
3147 jda.visible = annotation.getVisible();
3150 al.addAnnotation(jda);
3154 // Construct new annotation from model.
3155 AnnotationElement[] ae = annotation.getAnnotationElement();
3156 jalview.datamodel.Annotation[] anot = null;
3157 java.awt.Color firstColour = null;
3159 if (!annotation.getScoreOnly())
3161 anot = new jalview.datamodel.Annotation[al.getWidth()];
3162 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3164 anpos = ae[aa].getPosition();
3166 if (anpos >= anot.length)
3171 anot[anpos] = new jalview.datamodel.Annotation(
3173 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3174 (ae[aa].getSecondaryStructure() == null || ae[aa]
3175 .getSecondaryStructure().length() == 0) ? ' '
3176 : ae[aa].getSecondaryStructure().charAt(0),
3180 // JBPNote: Consider verifying dataflow for IO of secondary
3181 // structure annotation read from Stockholm files
3182 // this was added to try to ensure that
3183 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3185 // anot[ae[aa].getPosition()].displayCharacter = "";
3187 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3188 if (firstColour == null)
3190 firstColour = anot[anpos].colour;
3194 jalview.datamodel.AlignmentAnnotation jaa = null;
3196 if (annotation.getGraph())
3198 float llim = 0, hlim = 0;
3199 // if (autoForView || an[i].isAutoCalculated()) {
3202 jaa = new jalview.datamodel.AlignmentAnnotation(
3203 annotation.getLabel(), annotation.getDescription(), anot,
3204 llim, hlim, annotation.getGraphType());
3206 jaa.graphGroup = annotation.getGraphGroup();
3207 jaa._linecolour = firstColour;
3208 if (annotation.getThresholdLine() != null)
3210 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3211 .getThresholdLine().getValue(), annotation
3212 .getThresholdLine().getLabel(), new java.awt.Color(
3213 annotation.getThresholdLine().getColour())));
3216 if (autoForView || annotation.isAutoCalculated())
3218 // Hardwire the symbol display line to ensure that labels for
3219 // histograms are displayed
3225 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3226 an[i].getDescription(), anot);
3227 jaa._linecolour = firstColour;
3229 // register new annotation
3230 if (an[i].getId() != null)
3232 annotationIds.put(an[i].getId(), jaa);
3233 jaa.annotationId = an[i].getId();
3235 // recover sequence association
3236 String sequenceRef = an[i].getSequenceRef();
3237 if (sequenceRef != null)
3239 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3240 SequenceI sequence = seqRefIds.get(sequenceRef);
3241 if (sequence == null)
3243 // in pre-2.9 projects sequence ref is to sequence name
3244 sequence = al.findName(sequenceRef);
3246 if (sequence != null)
3248 jaa.createSequenceMapping(sequence, 1, true);
3249 sequence.addAlignmentAnnotation(jaa);
3252 // and make a note of any group association
3253 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3255 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3256 .get(an[i].getGroupRef());
3259 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3260 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3265 if (an[i].hasScore())
3267 jaa.setScore(an[i].getScore());
3269 if (an[i].hasVisible())
3271 jaa.visible = an[i].getVisible();
3274 if (an[i].hasCentreColLabels())
3276 jaa.centreColLabels = an[i].getCentreColLabels();
3279 if (an[i].hasScaleColLabels())
3281 jaa.scaleColLabel = an[i].getScaleColLabels();
3283 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3285 // newer files have an 'autoCalculated' flag and store calculation
3286 // state in viewport properties
3287 jaa.autoCalculated = true; // means annotation will be marked for
3288 // update at end of load.
3290 if (an[i].hasGraphHeight())
3292 jaa.graphHeight = an[i].getGraphHeight();
3294 if (an[i].hasBelowAlignment())
3296 jaa.belowAlignment = an[i].isBelowAlignment();
3298 jaa.setCalcId(an[i].getCalcId());
3299 if (an[i].getPropertyCount() > 0)
3301 for (jalview.schemabinding.version2.Property prop : an[i]
3304 jaa.setProperty(prop.getName(), prop.getValue());
3307 if (jaa.autoCalculated)
3309 autoAlan.add(new JvAnnotRow(i, jaa));
3312 // if (!autoForView)
3314 // add autocalculated group annotation and any user created annotation
3316 al.addAnnotation(jaa);
3320 // ///////////////////////
3322 // Create alignment markup and styles for this view
3323 if (jms.getJGroupCount() > 0)
3325 JGroup[] groups = jms.getJGroup();
3326 boolean addAnnotSchemeGroup = false;
3327 for (int i = 0; i < groups.length; i++)
3329 JGroup jGroup = groups[i];
3330 ColourSchemeI cs = null;
3331 if (jGroup.getColour() != null)
3333 if (jGroup.getColour().startsWith("ucs"))
3335 cs = getUserColourScheme(jms, jGroup.getColour());
3337 else if (jGroup.getColour().equals("AnnotationColourGradient")
3338 && jGroup.getAnnotationColours() != null)
3340 addAnnotSchemeGroup = true;
3345 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3350 cs.setThreshold(jGroup.getPidThreshold(), true);
3354 Vector<SequenceI> seqs = new Vector<SequenceI>();
3356 for (int s = 0; s < jGroup.getSeqCount(); s++)
3358 String seqId = jGroup.getSeq(s) + "";
3359 SequenceI ts = seqRefIds.get(seqId);
3363 seqs.addElement(ts);
3367 if (seqs.size() < 1)
3372 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3373 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3374 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3376 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3378 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3379 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3380 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3381 .isShowUnconserved() : false);
3382 sg.thresholdTextColour = jGroup.getTextColThreshold();
3383 if (jGroup.hasShowConsensusHistogram())
3385 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3388 if (jGroup.hasShowSequenceLogo())
3390 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3392 if (jGroup.hasNormaliseSequenceLogo())
3394 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3396 if (jGroup.hasIgnoreGapsinConsensus())
3398 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3400 if (jGroup.getConsThreshold() != 0)
3402 Conservation c = new Conservation("All", 3,
3403 sg.getSequences(null), 0, sg.getWidth() - 1);
3405 c.verdict(false, 25);
3406 sg.cs.setConservation(c);
3409 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3411 // re-instate unique group/annotation row reference
3412 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3416 for (AlignmentAnnotation jaa : jaal)
3419 if (jaa.autoCalculated)
3421 // match up and try to set group autocalc alignment row for this
3423 if (jaa.label.startsWith("Consensus for "))
3425 sg.setConsensus(jaa);
3427 // match up and try to set group autocalc alignment row for this
3429 if (jaa.label.startsWith("Conservation for "))
3431 sg.setConservationRow(jaa);
3438 if (addAnnotSchemeGroup)
3440 // reconstruct the annotation colourscheme
3441 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3442 null, al, jms, false);
3448 // only dataset in this model, so just return.
3451 // ///////////////////////////////
3454 // If we just load in the same jar file again, the sequenceSetId
3455 // will be the same, and we end up with multiple references
3456 // to the same sequenceSet. We must modify this id on load
3457 // so that each load of the file gives a unique id
3458 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3459 String viewId = (view.getId() == null ? null : view.getId()
3461 AlignFrame af = null;
3462 AlignViewport av = null;
3463 // now check to see if we really need to create a new viewport.
3464 if (multipleView && viewportsAdded.size() == 0)
3466 // We recovered an alignment for which a viewport already exists.
3467 // TODO: fix up any settings necessary for overlaying stored state onto
3468 // state recovered from another document. (may not be necessary).
3469 // we may need a binding from a viewport in memory to one recovered from
3471 // and then recover its containing af to allow the settings to be applied.
3472 // TODO: fix for vamsas demo
3474 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3476 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3477 if (seqsetobj != null)
3479 if (seqsetobj instanceof String)
3481 uniqueSeqSetId = (String) seqsetobj;
3483 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3489 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3495 * indicate that annotation colours are applied across all groups (pre
3496 * Jalview 2.8.1 behaviour)
3498 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3499 "2.8.1", object.getVersion());
3501 AlignmentPanel ap = null;
3502 boolean isnewview = true;
3505 // Check to see if this alignment already has a view id == viewId
3506 jalview.gui.AlignmentPanel views[] = Desktop
3507 .getAlignmentPanels(uniqueSeqSetId);
3508 if (views != null && views.length > 0)
3510 for (int v = 0; v < views.length; v++)
3512 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3514 // recover the existing alignpanel, alignframe, viewport
3515 af = views[v].alignFrame;
3518 // TODO: could even skip resetting view settings if we don't want to
3519 // change the local settings from other jalview processes
3528 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3529 uniqueSeqSetId, viewId, autoAlan);
3535 * Load any trees, PDB structures and viewers
3537 * Not done if flag is false (when this method is used for New View)
3539 if (loadTreesAndStructures)
3541 loadTrees(jms, view, af, av, ap);
3542 loadPDBStructures(jprovider, jseqs, af, ap);
3543 loadRnaViewers(jprovider, jseqs, ap);
3545 // and finally return.
3550 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3551 * panel is restored from separate jar entries, two (gapped and trimmed) per
3552 * sequence and secondary structure.
3554 * Currently each viewer shows just one sequence and structure (gapped and
3555 * trimmed), however this method is designed to support multiple sequences or
3556 * structures in viewers if wanted in future.
3562 private void loadRnaViewers(jarInputStreamProvider jprovider,
3563 JSeq[] jseqs, AlignmentPanel ap)
3566 * scan the sequences for references to viewers; create each one the first
3567 * time it is referenced, add Rna models to existing viewers
3569 for (JSeq jseq : jseqs)
3571 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3573 RnaViewer viewer = jseq.getRnaViewer(i);
3574 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3575 uniqueSetSuffix, ap);
3577 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3579 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3580 SequenceI seq = seqRefIds.get(jseq.getId());
3581 AlignmentAnnotation ann = this.annotationIds.get(ss
3582 .getAnnotationId());
3585 * add the structure to the Varna display (with session state copied
3586 * from the jar to a temporary file)
3588 boolean gapped = ss.isGapped();
3589 String rnaTitle = ss.getTitle();
3590 String sessionState = ss.getViewerState();
3591 String tempStateFile = copyJarEntry(jprovider, sessionState,
3593 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3594 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3596 appVarna.setInitialSelection(viewer.getSelectedRna());
3602 * Locate and return an already instantiated matching AppVarna, or create one
3606 * @param viewIdSuffix
3610 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3611 String viewIdSuffix, AlignmentPanel ap)
3614 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3615 * if load is repeated
3617 String postLoadId = viewer.getViewId() + viewIdSuffix;
3618 for (JInternalFrame frame : getAllFrames())
3620 if (frame instanceof AppVarna)
3622 AppVarna varna = (AppVarna) frame;
3623 if (postLoadId.equals(varna.getViewId()))
3625 // this viewer is already instantiated
3626 // could in future here add ap as another 'parent' of the
3627 // AppVarna window; currently just 1-to-many
3634 * viewer not found - make it
3636 RnaViewerModel model = new RnaViewerModel(postLoadId,
3637 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3638 viewer.getWidth(), viewer.getHeight(),
3639 viewer.getDividerLocation());
3640 AppVarna varna = new AppVarna(model, ap);
3646 * Load any saved trees
3654 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3655 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3657 // TODO result of automated refactoring - are all these parameters needed?
3660 for (int t = 0; t < jms.getTreeCount(); t++)
3663 Tree tree = jms.getTree(t);
3665 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3668 tp = af.ShowNewickTree(
3669 new jalview.io.NewickFile(tree.getNewick()),
3670 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3671 tree.getXpos(), tree.getYpos());
3672 if (tree.getId() != null)
3674 // perhaps bind the tree id to something ?
3679 // update local tree attributes ?
3680 // TODO: should check if tp has been manipulated by user - if so its
3681 // settings shouldn't be modified
3682 tp.setTitle(tree.getTitle());
3683 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3684 .getWidth(), tree.getHeight()));
3685 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3688 tp.treeCanvas.av = av; // af.viewport;
3689 tp.treeCanvas.ap = ap; // af.alignPanel;
3694 warn("There was a problem recovering stored Newick tree: \n"
3695 + tree.getNewick());
3699 tp.fitToWindow.setState(tree.getFitToWindow());
3700 tp.fitToWindow_actionPerformed(null);
3702 if (tree.getFontName() != null)
3704 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3705 .getFontStyle(), tree.getFontSize()));
3709 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3710 .getFontStyle(), tree.getFontSize()));
3713 tp.showPlaceholders(tree.getMarkUnlinked());
3714 tp.showBootstrap(tree.getShowBootstrap());
3715 tp.showDistances(tree.getShowDistances());
3717 tp.treeCanvas.threshold = tree.getThreshold();
3719 if (tree.getCurrentTree())
3721 af.viewport.setCurrentTree(tp.getTree());
3725 } catch (Exception ex)
3727 ex.printStackTrace();
3732 * Load and link any saved structure viewers.
3739 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3740 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3743 * Run through all PDB ids on the alignment, and collect mappings between
3744 * distinct view ids and all sequences referring to that view.
3746 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3748 for (int i = 0; i < jseqs.length; i++)
3750 if (jseqs[i].getPdbidsCount() > 0)
3752 Pdbids[] ids = jseqs[i].getPdbids();
3753 for (int p = 0; p < ids.length; p++)
3755 final int structureStateCount = ids[p].getStructureStateCount();
3756 for (int s = 0; s < structureStateCount; s++)
3758 // check to see if we haven't already created this structure view
3759 final StructureState structureState = ids[p]
3760 .getStructureState(s);
3761 String sviewid = (structureState.getViewId() == null) ? null
3762 : structureState.getViewId() + uniqueSetSuffix;
3763 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3764 // Originally : ids[p].getFile()
3765 // : TODO: verify external PDB file recovery still works in normal
3766 // jalview project load
3767 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3769 jpdb.setId(ids[p].getId());
3771 int x = structureState.getXpos();
3772 int y = structureState.getYpos();
3773 int width = structureState.getWidth();
3774 int height = structureState.getHeight();
3776 // Probably don't need to do this anymore...
3777 // Desktop.desktop.getComponentAt(x, y);
3778 // TODO: NOW: check that this recovers the PDB file correctly.
3779 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3781 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3783 if (sviewid == null)
3785 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3788 if (!structureViewers.containsKey(sviewid))
3790 structureViewers.put(sviewid,
3791 new StructureViewerModel(x, y, width, height, false,
3792 false, true, structureState.getViewId(),
3793 structureState.getType()));
3794 // Legacy pre-2.7 conversion JAL-823 :
3795 // do not assume any view has to be linked for colour by
3799 // assemble String[] { pdb files }, String[] { id for each
3800 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3801 // seqs_file 2}, boolean[] {
3802 // linkAlignPanel,superposeWithAlignpanel}} from hash
3803 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3804 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3805 | (structureState.hasAlignwithAlignPanel() ? structureState
3806 .getAlignwithAlignPanel() : false));
3809 * Default colour by linked panel to false if not specified (e.g.
3810 * for pre-2.7 projects)
3812 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3813 colourWithAlignPanel |= (structureState
3814 .hasColourwithAlignPanel() ? structureState
3815 .getColourwithAlignPanel() : false);
3816 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3819 * Default colour by viewer to true if not specified (e.g. for
3822 boolean colourByViewer = jmoldat.isColourByViewer();
3823 colourByViewer &= structureState.hasColourByJmol() ? structureState
3824 .getColourByJmol() : true;
3825 jmoldat.setColourByViewer(colourByViewer);
3827 if (jmoldat.getStateData().length() < structureState
3828 .getContent().length())
3831 jmoldat.setStateData(structureState.getContent());
3834 if (ids[p].getFile() != null)
3836 File mapkey = new File(ids[p].getFile());
3837 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3838 if (seqstrmaps == null)
3840 jmoldat.getFileData().put(
3842 seqstrmaps = jmoldat.new StructureData(pdbFile,
3845 if (!seqstrmaps.getSeqList().contains(seq))
3847 seqstrmaps.getSeqList().add(seq);
3853 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");
3860 // Instantiate the associated structure views
3861 for (Entry<String, StructureViewerModel> entry : structureViewers
3866 createOrLinkStructureViewer(entry, af, ap, jprovider);
3867 } catch (Exception e)
3869 System.err.println("Error loading structure viewer: "
3871 // failed - try the next one
3883 protected void createOrLinkStructureViewer(
3884 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3885 AlignmentPanel ap, jarInputStreamProvider jprovider)
3887 final StructureViewerModel stateData = viewerData.getValue();
3890 * Search for any viewer windows already open from other alignment views
3891 * that exactly match the stored structure state
3893 StructureViewerBase comp = findMatchingViewer(viewerData);
3897 linkStructureViewer(ap, comp, stateData);
3902 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3903 * "viewer_"+stateData.viewId
3905 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3907 createChimeraViewer(viewerData, af, jprovider);
3912 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3914 createJmolViewer(viewerData, af, jprovider);
3919 * Create a new Chimera viewer.
3925 protected void createChimeraViewer(
3926 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3927 jarInputStreamProvider jprovider)
3929 StructureViewerModel data = viewerData.getValue();
3930 String chimeraSessionFile = data.getStateData();
3933 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3935 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3936 * 'uniquified' sviewid used to reconstruct the viewer here
3938 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3939 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3942 Set<Entry<File, StructureData>> fileData = data.getFileData()
3944 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3945 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3946 for (Entry<File, StructureData> pdb : fileData)
3948 String filePath = pdb.getValue().getFilePath();
3949 String pdbId = pdb.getValue().getPdbId();
3950 // pdbs.add(new PDBEntry(filePath, pdbId));
3951 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3952 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3953 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3957 boolean colourByChimera = data.isColourByViewer();
3958 boolean colourBySequence = data.isColourWithAlignPanel();
3960 // TODO use StructureViewer as a factory here, see JAL-1761
3961 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3962 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3964 String newViewId = viewerData.getKey();
3966 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3967 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3968 colourBySequence, newViewId);
3969 cvf.setSize(data.getWidth(), data.getHeight());
3970 cvf.setLocation(data.getX(), data.getY());
3974 * Create a new Jmol window. First parse the Jmol state to translate filenames
3975 * loaded into the view, and record the order in which files are shown in the
3976 * Jmol view, so we can add the sequence mappings in same order.
3982 protected void createJmolViewer(
3983 final Entry<String, StructureViewerModel> viewerData,
3984 AlignFrame af, jarInputStreamProvider jprovider)
3986 final StructureViewerModel svattrib = viewerData.getValue();
3987 String state = svattrib.getStateData();
3990 * Pre-2.9: state element value is the Jmol state string
3992 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3995 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3997 state = readJarEntry(jprovider,
3998 getViewerJarEntryName(svattrib.getViewId()));
4001 List<String> pdbfilenames = new ArrayList<String>();
4002 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
4003 List<String> pdbids = new ArrayList<String>();
4004 StringBuilder newFileLoc = new StringBuilder(64);
4005 int cp = 0, ncp, ecp;
4006 Map<File, StructureData> oldFiles = svattrib.getFileData();
4007 while ((ncp = state.indexOf("load ", cp)) > -1)
4011 // look for next filename in load statement
4012 newFileLoc.append(state.substring(cp,
4013 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4014 String oldfilenam = state.substring(ncp,
4015 ecp = state.indexOf("\"", ncp));
4016 // recover the new mapping data for this old filename
4017 // have to normalize filename - since Jmol and jalview do
4019 // translation differently.
4020 StructureData filedat = oldFiles.get(new File(oldfilenam));
4021 if (filedat == null)
4023 String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
4024 filedat = oldFiles.get(new File(reformatedOldFilename));
4026 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4027 pdbfilenames.add(filedat.getFilePath());
4028 pdbids.add(filedat.getPdbId());
4029 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4030 newFileLoc.append("\"");
4031 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4032 // look for next file statement.
4033 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4037 // just append rest of state
4038 newFileLoc.append(state.substring(cp));
4042 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4043 newFileLoc = new StringBuilder(state);
4044 newFileLoc.append("; load append ");
4045 for (File id : oldFiles.keySet())
4047 // add this and any other pdb files that should be present in
4049 StructureData filedat = oldFiles.get(id);
4050 newFileLoc.append(filedat.getFilePath());
4051 pdbfilenames.add(filedat.getFilePath());
4052 pdbids.add(filedat.getPdbId());
4053 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4054 newFileLoc.append(" \"");
4055 newFileLoc.append(filedat.getFilePath());
4056 newFileLoc.append("\"");
4059 newFileLoc.append(";");
4062 if (newFileLoc.length() == 0)
4066 int histbug = newFileLoc.indexOf("history = ");
4070 * change "history = [true|false];" to "history = [1|0];"
4073 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4074 String val = (diff == -1) ? null : newFileLoc
4075 .substring(histbug, diff);
4076 if (val != null && val.length() >= 4)
4078 if (val.contains("e")) // eh? what can it be?
4080 if (val.trim().equals("true"))
4088 newFileLoc.replace(histbug, diff, val);
4093 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4095 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4096 final SequenceI[][] sq = seqmaps
4097 .toArray(new SequenceI[seqmaps.size()][]);
4098 final String fileloc = newFileLoc.toString();
4099 final String sviewid = viewerData.getKey();
4100 final AlignFrame alf = af;
4101 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4102 svattrib.getWidth(), svattrib.getHeight());
4105 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4110 JalviewStructureDisplayI sview = null;
4113 sview = new StructureViewer(alf.alignPanel
4114 .getStructureSelectionManager()).createView(
4115 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4116 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4117 addNewStructureViewer(sview);
4118 } catch (OutOfMemoryError ex)
4120 new OOMWarning("restoring structure view for PDB id " + id,
4121 (OutOfMemoryError) ex.getCause());
4122 if (sview != null && sview.isVisible())
4124 sview.closeViewer(false);
4125 sview.setVisible(false);
4131 } catch (InvocationTargetException ex)
4133 warn("Unexpected error when opening Jmol view.", ex);
4135 } catch (InterruptedException e)
4137 // e.printStackTrace();
4143 * Generates a name for the entry in the project jar file to hold state
4144 * information for a structure viewer
4149 protected String getViewerJarEntryName(String viewId)
4151 return VIEWER_PREFIX + viewId;
4155 * Returns any open frame that matches given structure viewer data. The match
4156 * is based on the unique viewId, or (for older project versions) the frame's
4162 protected StructureViewerBase findMatchingViewer(
4163 Entry<String, StructureViewerModel> viewerData)
4165 final String sviewid = viewerData.getKey();
4166 final StructureViewerModel svattrib = viewerData.getValue();
4167 StructureViewerBase comp = null;
4168 JInternalFrame[] frames = getAllFrames();
4169 for (JInternalFrame frame : frames)
4171 if (frame instanceof StructureViewerBase)
4174 * Post jalview 2.4 schema includes structure view id
4177 && ((StructureViewerBase) frame).getViewId()
4180 comp = (StructureViewerBase) frame;
4181 break; // break added in 2.9
4184 * Otherwise test for matching position and size of viewer frame
4186 else if (frame.getX() == svattrib.getX()
4187 && frame.getY() == svattrib.getY()
4188 && frame.getHeight() == svattrib.getHeight()
4189 && frame.getWidth() == svattrib.getWidth())
4191 comp = (StructureViewerBase) frame;
4192 // no break in faint hope of an exact match on viewId
4200 * Link an AlignmentPanel to an existing structure viewer.
4205 * @param useinViewerSuperpos
4206 * @param usetoColourbyseq
4207 * @param viewerColouring
4209 protected void linkStructureViewer(AlignmentPanel ap,
4210 StructureViewerBase viewer, StructureViewerModel stateData)
4212 // NOTE: if the jalview project is part of a shared session then
4213 // view synchronization should/could be done here.
4215 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4216 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4217 final boolean viewerColouring = stateData.isColourByViewer();
4218 Map<File, StructureData> oldFiles = stateData.getFileData();
4221 * Add mapping for sequences in this view to an already open viewer
4223 final AAStructureBindingModel binding = viewer.getBinding();
4224 for (File id : oldFiles.keySet())
4226 // add this and any other pdb files that should be present in the
4228 StructureData filedat = oldFiles.get(id);
4229 String pdbFile = filedat.getFilePath();
4230 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4231 binding.getSsm().setMapping(seq, null, pdbFile,
4232 jalview.io.AppletFormatAdapter.FILE);
4233 binding.addSequenceForStructFile(pdbFile, seq);
4235 // and add the AlignmentPanel's reference to the view panel
4236 viewer.addAlignmentPanel(ap);
4237 if (useinViewerSuperpos)
4239 viewer.useAlignmentPanelForSuperposition(ap);
4243 viewer.excludeAlignmentPanelForSuperposition(ap);
4245 if (usetoColourbyseq)
4247 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4251 viewer.excludeAlignmentPanelForColourbyseq(ap);
4256 * Get all frames within the Desktop.
4260 protected JInternalFrame[] getAllFrames()
4262 JInternalFrame[] frames = null;
4263 // TODO is this necessary - is it safe - risk of hanging?
4268 frames = Desktop.desktop.getAllFrames();
4269 } catch (ArrayIndexOutOfBoundsException e)
4271 // occasional No such child exceptions are thrown here...
4275 } catch (InterruptedException f)
4279 } while (frames == null);
4284 * Answers true if 'version' is equal to or later than 'supported', where each
4285 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4286 * changes. Development and test values for 'version' are leniently treated
4290 * - minimum version we are comparing against
4292 * - version of data being processsed
4295 public static boolean isVersionStringLaterThan(String supported,
4298 if (supported == null || version == null
4299 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4300 || version.equalsIgnoreCase("Test")
4301 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4303 System.err.println("Assuming project file with "
4304 + (version == null ? "null" : version)
4305 + " is compatible with Jalview version " + supported);
4310 return StringUtils.compareVersions(version, supported, "b") >= 0;
4314 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4316 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4318 if (newStructureViewers != null)
4320 sview.getBinding().setFinishedLoadingFromArchive(false);
4321 newStructureViewers.add(sview);
4325 protected void setLoadingFinishedForNewStructureViewers()
4327 if (newStructureViewers != null)
4329 for (JalviewStructureDisplayI sview : newStructureViewers)
4331 sview.getBinding().setFinishedLoadingFromArchive(true);
4333 newStructureViewers.clear();
4334 newStructureViewers = null;
4338 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4339 List<SequenceI> hiddenSeqs, AlignmentI al,
4340 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4341 String viewId, List<JvAnnotRow> autoAlan)
4343 AlignFrame af = null;
4344 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4345 uniqueSeqSetId, viewId);
4347 af.setFileName(file, "Jalview");
4349 for (int i = 0; i < JSEQ.length; i++)
4351 af.viewport.setSequenceColour(af.viewport.getAlignment()
4352 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4357 af.getViewport().setColourByReferenceSeq(true);
4358 af.getViewport().setDisplayReferenceSeq(true);
4361 af.viewport.setGatherViewsHere(view.getGatheredViews());
4363 if (view.getSequenceSetId() != null)
4365 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4367 af.viewport.setSequenceSetId(uniqueSeqSetId);
4370 // propagate shared settings to this new view
4371 af.viewport.setHistoryList(av.getHistoryList());
4372 af.viewport.setRedoList(av.getRedoList());
4376 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4378 // TODO: check if this method can be called repeatedly without
4379 // side-effects if alignpanel already registered.
4380 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4382 // apply Hidden regions to view.
4383 if (hiddenSeqs != null)
4385 for (int s = 0; s < JSEQ.length; s++)
4387 SequenceGroup hidden = new SequenceGroup();
4388 boolean isRepresentative = false;
4389 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4391 isRepresentative = true;
4392 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4393 .getHiddenSequences(r));
4394 hidden.addSequence(sequenceToHide, false);
4395 // remove from hiddenSeqs list so we don't try to hide it twice
4396 hiddenSeqs.remove(sequenceToHide);
4398 if (isRepresentative)
4400 SequenceI representativeSequence = al.getSequenceAt(s);
4401 hidden.addSequence(representativeSequence, false);
4402 af.viewport.hideRepSequences(representativeSequence, hidden);
4406 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4408 af.viewport.hideSequence(hseqs);
4411 // recover view properties and display parameters
4412 if (view.getViewName() != null)
4414 af.viewport.viewName = view.getViewName();
4415 af.setInitialTabVisible();
4417 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4420 af.viewport.setShowAnnotation(view.getShowAnnotation());
4421 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4423 af.viewport.setColourText(view.getShowColourText());
4425 af.viewport.setConservationSelected(view.getConservationSelected());
4426 af.viewport.setShowJVSuffix(view.getShowFullId());
4427 af.viewport.setRightAlignIds(view.getRightAlignIds());
4428 af.viewport.setFont(
4429 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4430 .getFontSize()), true);
4431 ViewStyleI vs = af.viewport.getViewStyle();
4432 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4433 af.viewport.setViewStyle(vs);
4434 // TODO: allow custom charWidth/Heights to be restored by updating them
4435 // after setting font - which means set above to false
4436 af.viewport.setRenderGaps(view.getRenderGaps());
4437 af.viewport.setWrapAlignment(view.getWrapAlignment());
4438 af.viewport.setShowAnnotation(view.getShowAnnotation());
4440 af.viewport.setShowBoxes(view.getShowBoxes());
4442 af.viewport.setShowText(view.getShowText());
4444 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4445 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4446 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4447 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4448 .isShowUnconserved() : false);
4449 af.viewport.setStartRes(view.getStartRes());
4450 af.viewport.setStartSeq(view.getStartSeq());
4451 af.alignPanel.updateLayout();
4452 ColourSchemeI cs = null;
4453 // apply colourschemes
4454 if (view.getBgColour() != null)
4456 if (view.getBgColour().startsWith("ucs"))
4458 cs = getUserColourScheme(jms, view.getBgColour());
4460 else if (view.getBgColour().startsWith("Annotation"))
4462 AnnotationColours viewAnnColour = view.getAnnotationColours();
4463 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4470 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4475 cs.setThreshold(view.getPidThreshold(), true);
4476 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4480 af.viewport.setGlobalColourScheme(cs);
4481 af.viewport.setColourAppliesToAllGroups(false);
4483 if (view.getConservationSelected() && cs != null)
4485 cs.setConservationInc(view.getConsThreshold());
4488 af.changeColour(cs);
4490 af.viewport.setColourAppliesToAllGroups(true);
4492 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4494 if (view.hasCentreColumnLabels())
4496 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4498 if (view.hasIgnoreGapsinConsensus())
4500 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4503 if (view.hasFollowHighlight())
4505 af.viewport.setFollowHighlight(view.getFollowHighlight());
4507 if (view.hasFollowSelection())
4509 af.viewport.followSelection = view.getFollowSelection();
4511 if (view.hasShowConsensusHistogram())
4513 af.viewport.setShowConsensusHistogram(view
4514 .getShowConsensusHistogram());
4518 af.viewport.setShowConsensusHistogram(true);
4520 if (view.hasShowSequenceLogo())
4522 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4526 af.viewport.setShowSequenceLogo(false);
4528 if (view.hasNormaliseSequenceLogo())
4530 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4532 if (view.hasShowDbRefTooltip())
4534 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4536 if (view.hasShowNPfeatureTooltip())
4538 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4540 if (view.hasShowGroupConsensus())
4542 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4546 af.viewport.setShowGroupConsensus(false);
4548 if (view.hasShowGroupConservation())
4550 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4554 af.viewport.setShowGroupConservation(false);
4557 // recover featre settings
4558 if (jms.getFeatureSettings() != null)
4560 FeaturesDisplayed fdi;
4561 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4562 String[] renderOrder = new String[jms.getFeatureSettings()
4563 .getSettingCount()];
4564 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4565 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4567 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4569 Setting setting = jms.getFeatureSettings().getSetting(fs);
4570 if (setting.hasMincolour())
4572 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4573 new Color(setting.getMincolour()), new Color(
4574 setting.getColour()), setting.getMin(),
4575 setting.getMax()) : new FeatureColour(new Color(
4576 setting.getMincolour()), new Color(setting.getColour()),
4578 if (setting.hasThreshold())
4580 gc.setThreshold(setting.getThreshold());
4581 int threshstate = setting.getThreshstate();
4582 // -1 = None, 0 = Below, 1 = Above threshold
4583 if (threshstate == 0)
4585 gc.setBelowThreshold(true);
4587 else if (threshstate == 1)
4589 gc.setAboveThreshold(true);
4592 gc.setAutoScaled(true); // default
4593 if (setting.hasAutoScale())
4595 gc.setAutoScaled(setting.getAutoScale());
4597 if (setting.hasColourByLabel())
4599 gc.setColourByLabel(setting.getColourByLabel());
4601 // and put in the feature colour table.
4602 featureColours.put(setting.getType(), gc);
4606 featureColours.put(setting.getType(), new FeatureColour(
4607 new Color(setting.getColour())));
4609 renderOrder[fs] = setting.getType();
4610 if (setting.hasOrder())
4612 featureOrder.put(setting.getType(), setting.getOrder());
4616 featureOrder.put(setting.getType(), new Float(fs
4617 / jms.getFeatureSettings().getSettingCount()));
4619 if (setting.getDisplay())
4621 fdi.setVisible(setting.getType());
4624 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4625 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4627 Group grp = jms.getFeatureSettings().getGroup(gs);
4628 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4630 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4631 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4632 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4633 FeatureRendererSettings frs = new FeatureRendererSettings(
4634 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4635 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4636 .transferSettings(frs);
4640 if (view.getHiddenColumnsCount() > 0)
4642 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4644 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4645 .getHiddenColumns(c).getEnd() // +1
4649 if (view.getCalcIdParam() != null)
4651 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4653 if (calcIdParam != null)
4655 if (recoverCalcIdParam(calcIdParam, af.viewport))
4660 warn("Couldn't recover parameters for "
4661 + calcIdParam.getCalcId());
4666 af.setMenusFromViewport(af.viewport);
4667 af.setTitle(view.getTitle());
4668 // TODO: we don't need to do this if the viewport is aready visible.
4670 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4671 * has a 'cdna/protein complement' view, in which case save it in order to
4672 * populate a SplitFrame once all views have been read in.
4674 String complementaryViewId = view.getComplementId();
4675 if (complementaryViewId == null)
4677 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4679 // recompute any autoannotation
4680 af.alignPanel.updateAnnotation(false, true);
4681 reorderAutoannotation(af, al, autoAlan);
4682 af.alignPanel.alignmentChanged();
4686 splitFrameCandidates.put(view, af);
4691 private ColourSchemeI constructAnnotationColour(
4692 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4693 JalviewModelSequence jms, boolean checkGroupAnnColour)
4695 boolean propagateAnnColour = false;
4696 ColourSchemeI cs = null;
4697 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4698 if (checkGroupAnnColour && al.getGroups() != null
4699 && al.getGroups().size() > 0)
4701 // pre 2.8.1 behaviour
4702 // check to see if we should transfer annotation colours
4703 propagateAnnColour = true;
4704 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4706 if (sg.cs instanceof AnnotationColourGradient)
4708 propagateAnnColour = false;
4712 // int find annotation
4713 if (annAlignment.getAlignmentAnnotation() != null)
4715 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4717 if (annAlignment.getAlignmentAnnotation()[i].label
4718 .equals(viewAnnColour.getAnnotation()))
4720 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4722 annAlignment.getAlignmentAnnotation()[i]
4723 .setThreshold(new jalview.datamodel.GraphLine(
4724 viewAnnColour.getThreshold(), "Threshold",
4725 java.awt.Color.black)
4730 if (viewAnnColour.getColourScheme().equals("None"))
4732 cs = new AnnotationColourGradient(
4733 annAlignment.getAlignmentAnnotation()[i],
4734 new java.awt.Color(viewAnnColour.getMinColour()),
4735 new java.awt.Color(viewAnnColour.getMaxColour()),
4736 viewAnnColour.getAboveThreshold());
4738 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4740 cs = new AnnotationColourGradient(
4741 annAlignment.getAlignmentAnnotation()[i],
4742 getUserColourScheme(jms,
4743 viewAnnColour.getColourScheme()),
4744 viewAnnColour.getAboveThreshold());
4748 cs = new AnnotationColourGradient(
4749 annAlignment.getAlignmentAnnotation()[i],
4750 ColourSchemeProperty.getColour(al,
4751 viewAnnColour.getColourScheme()),
4752 viewAnnColour.getAboveThreshold());
4754 if (viewAnnColour.hasPerSequence())
4756 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4759 if (viewAnnColour.hasPredefinedColours())
4761 ((AnnotationColourGradient) cs)
4762 .setPredefinedColours(viewAnnColour
4763 .isPredefinedColours());
4765 if (propagateAnnColour && al.getGroups() != null)
4767 // Also use these settings for all the groups
4768 for (int g = 0; g < al.getGroups().size(); g++)
4770 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4778 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4779 * new AnnotationColourGradient(
4780 * annAlignment.getAlignmentAnnotation()[i], new
4781 * java.awt.Color(viewAnnColour. getMinColour()), new
4782 * java.awt.Color(viewAnnColour. getMaxColour()),
4783 * viewAnnColour.getAboveThreshold()); } else
4786 sg.cs = new AnnotationColourGradient(
4787 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4788 viewAnnColour.getAboveThreshold());
4789 if (cs instanceof AnnotationColourGradient)
4791 if (viewAnnColour.hasPerSequence())
4793 ((AnnotationColourGradient) cs)
4794 .setSeqAssociated(viewAnnColour.isPerSequence());
4796 if (viewAnnColour.hasPredefinedColours())
4798 ((AnnotationColourGradient) cs)
4799 .setPredefinedColours(viewAnnColour
4800 .isPredefinedColours());
4816 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4817 List<JvAnnotRow> autoAlan)
4819 // copy over visualization settings for autocalculated annotation in the
4821 if (al.getAlignmentAnnotation() != null)
4824 * Kludge for magic autoannotation names (see JAL-811)
4826 String[] magicNames = new String[] { "Consensus", "Quality",
4828 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4829 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4830 for (String nm : magicNames)
4832 visan.put(nm, nullAnnot);
4834 for (JvAnnotRow auan : autoAlan)
4836 visan.put(auan.template.label
4837 + (auan.template.getCalcId() == null ? "" : "\t"
4838 + auan.template.getCalcId()), auan);
4840 int hSize = al.getAlignmentAnnotation().length;
4841 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4842 // work through any autoCalculated annotation already on the view
4843 // removing it if it should be placed in a different location on the
4844 // annotation panel.
4845 List<String> remains = new ArrayList<String>(visan.keySet());
4846 for (int h = 0; h < hSize; h++)
4848 jalview.datamodel.AlignmentAnnotation jalan = al
4849 .getAlignmentAnnotation()[h];
4850 if (jalan.autoCalculated)
4853 JvAnnotRow valan = visan.get(k = jalan.label);
4854 if (jalan.getCalcId() != null)
4856 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4861 // delete the auto calculated row from the alignment
4862 al.deleteAnnotation(jalan, false);
4866 if (valan != nullAnnot)
4868 if (jalan != valan.template)
4870 // newly created autoannotation row instance
4871 // so keep a reference to the visible annotation row
4872 // and copy over all relevant attributes
4873 if (valan.template.graphHeight >= 0)
4876 jalan.graphHeight = valan.template.graphHeight;
4878 jalan.visible = valan.template.visible;
4880 reorder.add(new JvAnnotRow(valan.order, jalan));
4885 // Add any (possibly stale) autocalculated rows that were not appended to
4886 // the view during construction
4887 for (String other : remains)
4889 JvAnnotRow othera = visan.get(other);
4890 if (othera != nullAnnot && othera.template.getCalcId() != null
4891 && othera.template.getCalcId().length() > 0)
4893 reorder.add(othera);
4896 // now put the automatic annotation in its correct place
4897 int s = 0, srt[] = new int[reorder.size()];
4898 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4899 for (JvAnnotRow jvar : reorder)
4902 srt[s++] = jvar.order;
4905 jalview.util.QuickSort.sort(srt, rws);
4906 // and re-insert the annotation at its correct position
4907 for (JvAnnotRow jvar : rws)
4909 al.addAnnotation(jvar.template, jvar.order);
4911 af.alignPanel.adjustAnnotationHeight();
4915 Hashtable skipList = null;
4918 * TODO remove this method
4921 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4922 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4923 * throw new Error("Implementation Error. No skipList defined for this
4924 * Jalview2XML instance."); } return (AlignFrame)
4925 * skipList.get(view.getSequenceSetId()); }
4929 * Check if the Jalview view contained in object should be skipped or not.
4932 * @return true if view's sequenceSetId is a key in skipList
4934 private boolean skipViewport(JalviewModel object)
4936 if (skipList == null)
4941 if (skipList.containsKey(id = object.getJalviewModelSequence()
4942 .getViewport()[0].getSequenceSetId()))
4944 if (Cache.log != null && Cache.log.isDebugEnabled())
4946 Cache.log.debug("Skipping seuqence set id " + id);
4953 public void addToSkipList(AlignFrame af)
4955 if (skipList == null)
4957 skipList = new Hashtable();
4959 skipList.put(af.getViewport().getSequenceSetId(), af);
4962 public void clearSkipList()
4964 if (skipList != null)
4971 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4972 boolean ignoreUnrefed)
4974 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4976 Vector dseqs = null;
4979 // create a list of new dataset sequences
4980 dseqs = new Vector();
4982 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4984 Sequence vamsasSeq = vamsasSet.getSequence(i);
4985 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4987 // create a new dataset
4990 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4991 dseqs.copyInto(dsseqs);
4992 ds = new jalview.datamodel.Alignment(dsseqs);
4993 debug("Created new dataset " + vamsasSet.getDatasetId()
4994 + " for alignment " + System.identityHashCode(al));
4995 addDatasetRef(vamsasSet.getDatasetId(), ds);
4997 // set the dataset for the newly imported alignment.
4998 if (al.getDataset() == null && !ignoreUnrefed)
5007 * sequence definition to create/merge dataset sequence for
5011 * vector to add new dataset sequence to
5012 * @param ignoreUnrefed
5013 * - when true, don't create new sequences from vamsasSeq if it's id
5014 * doesn't already have an asssociated Jalview sequence.
5016 * - used to reorder the sequence in the alignment according to the
5017 * vamsasSeq array ordering, to preserve ordering of dataset
5019 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5020 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5022 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5024 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5025 boolean reorder = false;
5026 SequenceI dsq = null;
5027 if (sq != null && sq.getDatasetSequence() != null)
5029 dsq = sq.getDatasetSequence();
5035 if (sq == null && ignoreUnrefed)
5039 String sqid = vamsasSeq.getDsseqid();
5042 // need to create or add a new dataset sequence reference to this sequence
5045 dsq = seqRefIds.get(sqid);
5050 // make a new dataset sequence
5051 dsq = sq.createDatasetSequence();
5054 // make up a new dataset reference for this sequence
5055 sqid = seqHash(dsq);
5057 dsq.setVamsasId(uniqueSetSuffix + sqid);
5058 seqRefIds.put(sqid, dsq);
5063 dseqs.addElement(dsq);
5068 ds.addSequence(dsq);
5074 { // make this dataset sequence sq's dataset sequence
5075 sq.setDatasetSequence(dsq);
5076 // and update the current dataset alignment
5081 if (!dseqs.contains(dsq))
5088 if (ds.findIndex(dsq) < 0)
5090 ds.addSequence(dsq);
5097 // TODO: refactor this as a merge dataset sequence function
5098 // now check that sq (the dataset sequence) sequence really is the union of
5099 // all references to it
5100 // boolean pre = sq.getStart() < dsq.getStart();
5101 // boolean post = sq.getEnd() > dsq.getEnd();
5105 // StringBuffer sb = new StringBuffer();
5106 String newres = jalview.analysis.AlignSeq.extractGaps(
5107 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5108 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5109 && newres.length() > dsq.getLength())
5111 // Update with the longer sequence.
5115 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5116 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5117 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5118 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5120 dsq.setSequence(newres);
5122 // TODO: merges will never happen if we 'know' we have the real dataset
5123 // sequence - this should be detected when id==dssid
5125 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5126 // + (pre ? "prepended" : "") + " "
5127 // + (post ? "appended" : ""));
5132 // sequence refs are identical. We may need to update the existing dataset
5133 // alignment with this one, though.
5134 if (ds != null && dseqs == null)
5136 int opos = ds.findIndex(dsq);
5137 SequenceI tseq = null;
5138 if (opos != -1 && vseqpos != opos)
5140 // remove from old position
5141 ds.deleteSequence(dsq);
5143 if (vseqpos < ds.getHeight())
5145 if (vseqpos != opos)
5147 // save sequence at destination position
5148 tseq = ds.getSequenceAt(vseqpos);
5149 ds.replaceSequenceAt(vseqpos, dsq);
5150 ds.addSequence(tseq);
5155 ds.addSequence(dsq);
5162 * TODO use AlignmentI here and in related methods - needs
5163 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5165 Hashtable<String, AlignmentI> datasetIds = null;
5167 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5169 private AlignmentI getDatasetFor(String datasetId)
5171 if (datasetIds == null)
5173 datasetIds = new Hashtable<String, AlignmentI>();
5176 if (datasetIds.containsKey(datasetId))
5178 return datasetIds.get(datasetId);
5183 private void addDatasetRef(String datasetId, AlignmentI dataset)
5185 if (datasetIds == null)
5187 datasetIds = new Hashtable<String, AlignmentI>();
5189 datasetIds.put(datasetId, dataset);
5193 * make a new dataset ID for this jalview dataset alignment
5198 private String getDatasetIdRef(AlignmentI dataset)
5200 if (dataset.getDataset() != null)
5202 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5204 String datasetId = makeHashCode(dataset, null);
5205 if (datasetId == null)
5207 // make a new datasetId and record it
5208 if (dataset2Ids == null)
5210 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5214 datasetId = dataset2Ids.get(dataset);
5216 if (datasetId == null)
5218 datasetId = "ds" + dataset2Ids.size() + 1;
5219 dataset2Ids.put(dataset, datasetId);
5225 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5227 for (int d = 0; d < sequence.getDBRefCount(); d++)
5229 DBRef dr = sequence.getDBRef(d);
5230 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5231 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5232 .getVersion(), sequence.getDBRef(d).getAccessionId());
5233 if (dr.getMapping() != null)
5235 entry.setMap(addMapping(dr.getMapping()));
5237 datasetSequence.addDBRef(entry);
5241 private jalview.datamodel.Mapping addMapping(Mapping m)
5243 SequenceI dsto = null;
5244 // Mapping m = dr.getMapping();
5245 int fr[] = new int[m.getMapListFromCount() * 2];
5246 Enumeration f = m.enumerateMapListFrom();
5247 for (int _i = 0; f.hasMoreElements(); _i += 2)
5249 MapListFrom mf = (MapListFrom) f.nextElement();
5250 fr[_i] = mf.getStart();
5251 fr[_i + 1] = mf.getEnd();
5253 int fto[] = new int[m.getMapListToCount() * 2];
5254 f = m.enumerateMapListTo();
5255 for (int _i = 0; f.hasMoreElements(); _i += 2)
5257 MapListTo mf = (MapListTo) f.nextElement();
5258 fto[_i] = mf.getStart();
5259 fto[_i + 1] = mf.getEnd();
5261 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5262 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5263 if (m.getMappingChoice() != null)
5265 MappingChoice mc = m.getMappingChoice();
5266 if (mc.getDseqFor() != null)
5268 String dsfor = "" + mc.getDseqFor();
5269 if (seqRefIds.containsKey(dsfor))
5274 jmap.setTo(seqRefIds.get(dsfor));
5278 frefedSequence.add(newMappingRef(dsfor, jmap));
5284 * local sequence definition
5286 Sequence ms = mc.getSequence();
5287 SequenceI djs = null;
5288 String sqid = ms.getDsseqid();
5289 if (sqid != null && sqid.length() > 0)
5292 * recover dataset sequence
5294 djs = seqRefIds.get(sqid);
5299 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5300 sqid = ((Object) ms).toString(); // make up a new hascode for
5301 // undefined dataset sequence hash
5302 // (unlikely to happen)
5308 * make a new dataset sequence and add it to refIds hash
5310 djs = new jalview.datamodel.Sequence(ms.getName(),
5312 djs.setStart(jmap.getMap().getToLowest());
5313 djs.setEnd(jmap.getMap().getToHighest());
5314 djs.setVamsasId(uniqueSetSuffix + sqid);
5316 incompleteSeqs.put(sqid, djs);
5317 seqRefIds.put(sqid, djs);
5320 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5329 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5330 boolean keepSeqRefs)
5333 JalviewModel jm = saveState(ap, null, null, null);
5338 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5342 uniqueSetSuffix = "";
5343 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5348 if (this.frefedSequence == null)
5350 frefedSequence = new Vector();
5353 viewportsAdded.clear();
5355 AlignFrame af = loadFromObject(jm, null, false, null);
5356 af.alignPanels.clear();
5357 af.closeMenuItem_actionPerformed(true);
5360 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5361 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5362 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5363 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5364 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5367 return af.alignPanel;
5371 * flag indicating if hashtables should be cleared on finalization TODO this
5372 * flag may not be necessary
5374 private final boolean _cleartables = true;
5376 private Hashtable jvids2vobj;
5381 * @see java.lang.Object#finalize()
5384 protected void finalize() throws Throwable
5386 // really make sure we have no buried refs left.
5391 this.seqRefIds = null;
5392 this.seqsToIds = null;
5396 private void warn(String msg)
5401 private void warn(String msg, Exception e)
5403 if (Cache.log != null)
5407 Cache.log.warn(msg, e);
5411 Cache.log.warn(msg);
5416 System.err.println("Warning: " + msg);
5419 e.printStackTrace();
5424 private void debug(String string)
5426 debug(string, null);
5429 private void debug(String msg, Exception e)
5431 if (Cache.log != null)
5435 Cache.log.debug(msg, e);
5439 Cache.log.debug(msg);
5444 System.err.println("Warning: " + msg);
5447 e.printStackTrace();
5453 * set the object to ID mapping tables used to write/recover objects and XML
5454 * ID strings for the jalview project. If external tables are provided then
5455 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5456 * object goes out of scope. - also populates the datasetIds hashtable with
5457 * alignment objects containing dataset sequences
5460 * Map from ID strings to jalview datamodel
5462 * Map from jalview datamodel to ID strings
5466 public void setObjectMappingTables(Hashtable vobj2jv,
5467 IdentityHashMap jv2vobj)
5469 this.jv2vobj = jv2vobj;
5470 this.vobj2jv = vobj2jv;
5471 Iterator ds = jv2vobj.keySet().iterator();
5473 while (ds.hasNext())
5475 Object jvobj = ds.next();
5476 id = jv2vobj.get(jvobj).toString();
5477 if (jvobj instanceof jalview.datamodel.Alignment)
5479 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5481 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5484 else if (jvobj instanceof jalview.datamodel.Sequence)
5486 // register sequence object so the XML parser can recover it.
5487 if (seqRefIds == null)
5489 seqRefIds = new HashMap<String, SequenceI>();
5491 if (seqsToIds == null)
5493 seqsToIds = new IdentityHashMap<SequenceI, String>();
5495 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5496 seqsToIds.put((SequenceI) jvobj, id);
5498 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5501 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5502 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5503 if (jvann.annotationId == null)
5505 jvann.annotationId = anid;
5507 if (!jvann.annotationId.equals(anid))
5509 // TODO verify that this is the correct behaviour
5510 this.warn("Overriding Annotation ID for " + anid
5511 + " from different id : " + jvann.annotationId);
5512 jvann.annotationId = anid;
5515 else if (jvobj instanceof String)
5517 if (jvids2vobj == null)
5519 jvids2vobj = new Hashtable();
5520 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5525 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5531 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5532 * objects created from the project archive. If string is null (default for
5533 * construction) then suffix will be set automatically.
5537 public void setUniqueSetSuffix(String string)
5539 uniqueSetSuffix = string;
5544 * uses skipList2 as the skipList for skipping views on sequence sets
5545 * associated with keys in the skipList
5549 public void setSkipList(Hashtable skipList2)
5551 skipList = skipList2;
5555 * Reads the jar entry of given name and returns its contents, or null if the
5556 * entry is not found.
5559 * @param jarEntryName
5562 protected String readJarEntry(jarInputStreamProvider jprovider,
5563 String jarEntryName)
5565 String result = null;
5566 BufferedReader in = null;
5571 * Reopen the jar input stream and traverse its entries to find a matching
5574 JarInputStream jin = jprovider.getJarInputStream();
5575 JarEntry entry = null;
5578 entry = jin.getNextJarEntry();
5579 } while (entry != null && !entry.getName().equals(jarEntryName));
5583 StringBuilder out = new StringBuilder(256);
5584 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5587 while ((data = in.readLine()) != null)
5591 result = out.toString();
5595 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5597 } catch (Exception ex)
5599 ex.printStackTrace();
5607 } catch (IOException e)
5618 * Returns an incrementing counter (0, 1, 2...)
5622 private synchronized int nextCounter()