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.io.DataSourceType;
41 import jalview.io.FileFormat;
42 import jalview.schemabinding.version2.AlcodMap;
43 import jalview.schemabinding.version2.AlcodonFrame;
44 import jalview.schemabinding.version2.Annotation;
45 import jalview.schemabinding.version2.AnnotationColours;
46 import jalview.schemabinding.version2.AnnotationElement;
47 import jalview.schemabinding.version2.CalcIdParam;
48 import jalview.schemabinding.version2.DBRef;
49 import jalview.schemabinding.version2.Features;
50 import jalview.schemabinding.version2.Group;
51 import jalview.schemabinding.version2.HiddenColumns;
52 import jalview.schemabinding.version2.JGroup;
53 import jalview.schemabinding.version2.JSeq;
54 import jalview.schemabinding.version2.JalviewModel;
55 import jalview.schemabinding.version2.JalviewModelSequence;
56 import jalview.schemabinding.version2.MapListFrom;
57 import jalview.schemabinding.version2.MapListTo;
58 import jalview.schemabinding.version2.Mapping;
59 import jalview.schemabinding.version2.MappingChoice;
60 import jalview.schemabinding.version2.OtherData;
61 import jalview.schemabinding.version2.PdbentryItem;
62 import jalview.schemabinding.version2.Pdbids;
63 import jalview.schemabinding.version2.Property;
64 import jalview.schemabinding.version2.RnaViewer;
65 import jalview.schemabinding.version2.SecondaryStructure;
66 import jalview.schemabinding.version2.Sequence;
67 import jalview.schemabinding.version2.SequenceSet;
68 import jalview.schemabinding.version2.SequenceSetProperties;
69 import jalview.schemabinding.version2.Setting;
70 import jalview.schemabinding.version2.StructureState;
71 import jalview.schemabinding.version2.ThresholdLine;
72 import jalview.schemabinding.version2.Tree;
73 import jalview.schemabinding.version2.UserColours;
74 import jalview.schemabinding.version2.Viewport;
75 import jalview.schemes.AnnotationColourGradient;
76 import jalview.schemes.CollectionColourSchemeI;
77 import jalview.schemes.ColourSchemeI;
78 import jalview.schemes.ColourSchemeProperty;
79 import jalview.schemes.FeatureColour;
80 import jalview.schemes.ResidueColourScheme;
81 import jalview.schemes.ResidueProperties;
82 import jalview.schemes.UserColourScheme;
83 import jalview.structure.StructureSelectionManager;
84 import jalview.structures.models.AAStructureBindingModel;
85 import jalview.util.MessageManager;
86 import jalview.util.Platform;
87 import jalview.util.StringUtils;
88 import jalview.util.jarInputStreamProvider;
89 import jalview.viewmodel.AlignmentViewport;
90 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
91 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
92 import jalview.ws.jws2.Jws2Discoverer;
93 import jalview.ws.jws2.dm.AAConSettings;
94 import jalview.ws.jws2.jabaws2.Jws2Instance;
95 import jalview.ws.params.ArgumentI;
96 import jalview.ws.params.AutoCalcSetting;
97 import jalview.ws.params.WsParamSetI;
99 import java.awt.Color;
100 import java.awt.Rectangle;
101 import java.io.BufferedReader;
102 import java.io.DataInputStream;
103 import java.io.DataOutputStream;
105 import java.io.FileInputStream;
106 import java.io.FileOutputStream;
107 import java.io.IOException;
108 import java.io.InputStreamReader;
109 import java.io.OutputStreamWriter;
110 import java.io.PrintWriter;
111 import java.lang.reflect.InvocationTargetException;
112 import java.net.MalformedURLException;
114 import java.util.ArrayList;
115 import java.util.Arrays;
116 import java.util.Enumeration;
117 import java.util.HashMap;
118 import java.util.HashSet;
119 import java.util.Hashtable;
120 import java.util.IdentityHashMap;
121 import java.util.Iterator;
122 import java.util.LinkedHashMap;
123 import java.util.List;
124 import java.util.Map;
125 import java.util.Map.Entry;
126 import java.util.Set;
127 import java.util.Vector;
128 import java.util.jar.JarEntry;
129 import java.util.jar.JarInputStream;
130 import java.util.jar.JarOutputStream;
132 import javax.swing.JInternalFrame;
133 import javax.swing.SwingUtilities;
135 import org.exolab.castor.xml.Marshaller;
136 import org.exolab.castor.xml.Unmarshaller;
139 * Write out the current jalview desktop state as a Jalview XML stream.
141 * Note: the vamsas objects referred to here are primitive versions of the
142 * VAMSAS project schema elements - they are not the same and most likely never
146 * @version $Revision: 1.134 $
148 public class Jalview2XML
150 private static final String VIEWER_PREFIX = "viewer_";
152 private static final String RNA_PREFIX = "rna_";
154 private static final String UTF_8 = "UTF-8";
156 // use this with nextCounter() to make unique names for entities
157 private int counter = 0;
160 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
161 * of sequence objects are created.
163 IdentityHashMap<SequenceI, String> seqsToIds = null;
166 * jalview XML Sequence ID to jalview sequence object reference (both dataset
167 * and alignment sequences. Populated as XML reps of sequence objects are
170 Map<String, SequenceI> seqRefIds = null;
172 Map<String, SequenceI> incompleteSeqs = null;
174 List<SeqFref> frefedSequence = null;
176 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
179 * Map of reconstructed AlignFrame objects that appear to have come from
180 * SplitFrame objects (have a dna/protein complement view).
182 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
185 * Map from displayed rna structure models to their saved session state jar
188 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
191 * create/return unique hash string for sq
194 * @return new or existing unique string for sq
196 String seqHash(SequenceI sq)
198 if (seqsToIds == null)
202 if (seqsToIds.containsKey(sq))
204 return seqsToIds.get(sq);
208 // create sequential key
209 String key = "sq" + (seqsToIds.size() + 1);
210 key = makeHashCode(sq, key); // check we don't have an external reference
212 seqsToIds.put(sq, key);
221 if (seqRefIds != null)
225 if (seqsToIds != null)
229 if (incompleteSeqs != null)
231 incompleteSeqs.clear();
239 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
240 // seqRefIds = new Hashtable();
241 // seqsToIds = new IdentityHashMap();
247 if (seqsToIds == null)
249 seqsToIds = new IdentityHashMap<SequenceI, String>();
251 if (seqRefIds == null)
253 seqRefIds = new HashMap<String, SequenceI>();
255 if (incompleteSeqs == null)
257 incompleteSeqs = new HashMap<String, SequenceI>();
259 if (frefedSequence == null)
261 frefedSequence = new ArrayList<SeqFref>();
269 public Jalview2XML(boolean raiseGUI)
271 this.raiseGUI = raiseGUI;
275 * base class for resolving forward references to sequences by their ID
280 abstract class SeqFref
286 public SeqFref(String _sref, String type)
292 public String getSref()
297 public SequenceI getSrefSeq()
299 return seqRefIds.get(sref);
302 public boolean isResolvable()
304 return seqRefIds.get(sref) != null;
307 public SequenceI getSrefDatasetSeq()
309 SequenceI sq = seqRefIds.get(sref);
312 while (sq.getDatasetSequence() != null)
314 sq = sq.getDatasetSequence();
321 * @return true if the forward reference was fully resolved
323 abstract boolean resolve();
326 public String toString()
328 return type + " reference to " + sref;
333 * create forward reference for a mapping
339 public SeqFref newMappingRef(final String sref,
340 final jalview.datamodel.Mapping _jmap)
342 SeqFref fref = new SeqFref(sref, "Mapping")
344 public jalview.datamodel.Mapping jmap = _jmap;
349 SequenceI seq = getSrefDatasetSeq();
361 public SeqFref newAlcodMapRef(final String sref,
362 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
365 SeqFref fref = new SeqFref(sref, "Codon Frame")
367 AlignedCodonFrame cf = _cf;
369 public jalview.datamodel.Mapping mp = _jmap;
372 public boolean isResolvable()
374 return super.isResolvable() && mp.getTo() != null;
380 SequenceI seq = getSrefDatasetSeq();
385 cf.addMap(seq, mp.getTo(), mp.getMap());
392 public void resolveFrefedSequences()
394 Iterator<SeqFref> nextFref = frefedSequence.iterator();
395 int toresolve = frefedSequence.size();
396 int unresolved = 0, failedtoresolve = 0;
397 while (nextFref.hasNext())
399 SeqFref ref = nextFref.next();
400 if (ref.isResolvable())
412 } catch (Exception x)
415 .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
428 System.err.println("Jalview Project Import: There were " + unresolved
429 + " forward references left unresolved on the stack.");
431 if (failedtoresolve > 0)
433 System.err.println("SERIOUS! " + failedtoresolve
434 + " resolvable forward references failed to resolve.");
436 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
438 System.err.println("Jalview Project Import: There are "
439 + incompleteSeqs.size()
440 + " sequences which may have incomplete metadata.");
441 if (incompleteSeqs.size() < 10)
443 for (SequenceI s : incompleteSeqs.values())
445 System.err.println(s.toString());
451 .println("Too many to report. Skipping output of incomplete sequences.");
457 * This maintains a map of viewports, the key being the seqSetId. Important to
458 * set historyItem and redoList for multiple views
460 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
462 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
464 String uniqueSetSuffix = "";
467 * List of pdbfiles added to Jar
469 List<String> pdbfiles = null;
471 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
472 public void saveState(File statefile)
474 FileOutputStream fos = null;
477 fos = new FileOutputStream(statefile);
478 JarOutputStream jout = new JarOutputStream(fos);
481 } catch (Exception e)
483 // TODO: inform user of the problem - they need to know if their data was
485 if (errorMessage == null)
487 errorMessage = "Couldn't write Jalview Archive to output file '"
488 + statefile + "' - See console error log for details";
492 errorMessage += "(output file was '" + statefile + "')";
502 } catch (IOException e)
512 * Writes a jalview project archive to the given Jar output stream.
516 public void saveState(JarOutputStream jout)
518 AlignFrame[] frames = Desktop.getAlignFrames();
524 saveAllFrames(Arrays.asList(frames), jout);
528 * core method for storing state for a set of AlignFrames.
531 * - frames involving all data to be exported (including containing
534 * - project output stream
536 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
538 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
541 * ensure cached data is clear before starting
543 // todo tidy up seqRefIds, seqsToIds initialisation / reset
545 splitFrameCandidates.clear();
550 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
551 // //////////////////////////////////////////////////
553 List<String> shortNames = new ArrayList<String>();
554 List<String> viewIds = new ArrayList<String>();
557 for (int i = frames.size() - 1; i > -1; i--)
559 AlignFrame af = frames.get(i);
563 .containsKey(af.getViewport().getSequenceSetId()))
568 String shortName = makeFilename(af, shortNames);
570 int ap, apSize = af.alignPanels.size();
572 for (ap = 0; ap < apSize; ap++)
574 AlignmentPanel apanel = af.alignPanels.get(ap);
575 String fileName = apSize == 1 ? shortName : ap + shortName;
576 if (!fileName.endsWith(".xml"))
578 fileName = fileName + ".xml";
581 saveState(apanel, fileName, jout, viewIds);
583 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
585 if (!dsses.containsKey(dssid))
587 dsses.put(dssid, af);
592 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
598 } catch (Exception foo)
603 } catch (Exception ex)
605 // TODO: inform user of the problem - they need to know if their data was
607 if (errorMessage == null)
609 errorMessage = "Couldn't write Jalview Archive - see error output for details";
611 ex.printStackTrace();
616 * Generates a distinct file name, based on the title of the AlignFrame, by
617 * appending _n for increasing n until an unused name is generated. The new
618 * name (without its extension) is added to the list.
622 * @return the generated name, with .xml extension
624 protected String makeFilename(AlignFrame af, List<String> namesUsed)
626 String shortName = af.getTitle();
628 if (shortName.indexOf(File.separatorChar) > -1)
630 shortName = shortName.substring(shortName
631 .lastIndexOf(File.separatorChar) + 1);
636 while (namesUsed.contains(shortName))
638 if (shortName.endsWith("_" + (count - 1)))
640 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
643 shortName = shortName.concat("_" + count);
647 namesUsed.add(shortName);
649 if (!shortName.endsWith(".xml"))
651 shortName = shortName + ".xml";
656 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
657 public boolean saveAlignment(AlignFrame af, String jarFile,
662 FileOutputStream fos = new FileOutputStream(jarFile);
663 JarOutputStream jout = new JarOutputStream(fos);
664 List<AlignFrame> frames = new ArrayList<AlignFrame>();
666 // resolve splitframes
667 if (af.getViewport().getCodingComplement() != null)
669 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
675 saveAllFrames(frames, jout);
679 } catch (Exception foo)
685 } catch (Exception ex)
687 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
688 ex.printStackTrace();
693 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
694 String fileName, JarOutputStream jout)
697 for (String dssids : dsses.keySet())
699 AlignFrame _af = dsses.get(dssids);
700 String jfileName = fileName + " Dataset for " + _af.getTitle();
701 if (!jfileName.endsWith(".xml"))
703 jfileName = jfileName + ".xml";
705 saveState(_af.alignPanel, jfileName, true, jout, null);
710 * create a JalviewModel from an alignment view and marshall it to a
714 * panel to create jalview model for
716 * name of alignment panel written to output stream
723 public JalviewModel saveState(AlignmentPanel ap, String fileName,
724 JarOutputStream jout, List<String> viewIds)
726 return saveState(ap, fileName, false, jout, viewIds);
730 * create a JalviewModel from an alignment view and marshall it to a
734 * panel to create jalview model for
736 * name of alignment panel written to output stream
738 * when true, only write the dataset for the alignment, not the data
739 * associated with the view.
745 public JalviewModel saveState(AlignmentPanel ap, String fileName,
746 boolean storeDS, JarOutputStream jout, List<String> viewIds)
750 viewIds = new ArrayList<String>();
755 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
757 AlignViewport av = ap.av;
759 JalviewModel object = new JalviewModel();
760 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
762 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
763 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
764 "Development Build"));
767 * rjal is full height alignment, jal is actual alignment with full metadata
768 * but excludes hidden sequences.
770 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
772 if (av.hasHiddenRows())
774 rjal = jal.getHiddenSequences().getFullAlignment();
777 SequenceSet vamsasSet = new SequenceSet();
779 JalviewModelSequence jms = new JalviewModelSequence();
781 vamsasSet.setGapChar(jal.getGapCharacter() + "");
783 if (jal.getDataset() != null)
785 // dataset id is the dataset's hashcode
786 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
789 // switch jal and the dataset
790 jal = jal.getDataset();
794 if (jal.getProperties() != null)
796 Enumeration en = jal.getProperties().keys();
797 while (en.hasMoreElements())
799 String key = en.nextElement().toString();
800 SequenceSetProperties ssp = new SequenceSetProperties();
802 ssp.setValue(jal.getProperties().get(key).toString());
803 vamsasSet.addSequenceSetProperties(ssp);
808 Set<String> calcIdSet = new HashSet<String>();
809 // record the set of vamsas sequence XML POJO we create.
810 HashMap<String, Sequence> vamsasSetIds = new HashMap<String, Sequence>();
812 for (final SequenceI jds : rjal.getSequences())
814 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
815 : jds.getDatasetSequence();
816 String id = seqHash(jds);
817 if (vamsasSetIds.get(id) == null)
819 if (seqRefIds.get(id) != null && !storeDS)
821 // This happens for two reasons: 1. multiple views are being
823 // 2. the hashCode has collided with another sequence's code. This
825 // HAPPEN! (PF00072.15.stk does this)
826 // JBPNote: Uncomment to debug writing out of files that do not read
827 // back in due to ArrayOutOfBoundExceptions.
828 // System.err.println("vamsasSeq backref: "+id+"");
829 // System.err.println(jds.getName()+"
830 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
831 // System.err.println("Hashcode: "+seqHash(jds));
832 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
833 // System.err.println(rsq.getName()+"
834 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
835 // System.err.println("Hashcode: "+seqHash(rsq));
839 vamsasSeq = createVamsasSequence(id, jds);
840 vamsasSet.addSequence(vamsasSeq);
841 vamsasSetIds.put(id, vamsasSeq);
842 seqRefIds.put(id, jds);
846 jseq.setStart(jds.getStart());
847 jseq.setEnd(jds.getEnd());
848 jseq.setColour(av.getSequenceColour(jds).getRGB());
850 jseq.setId(id); // jseq id should be a string not a number
853 // Store any sequences this sequence represents
854 if (av.hasHiddenRows())
856 // use rjal, contains the full height alignment
857 jseq.setHidden(av.getAlignment().getHiddenSequences()
860 if (av.isHiddenRepSequence(jds))
862 jalview.datamodel.SequenceI[] reps = av
863 .getRepresentedSequences(jds).getSequencesInOrder(rjal);
865 for (int h = 0; h < reps.length; h++)
869 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
874 // mark sequence as reference - if it is the reference for this view
877 jseq.setViewreference(jds == jal.getSeqrep());
881 // TODO: omit sequence features from each alignment view's XML dump if we
882 // are storing dataset
883 if (jds.getSequenceFeatures() != null)
885 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
887 while (index < sf.length)
889 Features features = new Features();
891 features.setBegin(sf[index].getBegin());
892 features.setEnd(sf[index].getEnd());
893 features.setDescription(sf[index].getDescription());
894 features.setType(sf[index].getType());
895 features.setFeatureGroup(sf[index].getFeatureGroup());
896 features.setScore(sf[index].getScore());
897 if (sf[index].links != null)
899 for (int l = 0; l < sf[index].links.size(); l++)
901 OtherData keyValue = new OtherData();
902 keyValue.setKey("LINK_" + l);
903 keyValue.setValue(sf[index].links.elementAt(l).toString());
904 features.addOtherData(keyValue);
907 if (sf[index].otherDetails != null)
910 Iterator<String> keys = sf[index].otherDetails.keySet()
912 while (keys.hasNext())
915 OtherData keyValue = new OtherData();
916 keyValue.setKey(key);
917 keyValue.setValue(sf[index].otherDetails.get(key).toString());
918 features.addOtherData(keyValue);
922 jseq.addFeatures(features);
927 if (jdatasq.getAllPDBEntries() != null)
929 Enumeration en = jdatasq.getAllPDBEntries().elements();
930 while (en.hasMoreElements())
932 Pdbids pdb = new Pdbids();
933 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
936 String pdbId = entry.getId();
938 pdb.setType(entry.getType());
941 * Store any structure views associated with this sequence. This
942 * section copes with duplicate entries in the project, so a dataset
943 * only view *should* be coped with sensibly.
945 // This must have been loaded, is it still visible?
946 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
947 String matchedFile = null;
948 for (int f = frames.length - 1; f > -1; f--)
950 if (frames[f] instanceof StructureViewerBase)
952 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
953 matchedFile = saveStructureState(ap, jds, pdb, entry,
954 viewIds, matchedFile, viewFrame);
956 * Only store each structure viewer's state once in the project
957 * jar. First time through only (storeDS==false)
959 String viewId = viewFrame.getViewId();
960 if (!storeDS && !viewIds.contains(viewId))
965 String viewerState = viewFrame.getStateInfo();
966 writeJarEntry(jout, getViewerJarEntryName(viewId),
967 viewerState.getBytes());
968 } catch (IOException e)
970 System.err.println("Error saving viewer state: "
977 if (matchedFile != null || entry.getFile() != null)
979 if (entry.getFile() != null)
982 matchedFile = entry.getFile();
984 pdb.setFile(matchedFile); // entry.getFile());
985 if (pdbfiles == null)
987 pdbfiles = new ArrayList<String>();
990 if (!pdbfiles.contains(pdbId))
993 copyFileToJar(jout, matchedFile, pdbId);
997 Enumeration<String> props = entry.getProperties();
998 if (props.hasMoreElements())
1000 PdbentryItem item = new PdbentryItem();
1001 while (props.hasMoreElements())
1003 Property prop = new Property();
1004 String key = props.nextElement();
1006 prop.setValue(entry.getProperty(key).toString());
1007 item.addProperty(prop);
1009 pdb.addPdbentryItem(item);
1012 jseq.addPdbids(pdb);
1016 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1021 if (!storeDS && av.hasHiddenRows())
1023 jal = av.getAlignment();
1027 if (storeDS && jal.getCodonFrames() != null)
1029 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1030 for (AlignedCodonFrame acf : jac)
1032 AlcodonFrame alc = new AlcodonFrame();
1033 if (acf.getProtMappings() != null
1034 && acf.getProtMappings().length > 0)
1036 boolean hasMap = false;
1037 SequenceI[] dnas = acf.getdnaSeqs();
1038 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1039 for (int m = 0; m < pmaps.length; m++)
1041 AlcodMap alcmap = new AlcodMap();
1042 alcmap.setDnasq(seqHash(dnas[m]));
1043 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1045 alc.addAlcodMap(alcmap);
1050 vamsasSet.addAlcodonFrame(alc);
1053 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1055 // AlcodonFrame alc = new AlcodonFrame();
1056 // vamsasSet.addAlcodonFrame(alc);
1057 // for (int p = 0; p < acf.aaWidth; p++)
1059 // Alcodon cmap = new Alcodon();
1060 // if (acf.codons[p] != null)
1062 // // Null codons indicate a gapped column in the translated peptide
1064 // cmap.setPos1(acf.codons[p][0]);
1065 // cmap.setPos2(acf.codons[p][1]);
1066 // cmap.setPos3(acf.codons[p][2]);
1068 // alc.addAlcodon(cmap);
1070 // if (acf.getProtMappings() != null
1071 // && acf.getProtMappings().length > 0)
1073 // SequenceI[] dnas = acf.getdnaSeqs();
1074 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1075 // for (int m = 0; m < pmaps.length; m++)
1077 // AlcodMap alcmap = new AlcodMap();
1078 // alcmap.setDnasq(seqHash(dnas[m]));
1079 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1081 // alc.addAlcodMap(alcmap);
1088 // /////////////////////////////////
1089 if (!storeDS && av.currentTree != null)
1091 // FIND ANY ASSOCIATED TREES
1092 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1093 if (Desktop.desktop != null)
1095 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1097 for (int t = 0; t < frames.length; t++)
1099 if (frames[t] instanceof TreePanel)
1101 TreePanel tp = (TreePanel) frames[t];
1103 if (tp.treeCanvas.av.getAlignment() == jal)
1105 Tree tree = new Tree();
1106 tree.setTitle(tp.getTitle());
1107 tree.setCurrentTree((av.currentTree == tp.getTree()));
1108 tree.setNewick(tp.getTree().toString());
1109 tree.setThreshold(tp.treeCanvas.threshold);
1111 tree.setFitToWindow(tp.fitToWindow.getState());
1112 tree.setFontName(tp.getTreeFont().getName());
1113 tree.setFontSize(tp.getTreeFont().getSize());
1114 tree.setFontStyle(tp.getTreeFont().getStyle());
1115 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1117 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1118 tree.setShowDistances(tp.distanceMenu.getState());
1120 tree.setHeight(tp.getHeight());
1121 tree.setWidth(tp.getWidth());
1122 tree.setXpos(tp.getX());
1123 tree.setYpos(tp.getY());
1124 tree.setId(makeHashCode(tp, null));
1134 * store forward refs from an annotationRow to any groups
1136 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1139 for (SequenceI sq : jal.getSequences())
1141 // Store annotation on dataset sequences only
1142 AlignmentAnnotation[] aa = sq.getAnnotation();
1143 if (aa != null && aa.length > 0)
1145 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1152 if (jal.getAlignmentAnnotation() != null)
1154 // Store the annotation shown on the alignment.
1155 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1156 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1161 if (jal.getGroups() != null)
1163 JGroup[] groups = new JGroup[jal.getGroups().size()];
1165 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1167 JGroup jGroup = new JGroup();
1168 groups[++i] = jGroup;
1170 jGroup.setStart(sg.getStartRes());
1171 jGroup.setEnd(sg.getEndRes());
1172 jGroup.setName(sg.getName());
1173 if (groupRefs.containsKey(sg))
1175 // group has references so set its ID field
1176 jGroup.setId(groupRefs.get(sg));
1178 ColourSchemeI colourScheme = sg.getColourScheme();
1179 if (colourScheme != null)
1181 CollectionColourSchemeI groupColourScheme = sg
1182 .getGroupColourScheme();
1183 if (groupColourScheme.conservationApplied())
1185 jGroup.setConsThreshold(groupColourScheme.getConservationInc());
1187 if (colourScheme instanceof jalview.schemes.UserColourScheme)
1189 jGroup.setColour(setUserColourScheme(colourScheme,
1194 jGroup.setColour(colourScheme.getSchemeName());
1197 else if (colourScheme instanceof jalview.schemes.AnnotationColourGradient)
1199 jGroup.setColour("AnnotationColourGradient");
1200 jGroup.setAnnotationColours(constructAnnotationColours(
1201 (jalview.schemes.AnnotationColourGradient) colourScheme,
1204 else if (colourScheme instanceof jalview.schemes.UserColourScheme)
1206 jGroup.setColour(setUserColourScheme(colourScheme,
1211 jGroup.setColour(colourScheme.getSchemeName());
1214 jGroup.setPidThreshold(groupColourScheme.getThreshold());
1217 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1218 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1219 jGroup.setDisplayText(sg.getDisplayText());
1220 jGroup.setColourText(sg.getColourText());
1221 jGroup.setTextCol1(sg.textColour.getRGB());
1222 jGroup.setTextCol2(sg.textColour2.getRGB());
1223 jGroup.setTextColThreshold(sg.thresholdTextColour);
1224 jGroup.setShowUnconserved(sg.getShowNonconserved());
1225 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1226 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1227 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1228 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1229 for (SequenceI seq : sg.getSequences())
1231 jGroup.addSeq(seqHash(seq));
1235 jms.setJGroup(groups);
1239 // /////////SAVE VIEWPORT
1240 Viewport view = new Viewport();
1241 view.setTitle(ap.alignFrame.getTitle());
1242 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1243 av.getSequenceSetId()));
1244 view.setId(av.getViewId());
1245 if (av.getCodingComplement() != null)
1247 view.setComplementId(av.getCodingComplement().getViewId());
1249 view.setViewName(av.viewName);
1250 view.setGatheredViews(av.isGatherViewsHere());
1252 Rectangle size = ap.av.getExplodedGeometry();
1253 Rectangle position = size;
1256 size = ap.alignFrame.getBounds();
1257 if (av.getCodingComplement() != null)
1259 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1267 view.setXpos(position.x);
1268 view.setYpos(position.y);
1270 view.setWidth(size.width);
1271 view.setHeight(size.height);
1273 view.setStartRes(av.startRes);
1274 view.setStartSeq(av.startSeq);
1276 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1278 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1281 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1283 AnnotationColours ac = constructAnnotationColours(
1284 (jalview.schemes.AnnotationColourGradient) av
1285 .getGlobalColourScheme(),
1288 view.setAnnotationColours(ac);
1289 view.setBgColour("AnnotationColourGradient");
1293 view.setBgColour(ColourSchemeProperty.getColourName(av
1294 .getGlobalColourScheme()));
1297 CollectionColourSchemeI vcs = av.getViewportColourScheme();
1298 ColourSchemeI cs = av.getGlobalColourScheme();
1302 if (vcs.conservationApplied())
1304 view.setConsThreshold(vcs.getConservationInc());
1305 if (cs instanceof jalview.schemes.UserColourScheme)
1307 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1310 view.setPidThreshold(vcs.getThreshold());
1313 view.setConservationSelected(av.getConservationSelected());
1314 view.setPidSelected(av.getAbovePIDThreshold());
1315 view.setFontName(av.font.getName());
1316 view.setFontSize(av.font.getSize());
1317 view.setFontStyle(av.font.getStyle());
1318 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1319 view.setRenderGaps(av.isRenderGaps());
1320 view.setShowAnnotation(av.isShowAnnotation());
1321 view.setShowBoxes(av.getShowBoxes());
1322 view.setShowColourText(av.getColourText());
1323 view.setShowFullId(av.getShowJVSuffix());
1324 view.setRightAlignIds(av.isRightAlignIds());
1325 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1326 view.setShowText(av.getShowText());
1327 view.setShowUnconserved(av.getShowUnconserved());
1328 view.setWrapAlignment(av.getWrapAlignment());
1329 view.setTextCol1(av.getTextColour().getRGB());
1330 view.setTextCol2(av.getTextColour2().getRGB());
1331 view.setTextColThreshold(av.getThresholdTextColour());
1332 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1333 view.setShowSequenceLogo(av.isShowSequenceLogo());
1334 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1335 view.setShowGroupConsensus(av.isShowGroupConsensus());
1336 view.setShowGroupConservation(av.isShowGroupConservation());
1337 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1338 view.setShowDbRefTooltip(av.isShowDBRefs());
1339 view.setFollowHighlight(av.isFollowHighlight());
1340 view.setFollowSelection(av.followSelection);
1341 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1342 if (av.getFeaturesDisplayed() != null)
1344 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1346 String[] renderOrder = ap.getSeqPanel().seqCanvas
1347 .getFeatureRenderer().getRenderOrder()
1348 .toArray(new String[0]);
1350 Vector<String> settingsAdded = new Vector<String>();
1351 if (renderOrder != null)
1353 for (String featureType : renderOrder)
1355 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1356 .getFeatureRenderer().getFeatureStyle(featureType);
1357 Setting setting = new Setting();
1358 setting.setType(featureType);
1359 if (!fcol.isSimpleColour())
1361 setting.setColour(fcol.getMaxColour().getRGB());
1362 setting.setMincolour(fcol.getMinColour().getRGB());
1363 setting.setMin(fcol.getMin());
1364 setting.setMax(fcol.getMax());
1365 setting.setColourByLabel(fcol.isColourByLabel());
1366 setting.setAutoScale(fcol.isAutoScaled());
1367 setting.setThreshold(fcol.getThreshold());
1368 // -1 = No threshold, 0 = Below, 1 = Above
1369 setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
1370 .isBelowThreshold() ? 0 : -1));
1374 setting.setColour(fcol.getColour().getRGB());
1377 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1379 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1380 .getOrder(featureType);
1383 setting.setOrder(rorder);
1385 fs.addSetting(setting);
1386 settingsAdded.addElement(featureType);
1390 // is groups actually supposed to be a map here ?
1391 Iterator<String> en = ap.getSeqPanel().seqCanvas
1392 .getFeatureRenderer().getFeatureGroups().iterator();
1393 Vector<String> groupsAdded = new Vector<String>();
1394 while (en.hasNext())
1396 String grp = en.next();
1397 if (groupsAdded.contains(grp))
1401 Group g = new Group();
1403 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1404 .getFeatureRenderer().checkGroupVisibility(grp, false))
1407 groupsAdded.addElement(grp);
1409 jms.setFeatureSettings(fs);
1412 if (av.hasHiddenColumns())
1414 if (av.getColumnSelection() == null
1415 || av.getColumnSelection().getHiddenColumns() == null)
1417 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1421 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1424 int[] region = av.getColumnSelection().getHiddenColumns()
1426 HiddenColumns hc = new HiddenColumns();
1427 hc.setStart(region[0]);
1428 hc.setEnd(region[1]);
1429 view.addHiddenColumns(hc);
1433 if (calcIdSet.size() > 0)
1435 for (String calcId : calcIdSet)
1437 if (calcId.trim().length() > 0)
1439 CalcIdParam cidp = createCalcIdParam(calcId, av);
1440 // Some calcIds have no parameters.
1443 view.addCalcIdParam(cidp);
1449 jms.addViewport(view);
1451 object.setJalviewModelSequence(jms);
1452 object.getVamsasModel().addSequenceSet(vamsasSet);
1454 if (jout != null && fileName != null)
1456 // We may not want to write the object to disk,
1457 // eg we can copy the alignViewport to a new view object
1458 // using save and then load
1461 System.out.println("Writing jar entry " + fileName);
1462 JarEntry entry = new JarEntry(fileName);
1463 jout.putNextEntry(entry);
1464 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1466 Marshaller marshaller = new Marshaller(pout);
1467 marshaller.marshal(object);
1470 } catch (Exception ex)
1472 // TODO: raise error in GUI if marshalling failed.
1473 ex.printStackTrace();
1480 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1481 * for each viewer, with
1483 * <li>viewer geometry (position, size, split pane divider location)</li>
1484 * <li>index of the selected structure in the viewer (currently shows gapped
1486 * <li>the id of the annotation holding RNA secondary structure</li>
1487 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1489 * Varna viewer state is also written out (in native Varna XML) to separate
1490 * project jar entries. A separate entry is written for each RNA structure
1491 * displayed, with the naming convention
1493 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1501 * @param storeDataset
1503 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1504 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1505 boolean storeDataset)
1507 if (Desktop.desktop == null)
1511 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1512 for (int f = frames.length - 1; f > -1; f--)
1514 if (frames[f] instanceof AppVarna)
1516 AppVarna varna = (AppVarna) frames[f];
1518 * link the sequence to every viewer that is showing it and is linked to
1519 * its alignment panel
1521 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1523 String viewId = varna.getViewId();
1524 RnaViewer rna = new RnaViewer();
1525 rna.setViewId(viewId);
1526 rna.setTitle(varna.getTitle());
1527 rna.setXpos(varna.getX());
1528 rna.setYpos(varna.getY());
1529 rna.setWidth(varna.getWidth());
1530 rna.setHeight(varna.getHeight());
1531 rna.setDividerLocation(varna.getDividerLocation());
1532 rna.setSelectedRna(varna.getSelectedIndex());
1533 jseq.addRnaViewer(rna);
1536 * Store each Varna panel's state once in the project per sequence.
1537 * First time through only (storeDataset==false)
1539 // boolean storeSessions = false;
1540 // String sequenceViewId = viewId + seqsToIds.get(jds);
1541 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1543 // viewIds.add(sequenceViewId);
1544 // storeSessions = true;
1546 for (RnaModel model : varna.getModels())
1548 if (model.seq == jds)
1551 * VARNA saves each view (sequence or alignment secondary
1552 * structure, gapped or trimmed) as a separate XML file
1554 String jarEntryName = rnaSessions.get(model);
1555 if (jarEntryName == null)
1558 String varnaStateFile = varna.getStateInfo(model.rna);
1559 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1560 copyFileToJar(jout, varnaStateFile, jarEntryName);
1561 rnaSessions.put(model, jarEntryName);
1563 SecondaryStructure ss = new SecondaryStructure();
1564 String annotationId = varna.getAnnotation(jds).annotationId;
1565 ss.setAnnotationId(annotationId);
1566 ss.setViewerState(jarEntryName);
1567 ss.setGapped(model.gapped);
1568 ss.setTitle(model.title);
1569 rna.addSecondaryStructure(ss);
1578 * Copy the contents of a file to a new entry added to the output jar
1582 * @param jarEntryName
1584 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1585 String jarEntryName)
1587 DataInputStream dis = null;
1590 File file = new File(infilePath);
1591 if (file.exists() && jout != null)
1593 dis = new DataInputStream(new FileInputStream(file));
1594 byte[] data = new byte[(int) file.length()];
1595 dis.readFully(data);
1596 writeJarEntry(jout, jarEntryName, data);
1598 } catch (Exception ex)
1600 ex.printStackTrace();
1608 } catch (IOException e)
1617 * Write the data to a new entry of given name in the output jar file
1620 * @param jarEntryName
1622 * @throws IOException
1624 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1625 byte[] data) throws IOException
1629 System.out.println("Writing jar entry " + jarEntryName);
1630 jout.putNextEntry(new JarEntry(jarEntryName));
1631 DataOutputStream dout = new DataOutputStream(jout);
1632 dout.write(data, 0, data.length);
1639 * Save the state of a structure viewer
1644 * the archive XML element under which to save the state
1647 * @param matchedFile
1651 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1652 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1653 String matchedFile, StructureViewerBase viewFrame)
1655 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1658 * Look for any bindings for this viewer to the PDB file of interest
1659 * (including part matches excluding chain id)
1661 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1663 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1664 final String pdbId = pdbentry.getId();
1665 if (!pdbId.equals(entry.getId())
1666 && !(entry.getId().length() > 4 && entry.getId()
1667 .toLowerCase().startsWith(pdbId.toLowerCase())))
1670 * not interested in a binding to a different PDB entry here
1674 if (matchedFile == null)
1676 matchedFile = pdbentry.getFile();
1678 else if (!matchedFile.equals(pdbentry.getFile()))
1681 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1682 + pdbentry.getFile());
1686 // can get at it if the ID
1687 // match is ambiguous (e.g.
1690 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1692 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1693 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1695 StructureState state = new StructureState();
1696 state.setVisible(true);
1697 state.setXpos(viewFrame.getX());
1698 state.setYpos(viewFrame.getY());
1699 state.setWidth(viewFrame.getWidth());
1700 state.setHeight(viewFrame.getHeight());
1701 final String viewId = viewFrame.getViewId();
1702 state.setViewId(viewId);
1703 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1704 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1705 state.setColourByJmol(viewFrame.isColouredByViewer());
1706 state.setType(viewFrame.getViewerType().toString());
1707 pdb.addStructureState(state);
1714 private AnnotationColours constructAnnotationColours(
1715 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1716 JalviewModelSequence jms)
1718 AnnotationColours ac = new AnnotationColours();
1719 ac.setAboveThreshold(acg.getAboveThreshold());
1720 ac.setThreshold(acg.getAnnotationThreshold());
1721 ac.setAnnotation(acg.getAnnotation());
1722 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1724 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1729 ac.setColourScheme(ColourSchemeProperty.getColourName(acg.getBaseColour()));
1732 ac.setMaxColour(acg.getMaxColour().getRGB());
1733 ac.setMinColour(acg.getMinColour().getRGB());
1734 ac.setPerSequence(acg.isSeqAssociated());
1735 ac.setPredefinedColours(acg.isPredefinedColours());
1739 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1740 IdentityHashMap<SequenceGroup, String> groupRefs,
1741 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1742 SequenceSet vamsasSet)
1745 for (int i = 0; i < aa.length; i++)
1747 Annotation an = new Annotation();
1749 AlignmentAnnotation annotation = aa[i];
1750 if (annotation.annotationId != null)
1752 annotationIds.put(annotation.annotationId, annotation);
1755 an.setId(annotation.annotationId);
1757 an.setVisible(annotation.visible);
1759 an.setDescription(annotation.description);
1761 if (annotation.sequenceRef != null)
1763 // 2.9 JAL-1781 xref on sequence id rather than name
1764 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1766 if (annotation.groupRef != null)
1768 String groupIdr = groupRefs.get(annotation.groupRef);
1769 if (groupIdr == null)
1771 // make a locally unique String
1773 annotation.groupRef,
1774 groupIdr = ("" + System.currentTimeMillis()
1775 + annotation.groupRef.getName() + groupRefs
1778 an.setGroupRef(groupIdr.toString());
1781 // store all visualization attributes for annotation
1782 an.setGraphHeight(annotation.graphHeight);
1783 an.setCentreColLabels(annotation.centreColLabels);
1784 an.setScaleColLabels(annotation.scaleColLabel);
1785 an.setShowAllColLabels(annotation.showAllColLabels);
1786 an.setBelowAlignment(annotation.belowAlignment);
1788 if (annotation.graph > 0)
1791 an.setGraphType(annotation.graph);
1792 an.setGraphGroup(annotation.graphGroup);
1793 if (annotation.getThreshold() != null)
1795 ThresholdLine line = new ThresholdLine();
1796 line.setLabel(annotation.getThreshold().label);
1797 line.setValue(annotation.getThreshold().value);
1798 line.setColour(annotation.getThreshold().colour.getRGB());
1799 an.setThresholdLine(line);
1807 an.setLabel(annotation.label);
1809 if (annotation == av.getAlignmentQualityAnnot()
1810 || annotation == av.getAlignmentConservationAnnotation()
1811 || annotation == av.getAlignmentConsensusAnnotation()
1812 || annotation.autoCalculated)
1814 // new way of indicating autocalculated annotation -
1815 an.setAutoCalculated(annotation.autoCalculated);
1817 if (annotation.hasScore())
1819 an.setScore(annotation.getScore());
1822 if (annotation.getCalcId() != null)
1824 calcIdSet.add(annotation.getCalcId());
1825 an.setCalcId(annotation.getCalcId());
1827 if (annotation.hasProperties())
1829 for (String pr : annotation.getProperties())
1831 Property prop = new Property();
1833 prop.setValue(annotation.getProperty(pr));
1834 an.addProperty(prop);
1838 AnnotationElement ae;
1839 if (annotation.annotations != null)
1841 an.setScoreOnly(false);
1842 for (int a = 0; a < annotation.annotations.length; a++)
1844 if ((annotation == null) || (annotation.annotations[a] == null))
1849 ae = new AnnotationElement();
1850 if (annotation.annotations[a].description != null)
1852 ae.setDescription(annotation.annotations[a].description);
1854 if (annotation.annotations[a].displayCharacter != null)
1856 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1859 if (!Float.isNaN(annotation.annotations[a].value))
1861 ae.setValue(annotation.annotations[a].value);
1865 if (annotation.annotations[a].secondaryStructure > ' ')
1867 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1871 if (annotation.annotations[a].colour != null
1872 && annotation.annotations[a].colour != java.awt.Color.black)
1874 ae.setColour(annotation.annotations[a].colour.getRGB());
1877 an.addAnnotationElement(ae);
1878 if (annotation.autoCalculated)
1880 // only write one non-null entry into the annotation row -
1881 // sufficient to get the visualization attributes necessary to
1889 an.setScoreOnly(true);
1891 if (!storeDS || (storeDS && !annotation.autoCalculated))
1893 // skip autocalculated annotation - these are only provided for
1895 vamsasSet.addAnnotation(an);
1901 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1903 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1904 if (settings != null)
1906 CalcIdParam vCalcIdParam = new CalcIdParam();
1907 vCalcIdParam.setCalcId(calcId);
1908 vCalcIdParam.addServiceURL(settings.getServiceURI());
1909 // generic URI allowing a third party to resolve another instance of the
1910 // service used for this calculation
1911 for (String urls : settings.getServiceURLs())
1913 vCalcIdParam.addServiceURL(urls);
1915 vCalcIdParam.setVersion("1.0");
1916 if (settings.getPreset() != null)
1918 WsParamSetI setting = settings.getPreset();
1919 vCalcIdParam.setName(setting.getName());
1920 vCalcIdParam.setDescription(setting.getDescription());
1924 vCalcIdParam.setName("");
1925 vCalcIdParam.setDescription("Last used parameters");
1927 // need to be able to recover 1) settings 2) user-defined presets or
1928 // recreate settings from preset 3) predefined settings provided by
1929 // service - or settings that can be transferred (or discarded)
1930 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1932 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1933 // todo - decide if updateImmediately is needed for any projects.
1935 return vCalcIdParam;
1940 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1943 if (calcIdParam.getVersion().equals("1.0"))
1945 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1946 .getPreferredServiceFor(calcIdParam.getServiceURL());
1947 if (service != null)
1949 WsParamSetI parmSet = null;
1952 parmSet = service.getParamStore().parseServiceParameterFile(
1953 calcIdParam.getName(), calcIdParam.getDescription(),
1954 calcIdParam.getServiceURL(),
1955 calcIdParam.getParameters().replace("|\\n|", "\n"));
1956 } catch (IOException x)
1958 warn("Couldn't parse parameter data for "
1959 + calcIdParam.getCalcId(), x);
1962 List<ArgumentI> argList = null;
1963 if (calcIdParam.getName().length() > 0)
1965 parmSet = service.getParamStore()
1966 .getPreset(calcIdParam.getName());
1967 if (parmSet != null)
1969 // TODO : check we have a good match with settings in AACon -
1970 // otherwise we'll need to create a new preset
1975 argList = parmSet.getArguments();
1978 AAConSettings settings = new AAConSettings(
1979 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1980 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1981 calcIdParam.isNeedsUpdate());
1986 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1990 throw new Error(MessageManager.formatMessage(
1991 "error.unsupported_version_calcIdparam",
1992 new Object[] { calcIdParam.toString() }));
1996 * External mapping between jalview objects and objects yielding a valid and
1997 * unique object ID string. This is null for normal Jalview project IO, but
1998 * non-null when a jalview project is being read or written as part of a
2001 IdentityHashMap jv2vobj = null;
2004 * Construct a unique ID for jvobj using either existing bindings or if none
2005 * exist, the result of the hashcode call for the object.
2008 * jalview data object
2009 * @return unique ID for referring to jvobj
2011 private String makeHashCode(Object jvobj, String altCode)
2013 if (jv2vobj != null)
2015 Object id = jv2vobj.get(jvobj);
2018 return id.toString();
2020 // check string ID mappings
2021 if (jvids2vobj != null && jvobj instanceof String)
2023 id = jvids2vobj.get(jvobj);
2027 return id.toString();
2029 // give up and warn that something has gone wrong
2030 warn("Cannot find ID for object in external mapping : " + jvobj);
2036 * return local jalview object mapped to ID, if it exists
2040 * @return null or object bound to idcode
2042 private Object retrieveExistingObj(String idcode)
2044 if (idcode != null && vobj2jv != null)
2046 return vobj2jv.get(idcode);
2052 * binding from ID strings from external mapping table to jalview data model
2055 private Hashtable vobj2jv;
2057 private Sequence createVamsasSequence(String id, SequenceI jds)
2059 return createVamsasSequence(true, id, jds, null);
2062 private Sequence createVamsasSequence(boolean recurse, String id,
2063 SequenceI jds, SequenceI parentseq)
2065 Sequence vamsasSeq = new Sequence();
2066 vamsasSeq.setId(id);
2067 vamsasSeq.setName(jds.getName());
2068 vamsasSeq.setSequence(jds.getSequenceAsString());
2069 vamsasSeq.setDescription(jds.getDescription());
2070 jalview.datamodel.DBRefEntry[] dbrefs = null;
2071 if (jds.getDatasetSequence() != null)
2073 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2077 // seqId==dsseqid so we can tell which sequences really are
2078 // dataset sequences only
2079 vamsasSeq.setDsseqid(id);
2080 dbrefs = jds.getDBRefs();
2081 if (parentseq == null)
2088 for (int d = 0; d < dbrefs.length; d++)
2090 DBRef dbref = new DBRef();
2091 dbref.setSource(dbrefs[d].getSource());
2092 dbref.setVersion(dbrefs[d].getVersion());
2093 dbref.setAccessionId(dbrefs[d].getAccessionId());
2094 if (dbrefs[d].hasMap())
2096 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2098 dbref.setMapping(mp);
2100 vamsasSeq.addDBRef(dbref);
2106 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2107 SequenceI parentseq, SequenceI jds, boolean recurse)
2110 if (jmp.getMap() != null)
2114 jalview.util.MapList mlst = jmp.getMap();
2115 List<int[]> r = mlst.getFromRanges();
2116 for (int[] range : r)
2118 MapListFrom mfrom = new MapListFrom();
2119 mfrom.setStart(range[0]);
2120 mfrom.setEnd(range[1]);
2121 mp.addMapListFrom(mfrom);
2123 r = mlst.getToRanges();
2124 for (int[] range : r)
2126 MapListTo mto = new MapListTo();
2127 mto.setStart(range[0]);
2128 mto.setEnd(range[1]);
2129 mp.addMapListTo(mto);
2131 mp.setMapFromUnit(mlst.getFromRatio());
2132 mp.setMapToUnit(mlst.getToRatio());
2133 if (jmp.getTo() != null)
2135 MappingChoice mpc = new MappingChoice();
2137 // check/create ID for the sequence referenced by getTo()
2140 SequenceI ps = null;
2141 if (parentseq != jmp.getTo()
2142 && parentseq.getDatasetSequence() != jmp.getTo())
2144 // chaining dbref rather than a handshaking one
2145 jmpid = seqHash(ps = jmp.getTo());
2149 jmpid = seqHash(ps = parentseq);
2151 mpc.setDseqFor(jmpid);
2152 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2154 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2155 seqRefIds.put(mpc.getDseqFor(), ps);
2159 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2162 mp.setMappingChoice(mpc);
2168 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2169 List<UserColourScheme> userColours, JalviewModelSequence jms)
2172 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2173 boolean newucs = false;
2174 if (!userColours.contains(ucs))
2176 userColours.add(ucs);
2179 id = "ucs" + userColours.indexOf(ucs);
2182 // actually create the scheme's entry in the XML model
2183 java.awt.Color[] colours = ucs.getColours();
2184 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2185 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2187 for (int i = 0; i < colours.length; i++)
2189 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2190 col.setName(ResidueProperties.aa[i]);
2191 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2192 jbucs.addColour(col);
2194 if (ucs.getLowerCaseColours() != null)
2196 colours = ucs.getLowerCaseColours();
2197 for (int i = 0; i < colours.length; i++)
2199 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2200 col.setName(ResidueProperties.aa[i].toLowerCase());
2201 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2202 jbucs.addColour(col);
2207 uc.setUserColourScheme(jbucs);
2208 jms.addUserColours(uc);
2214 jalview.schemes.UserColourScheme getUserColourScheme(
2215 JalviewModelSequence jms, String id)
2217 UserColours[] uc = jms.getUserColours();
2218 UserColours colours = null;
2220 for (int i = 0; i < uc.length; i++)
2222 if (uc[i].getId().equals(id))
2230 java.awt.Color[] newColours = new java.awt.Color[24];
2232 for (int i = 0; i < 24; i++)
2234 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2235 .getUserColourScheme().getColour(i).getRGB(), 16));
2238 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2241 if (colours.getUserColourScheme().getColourCount() > 24)
2243 newColours = new java.awt.Color[23];
2244 for (int i = 0; i < 23; i++)
2246 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2247 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2249 ucs.setLowerCaseColours(newColours);
2256 * contains last error message (if any) encountered by XML loader.
2258 String errorMessage = null;
2261 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2262 * exceptions are raised during project XML parsing
2264 public boolean attemptversion1parse = true;
2267 * Load a jalview project archive from a jar file
2270 * - HTTP URL or filename
2272 public AlignFrame loadJalviewAlign(final String file)
2275 jalview.gui.AlignFrame af = null;
2279 // create list to store references for any new Jmol viewers created
2280 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2281 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2282 // Workaround is to make sure caller implements the JarInputStreamProvider
2284 // so we can re-open the jar input stream for each entry.
2286 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2287 af = loadJalviewAlign(jprovider);
2289 } catch (MalformedURLException e)
2291 errorMessage = "Invalid URL format for '" + file + "'";
2297 SwingUtilities.invokeAndWait(new Runnable()
2302 setLoadingFinishedForNewStructureViewers();
2305 } catch (Exception x)
2307 System.err.println("Error loading alignment: " + x.getMessage());
2313 private jarInputStreamProvider createjarInputStreamProvider(
2314 final String file) throws MalformedURLException
2317 errorMessage = null;
2318 uniqueSetSuffix = null;
2320 viewportsAdded.clear();
2321 frefedSequence = null;
2323 if (file.startsWith("http://"))
2325 url = new URL(file);
2327 final URL _url = url;
2328 return new jarInputStreamProvider()
2332 public JarInputStream getJarInputStream() throws IOException
2336 return new JarInputStream(_url.openStream());
2340 return new JarInputStream(new FileInputStream(file));
2345 public String getFilename()
2353 * Recover jalview session from a jalview project archive. Caller may
2354 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2355 * themselves. Any null fields will be initialised with default values,
2356 * non-null fields are left alone.
2361 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2363 errorMessage = null;
2364 if (uniqueSetSuffix == null)
2366 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2368 if (seqRefIds == null)
2372 AlignFrame af = null, _af = null;
2373 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2374 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2375 final String file = jprovider.getFilename();
2378 JarInputStream jin = null;
2379 JarEntry jarentry = null;
2384 jin = jprovider.getJarInputStream();
2385 for (int i = 0; i < entryCount; i++)
2387 jarentry = jin.getNextJarEntry();
2390 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2392 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2393 JalviewModel object = new JalviewModel();
2395 Unmarshaller unmar = new Unmarshaller(object);
2396 unmar.setValidation(false);
2397 object = (JalviewModel) unmar.unmarshal(in);
2398 if (true) // !skipViewport(object))
2400 _af = loadFromObject(object, file, true, jprovider);
2402 && object.getJalviewModelSequence().getViewportCount() > 0)
2406 // store a reference to the first view
2409 if (_af.viewport.isGatherViewsHere())
2411 // if this is a gathered view, keep its reference since
2412 // after gathering views, only this frame will remain
2414 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2416 // Save dataset to register mappings once all resolved
2417 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2418 af.viewport.getAlignment().getDataset());
2423 else if (jarentry != null)
2425 // Some other file here.
2428 } while (jarentry != null);
2429 resolveFrefedSequences();
2430 } catch (IOException ex)
2432 ex.printStackTrace();
2433 errorMessage = "Couldn't locate Jalview XML file : " + file;
2434 System.err.println("Exception whilst loading jalview XML file : "
2436 } catch (Exception ex)
2438 System.err.println("Parsing as Jalview Version 2 file failed.");
2439 ex.printStackTrace(System.err);
2440 if (attemptversion1parse)
2442 // Is Version 1 Jar file?
2445 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2446 } catch (Exception ex2)
2448 System.err.println("Exception whilst loading as jalviewXMLV1:");
2449 ex2.printStackTrace();
2453 if (Desktop.instance != null)
2455 Desktop.instance.stopLoading();
2459 System.out.println("Successfully loaded archive file");
2462 ex.printStackTrace();
2464 System.err.println("Exception whilst loading jalview XML file : "
2466 } catch (OutOfMemoryError e)
2468 // Don't use the OOM Window here
2469 errorMessage = "Out of memory loading jalview XML file";
2470 System.err.println("Out of memory whilst loading jalview XML file");
2471 e.printStackTrace();
2475 * Regather multiple views (with the same sequence set id) to the frame (if
2476 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2477 * views instead of separate frames. Note this doesn't restore a state where
2478 * some expanded views in turn have tabbed views - the last "first tab" read
2479 * in will play the role of gatherer for all.
2481 for (AlignFrame fr : gatherToThisFrame.values())
2483 Desktop.instance.gatherViews(fr);
2486 restoreSplitFrames();
2487 for (AlignmentI ds : importedDatasets.keySet())
2489 if (ds.getCodonFrames() != null)
2491 StructureSelectionManager.getStructureSelectionManager(
2492 Desktop.instance).registerMappings(ds.getCodonFrames());
2495 if (errorMessage != null)
2500 if (Desktop.instance != null)
2502 Desktop.instance.stopLoading();
2509 * Try to reconstruct and display SplitFrame windows, where each contains
2510 * complementary dna and protein alignments. Done by pairing up AlignFrame
2511 * objects (created earlier) which have complementary viewport ids associated.
2513 protected void restoreSplitFrames()
2515 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2516 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2517 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2520 * Identify the DNA alignments
2522 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2525 AlignFrame af = candidate.getValue();
2526 if (af.getViewport().getAlignment().isNucleotide())
2528 dna.put(candidate.getKey().getId(), af);
2533 * Try to match up the protein complements
2535 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2538 AlignFrame af = candidate.getValue();
2539 if (!af.getViewport().getAlignment().isNucleotide())
2541 String complementId = candidate.getKey().getComplementId();
2542 // only non-null complements should be in the Map
2543 if (complementId != null && dna.containsKey(complementId))
2545 final AlignFrame dnaFrame = dna.get(complementId);
2546 SplitFrame sf = createSplitFrame(dnaFrame, af);
2547 addedToSplitFrames.add(dnaFrame);
2548 addedToSplitFrames.add(af);
2549 dnaFrame.setMenusForViewport();
2550 af.setMenusForViewport();
2551 if (af.viewport.isGatherViewsHere())
2560 * Open any that we failed to pair up (which shouldn't happen!) as
2561 * standalone AlignFrame's.
2563 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2566 AlignFrame af = candidate.getValue();
2567 if (!addedToSplitFrames.contains(af))
2569 Viewport view = candidate.getKey();
2570 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2572 af.setMenusForViewport();
2573 System.err.println("Failed to restore view " + view.getTitle()
2574 + " to split frame");
2579 * Gather back into tabbed views as flagged.
2581 for (SplitFrame sf : gatherTo)
2583 Desktop.instance.gatherViews(sf);
2586 splitFrameCandidates.clear();
2590 * Construct and display one SplitFrame holding DNA and protein alignments.
2593 * @param proteinFrame
2596 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2597 AlignFrame proteinFrame)
2599 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2600 String title = MessageManager.getString("label.linked_view_title");
2601 int width = (int) dnaFrame.getBounds().getWidth();
2602 int height = (int) (dnaFrame.getBounds().getHeight()
2603 + proteinFrame.getBounds().getHeight() + 50);
2606 * SplitFrame location is saved to both enclosed frames
2608 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2609 Desktop.addInternalFrame(splitFrame, title, width, height);
2612 * And compute cDNA consensus (couldn't do earlier with consensus as
2613 * mappings were not yet present)
2615 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2621 * check errorMessage for a valid error message and raise an error box in the
2622 * GUI or write the current errorMessage to stderr and then clear the error
2625 protected void reportErrors()
2627 reportErrors(false);
2630 protected void reportErrors(final boolean saving)
2632 if (errorMessage != null)
2634 final String finalErrorMessage = errorMessage;
2637 javax.swing.SwingUtilities.invokeLater(new Runnable()
2642 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2643 finalErrorMessage, "Error "
2644 + (saving ? "saving" : "loading")
2645 + " Jalview file", JvOptionPane.WARNING_MESSAGE);
2651 System.err.println("Problem loading Jalview file: " + errorMessage);
2654 errorMessage = null;
2657 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2660 * when set, local views will be updated from view stored in JalviewXML
2661 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2662 * sync if this is set to true.
2664 private final boolean updateLocalViews = false;
2667 * Returns the path to a temporary file holding the PDB file for the given PDB
2668 * id. The first time of asking, searches for a file of that name in the
2669 * Jalview project jar, and copies it to a new temporary file. Any repeat
2670 * requests just return the path to the file previously created.
2676 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2679 if (alreadyLoadedPDB.containsKey(pdbId))
2681 return alreadyLoadedPDB.get(pdbId).toString();
2684 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2686 if (tempFile != null)
2688 alreadyLoadedPDB.put(pdbId, tempFile);
2694 * Copies the jar entry of given name to a new temporary file and returns the
2695 * path to the file, or null if the entry is not found.
2698 * @param jarEntryName
2700 * a prefix for the temporary file name, must be at least three
2703 * null or original file - so new file can be given the same suffix
2707 protected String copyJarEntry(jarInputStreamProvider jprovider,
2708 String jarEntryName, String prefix, String origFile)
2710 BufferedReader in = null;
2711 PrintWriter out = null;
2712 String suffix = ".tmp";
2713 if (origFile == null)
2715 origFile = jarEntryName;
2717 int sfpos = origFile.lastIndexOf(".");
2718 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2720 suffix = "." + origFile.substring(sfpos + 1);
2724 JarInputStream jin = jprovider.getJarInputStream();
2726 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2727 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2728 * FileInputStream(jprovider)); }
2731 JarEntry entry = null;
2734 entry = jin.getNextJarEntry();
2735 } while (entry != null && !entry.getName().equals(jarEntryName));
2738 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2739 File outFile = File.createTempFile(prefix, suffix);
2740 outFile.deleteOnExit();
2741 out = new PrintWriter(new FileOutputStream(outFile));
2744 while ((data = in.readLine()) != null)
2749 String t = outFile.getAbsolutePath();
2754 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2756 } catch (Exception ex)
2758 ex.printStackTrace();
2766 } catch (IOException e)
2780 private class JvAnnotRow
2782 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2789 * persisted version of annotation row from which to take vis properties
2791 public jalview.datamodel.AlignmentAnnotation template;
2794 * original position of the annotation row in the alignment
2800 * Load alignment frame from jalview XML DOM object
2805 * filename source string
2806 * @param loadTreesAndStructures
2807 * when false only create Viewport
2809 * data source provider
2810 * @return alignment frame created from view stored in DOM
2812 AlignFrame loadFromObject(JalviewModel object, String file,
2813 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2815 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2816 Sequence[] vamsasSeq = vamsasSet.getSequence();
2818 JalviewModelSequence jms = object.getJalviewModelSequence();
2820 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2823 // ////////////////////////////////
2826 List<SequenceI> hiddenSeqs = null;
2828 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2830 boolean multipleView = false;
2831 SequenceI referenceseqForView = null;
2832 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2833 int vi = 0; // counter in vamsasSeq array
2834 for (int i = 0; i < jseqs.length; i++)
2836 String seqId = jseqs[i].getId();
2838 SequenceI tmpSeq = seqRefIds.get(seqId);
2841 if (!incompleteSeqs.containsKey(seqId))
2843 // may not need this check, but keep it for at least 2.9,1 release
2844 if (tmpSeq.getStart() != jseqs[i].getStart()
2845 || tmpSeq.getEnd() != jseqs[i].getEnd())
2848 .println("Warning JAL-2154 regression: updating start/end for sequence "
2849 + tmpSeq.toString() + " to " + jseqs[i]);
2854 incompleteSeqs.remove(seqId);
2856 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2858 // most likely we are reading a dataset XML document so
2859 // update from vamsasSeq section of XML for this sequence
2860 tmpSeq.setName(vamsasSeq[vi].getName());
2861 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2862 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2867 // reading multiple views, so vamsasSeq set is a subset of JSeq
2868 multipleView = true;
2870 tmpSeq.setStart(jseqs[i].getStart());
2871 tmpSeq.setEnd(jseqs[i].getEnd());
2872 tmpseqs.add(tmpSeq);
2876 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2877 vamsasSeq[vi].getSequence());
2878 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2879 tmpSeq.setStart(jseqs[i].getStart());
2880 tmpSeq.setEnd(jseqs[i].getEnd());
2881 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2882 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2883 tmpseqs.add(tmpSeq);
2887 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2889 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2892 if (jseqs[i].getHidden())
2894 if (hiddenSeqs == null)
2896 hiddenSeqs = new ArrayList<SequenceI>();
2899 hiddenSeqs.add(tmpSeq);
2904 // Create the alignment object from the sequence set
2905 // ///////////////////////////////
2906 SequenceI[] orderedSeqs = tmpseqs
2907 .toArray(new SequenceI[tmpseqs.size()]);
2909 AlignmentI al = null;
2910 // so we must create or recover the dataset alignment before going further
2911 // ///////////////////////////////
2912 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2914 // older jalview projects do not have a dataset - so creat alignment and
2916 al = new Alignment(orderedSeqs);
2917 al.setDataset(null);
2921 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2924 // we are importing a dataset record, so
2925 // recover reference to an alignment already materialsed as dataset
2926 al = getDatasetFor(vamsasSet.getDatasetId());
2930 // materialse the alignment
2931 al = new Alignment(orderedSeqs);
2935 addDatasetRef(vamsasSet.getDatasetId(), al);
2938 // finally, verify all data in vamsasSet is actually present in al
2939 // passing on flag indicating if it is actually a stored dataset
2940 recoverDatasetFor(vamsasSet, al, isdsal);
2943 if (referenceseqForView != null)
2945 al.setSeqrep(referenceseqForView);
2947 // / Add the alignment properties
2948 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2950 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2951 al.setProperty(ssp.getKey(), ssp.getValue());
2954 // ///////////////////////////////
2956 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2959 // load sequence features, database references and any associated PDB
2960 // structures for the alignment
2962 // prior to 2.10, this part would only be executed the first time a
2963 // sequence was encountered, but not afterwards.
2964 // now, for 2.10 projects, this is also done if the xml doc includes
2965 // dataset sequences not actually present in any particular view.
2967 for (int i = 0; i < vamsasSeq.length; i++)
2969 if (jseqs[i].getFeaturesCount() > 0)
2971 Features[] features = jseqs[i].getFeatures();
2972 for (int f = 0; f < features.length; f++)
2974 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2975 features[f].getType(), features[f].getDescription(),
2976 features[f].getStatus(), features[f].getBegin(),
2977 features[f].getEnd(), features[f].getFeatureGroup());
2979 sf.setScore(features[f].getScore());
2980 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2982 OtherData keyValue = features[f].getOtherData(od);
2983 if (keyValue.getKey().startsWith("LINK"))
2985 sf.addLink(keyValue.getValue());
2989 sf.setValue(keyValue.getKey(), keyValue.getValue());
2993 // adds feature to datasequence's feature set (since Jalview 2.10)
2994 al.getSequenceAt(i).addSequenceFeature(sf);
2997 if (vamsasSeq[i].getDBRefCount() > 0)
2999 // adds dbrefs to datasequence's set (since Jalview 2.10)
3001 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
3002 : al.getSequenceAt(i).getDatasetSequence(),
3005 if (jseqs[i].getPdbidsCount() > 0)
3007 Pdbids[] ids = jseqs[i].getPdbids();
3008 for (int p = 0; p < ids.length; p++)
3010 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
3011 entry.setId(ids[p].getId());
3012 if (ids[p].getType() != null)
3014 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3016 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3020 entry.setType(PDBEntry.Type.FILE);
3023 // jprovider is null when executing 'New View'
3024 if (ids[p].getFile() != null && jprovider != null)
3026 if (!pdbloaded.containsKey(ids[p].getFile()))
3028 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3033 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3036 if (ids[p].getPdbentryItem() != null)
3038 for (PdbentryItem item : ids[p].getPdbentryItem())
3040 for (Property pr : item.getProperty())
3042 entry.setProperty(pr.getName(), pr.getValue());
3046 StructureSelectionManager.getStructureSelectionManager(
3047 Desktop.instance).registerPDBEntry(entry);
3048 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3049 if (al.getSequenceAt(i).getDatasetSequence() != null)
3051 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3055 al.getSequenceAt(i).addPDBId(entry);
3060 } // end !multipleview
3062 // ///////////////////////////////
3063 // LOAD SEQUENCE MAPPINGS
3065 if (vamsasSet.getAlcodonFrameCount() > 0)
3067 // TODO Potentially this should only be done once for all views of an
3069 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3070 for (int i = 0; i < alc.length; i++)
3072 AlignedCodonFrame cf = new AlignedCodonFrame();
3073 if (alc[i].getAlcodMapCount() > 0)
3075 AlcodMap[] maps = alc[i].getAlcodMap();
3076 for (int m = 0; m < maps.length; m++)
3078 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3080 jalview.datamodel.Mapping mapping = null;
3081 // attach to dna sequence reference.
3082 if (maps[m].getMapping() != null)
3084 mapping = addMapping(maps[m].getMapping());
3085 if (dnaseq != null && mapping.getTo() != null)
3087 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3092 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3097 al.addCodonFrame(cf);
3102 // ////////////////////////////////
3104 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3107 * store any annotations which forward reference a group's ID
3109 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3111 if (vamsasSet.getAnnotationCount() > 0)
3113 Annotation[] an = vamsasSet.getAnnotation();
3115 for (int i = 0; i < an.length; i++)
3117 Annotation annotation = an[i];
3120 * test if annotation is automatically calculated for this view only
3122 boolean autoForView = false;
3123 if (annotation.getLabel().equals("Quality")
3124 || annotation.getLabel().equals("Conservation")
3125 || annotation.getLabel().equals("Consensus"))
3127 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3129 if (!annotation.hasAutoCalculated())
3131 annotation.setAutoCalculated(true);
3135 || (annotation.hasAutoCalculated() && annotation
3136 .isAutoCalculated()))
3138 // remove ID - we don't recover annotation from other views for
3139 // view-specific annotation
3140 annotation.setId(null);
3143 // set visiblity for other annotation in this view
3144 String annotationId = annotation.getId();
3145 if (annotationId != null && annotationIds.containsKey(annotationId))
3147 AlignmentAnnotation jda = annotationIds.get(annotationId);
3148 // in principle Visible should always be true for annotation displayed
3149 // in multiple views
3150 if (annotation.hasVisible())
3152 jda.visible = annotation.getVisible();
3155 al.addAnnotation(jda);
3159 // Construct new annotation from model.
3160 AnnotationElement[] ae = annotation.getAnnotationElement();
3161 jalview.datamodel.Annotation[] anot = null;
3162 java.awt.Color firstColour = null;
3164 if (!annotation.getScoreOnly())
3166 anot = new jalview.datamodel.Annotation[al.getWidth()];
3167 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3169 anpos = ae[aa].getPosition();
3171 if (anpos >= anot.length)
3176 anot[anpos] = new jalview.datamodel.Annotation(
3178 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3179 (ae[aa].getSecondaryStructure() == null || ae[aa]
3180 .getSecondaryStructure().length() == 0) ? ' '
3181 : ae[aa].getSecondaryStructure().charAt(0),
3185 // JBPNote: Consider verifying dataflow for IO of secondary
3186 // structure annotation read from Stockholm files
3187 // this was added to try to ensure that
3188 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3190 // anot[ae[aa].getPosition()].displayCharacter = "";
3192 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3193 if (firstColour == null)
3195 firstColour = anot[anpos].colour;
3199 jalview.datamodel.AlignmentAnnotation jaa = null;
3201 if (annotation.getGraph())
3203 float llim = 0, hlim = 0;
3204 // if (autoForView || an[i].isAutoCalculated()) {
3207 jaa = new jalview.datamodel.AlignmentAnnotation(
3208 annotation.getLabel(), annotation.getDescription(), anot,
3209 llim, hlim, annotation.getGraphType());
3211 jaa.graphGroup = annotation.getGraphGroup();
3212 jaa._linecolour = firstColour;
3213 if (annotation.getThresholdLine() != null)
3215 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3216 .getThresholdLine().getValue(), annotation
3217 .getThresholdLine().getLabel(), new java.awt.Color(
3218 annotation.getThresholdLine().getColour())));
3221 if (autoForView || annotation.isAutoCalculated())
3223 // Hardwire the symbol display line to ensure that labels for
3224 // histograms are displayed
3230 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3231 an[i].getDescription(), anot);
3232 jaa._linecolour = firstColour;
3234 // register new annotation
3235 if (an[i].getId() != null)
3237 annotationIds.put(an[i].getId(), jaa);
3238 jaa.annotationId = an[i].getId();
3240 // recover sequence association
3241 String sequenceRef = an[i].getSequenceRef();
3242 if (sequenceRef != null)
3244 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3245 SequenceI sequence = seqRefIds.get(sequenceRef);
3246 if (sequence == null)
3248 // in pre-2.9 projects sequence ref is to sequence name
3249 sequence = al.findName(sequenceRef);
3251 if (sequence != null)
3253 jaa.createSequenceMapping(sequence, 1, true);
3254 sequence.addAlignmentAnnotation(jaa);
3257 // and make a note of any group association
3258 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3260 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3261 .get(an[i].getGroupRef());
3264 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3265 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3270 if (an[i].hasScore())
3272 jaa.setScore(an[i].getScore());
3274 if (an[i].hasVisible())
3276 jaa.visible = an[i].getVisible();
3279 if (an[i].hasCentreColLabels())
3281 jaa.centreColLabels = an[i].getCentreColLabels();
3284 if (an[i].hasScaleColLabels())
3286 jaa.scaleColLabel = an[i].getScaleColLabels();
3288 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3290 // newer files have an 'autoCalculated' flag and store calculation
3291 // state in viewport properties
3292 jaa.autoCalculated = true; // means annotation will be marked for
3293 // update at end of load.
3295 if (an[i].hasGraphHeight())
3297 jaa.graphHeight = an[i].getGraphHeight();
3299 if (an[i].hasBelowAlignment())
3301 jaa.belowAlignment = an[i].isBelowAlignment();
3303 jaa.setCalcId(an[i].getCalcId());
3304 if (an[i].getPropertyCount() > 0)
3306 for (jalview.schemabinding.version2.Property prop : an[i]
3309 jaa.setProperty(prop.getName(), prop.getValue());
3312 if (jaa.autoCalculated)
3314 autoAlan.add(new JvAnnotRow(i, jaa));
3317 // if (!autoForView)
3319 // add autocalculated group annotation and any user created annotation
3321 al.addAnnotation(jaa);
3325 // ///////////////////////
3327 // Create alignment markup and styles for this view
3328 if (jms.getJGroupCount() > 0)
3330 JGroup[] groups = jms.getJGroup();
3331 boolean addAnnotSchemeGroup = false;
3332 for (int i = 0; i < groups.length; i++)
3334 JGroup jGroup = groups[i];
3335 ColourSchemeI cs = null;
3336 if (jGroup.getColour() != null)
3338 if (jGroup.getColour().startsWith("ucs"))
3340 cs = getUserColourScheme(jms, jGroup.getColour());
3342 else if (jGroup.getColour().equals("AnnotationColourGradient")
3343 && jGroup.getAnnotationColours() != null)
3345 addAnnotSchemeGroup = true;
3349 cs = ColourSchemeProperty.getColourScheme(al, jGroup.getColour());
3352 int pidThreshold = jGroup.getPidThreshold();
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());
3375 sg.getGroupColourScheme().setThreshold(pidThreshold, true);
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", sg.getSequences(null),
3403 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.setColourScheme(constructAnnotationColour(
3442 jGroup.getAnnotationColours(), 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, DataSourceType.FILE);
4232 binding.addSequenceForStructFile(pdbFile, seq);
4234 // and add the AlignmentPanel's reference to the view panel
4235 viewer.addAlignmentPanel(ap);
4236 if (useinViewerSuperpos)
4238 viewer.useAlignmentPanelForSuperposition(ap);
4242 viewer.excludeAlignmentPanelForSuperposition(ap);
4244 if (usetoColourbyseq)
4246 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4250 viewer.excludeAlignmentPanelForColourbyseq(ap);
4255 * Get all frames within the Desktop.
4259 protected JInternalFrame[] getAllFrames()
4261 JInternalFrame[] frames = null;
4262 // TODO is this necessary - is it safe - risk of hanging?
4267 frames = Desktop.desktop.getAllFrames();
4268 } catch (ArrayIndexOutOfBoundsException e)
4270 // occasional No such child exceptions are thrown here...
4274 } catch (InterruptedException f)
4278 } while (frames == null);
4283 * Answers true if 'version' is equal to or later than 'supported', where each
4284 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4285 * changes. Development and test values for 'version' are leniently treated
4289 * - minimum version we are comparing against
4291 * - version of data being processsed
4294 public static boolean isVersionStringLaterThan(String supported,
4297 if (supported == null || version == null
4298 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4299 || version.equalsIgnoreCase("Test")
4300 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4302 System.err.println("Assuming project file with "
4303 + (version == null ? "null" : version)
4304 + " is compatible with Jalview version " + supported);
4309 return StringUtils.compareVersions(version, supported, "b") >= 0;
4313 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4315 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4317 if (newStructureViewers != null)
4319 sview.getBinding().setFinishedLoadingFromArchive(false);
4320 newStructureViewers.add(sview);
4324 protected void setLoadingFinishedForNewStructureViewers()
4326 if (newStructureViewers != null)
4328 for (JalviewStructureDisplayI sview : newStructureViewers)
4330 sview.getBinding().setFinishedLoadingFromArchive(true);
4332 newStructureViewers.clear();
4333 newStructureViewers = null;
4337 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4338 List<SequenceI> hiddenSeqs, AlignmentI al,
4339 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4340 String viewId, List<JvAnnotRow> autoAlan)
4342 AlignFrame af = null;
4343 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4344 uniqueSeqSetId, viewId);
4346 af.setFileName(file, FileFormat.Jalview);
4348 for (int i = 0; i < JSEQ.length; i++)
4350 af.viewport.setSequenceColour(af.viewport.getAlignment()
4351 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4356 af.getViewport().setColourByReferenceSeq(true);
4357 af.getViewport().setDisplayReferenceSeq(true);
4360 af.viewport.setGatherViewsHere(view.getGatheredViews());
4362 if (view.getSequenceSetId() != null)
4364 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4366 af.viewport.setSequenceSetId(uniqueSeqSetId);
4369 // propagate shared settings to this new view
4370 af.viewport.setHistoryList(av.getHistoryList());
4371 af.viewport.setRedoList(av.getRedoList());
4375 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4377 // TODO: check if this method can be called repeatedly without
4378 // side-effects if alignpanel already registered.
4379 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4381 // apply Hidden regions to view.
4382 if (hiddenSeqs != null)
4384 for (int s = 0; s < JSEQ.length; s++)
4386 SequenceGroup hidden = new SequenceGroup();
4387 boolean isRepresentative = false;
4388 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4390 isRepresentative = true;
4391 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4392 .getHiddenSequences(r));
4393 hidden.addSequence(sequenceToHide, false);
4394 // remove from hiddenSeqs list so we don't try to hide it twice
4395 hiddenSeqs.remove(sequenceToHide);
4397 if (isRepresentative)
4399 SequenceI representativeSequence = al.getSequenceAt(s);
4400 hidden.addSequence(representativeSequence, false);
4401 af.viewport.hideRepSequences(representativeSequence, hidden);
4405 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4407 af.viewport.hideSequence(hseqs);
4410 // recover view properties and display parameters
4411 if (view.getViewName() != null)
4413 af.viewport.viewName = view.getViewName();
4414 af.setInitialTabVisible();
4416 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4419 af.viewport.setShowAnnotation(view.getShowAnnotation());
4420 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4422 af.viewport.setColourText(view.getShowColourText());
4424 af.viewport.setConservationSelected(view.getConservationSelected());
4425 af.viewport.setShowJVSuffix(view.getShowFullId());
4426 af.viewport.setRightAlignIds(view.getRightAlignIds());
4427 af.viewport.setFont(
4428 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4429 .getFontSize()), true);
4430 ViewStyleI vs = af.viewport.getViewStyle();
4431 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4432 af.viewport.setViewStyle(vs);
4433 // TODO: allow custom charWidth/Heights to be restored by updating them
4434 // after setting font - which means set above to false
4435 af.viewport.setRenderGaps(view.getRenderGaps());
4436 af.viewport.setWrapAlignment(view.getWrapAlignment());
4437 af.viewport.setShowAnnotation(view.getShowAnnotation());
4439 af.viewport.setShowBoxes(view.getShowBoxes());
4441 af.viewport.setShowText(view.getShowText());
4443 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4444 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4445 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4446 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4447 .isShowUnconserved() : false);
4448 af.viewport.setStartRes(view.getStartRes());
4449 af.viewport.setStartSeq(view.getStartSeq());
4450 af.alignPanel.updateLayout();
4451 ColourSchemeI cs = null;
4452 // apply colourschemes
4453 if (view.getBgColour() != null)
4455 if (view.getBgColour().startsWith("ucs"))
4457 cs = getUserColourScheme(jms, view.getBgColour());
4459 else if (view.getBgColour().startsWith("Annotation"))
4461 AnnotationColours viewAnnColour = view.getAnnotationColours();
4462 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4469 cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour());
4474 // cs.setThreshold(view.getPidThreshold(), true);
4475 // cs.setConsensus(af.viewport.getSequenceConsensusHash());
4479 af.viewport.setGlobalColourScheme(cs);
4480 af.viewport.getViewportColourScheme().setThreshold(
4481 view.getPidThreshold(), true);
4482 af.viewport.getViewportColourScheme().setConsensus(
4483 af.viewport.getSequenceConsensusHash());
4484 af.viewport.setColourAppliesToAllGroups(false);
4486 if (view.getConservationSelected() && cs != null)
4488 af.viewport.getViewportColourScheme().setConservationInc(
4489 view.getConsThreshold());
4492 af.changeColour(cs);
4494 af.viewport.setColourAppliesToAllGroups(true);
4496 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4498 if (view.hasCentreColumnLabels())
4500 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4502 if (view.hasIgnoreGapsinConsensus())
4504 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4507 if (view.hasFollowHighlight())
4509 af.viewport.setFollowHighlight(view.getFollowHighlight());
4511 if (view.hasFollowSelection())
4513 af.viewport.followSelection = view.getFollowSelection();
4515 if (view.hasShowConsensusHistogram())
4517 af.viewport.setShowConsensusHistogram(view
4518 .getShowConsensusHistogram());
4522 af.viewport.setShowConsensusHistogram(true);
4524 if (view.hasShowSequenceLogo())
4526 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4530 af.viewport.setShowSequenceLogo(false);
4532 if (view.hasNormaliseSequenceLogo())
4534 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4536 if (view.hasShowDbRefTooltip())
4538 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4540 if (view.hasShowNPfeatureTooltip())
4542 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4544 if (view.hasShowGroupConsensus())
4546 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4550 af.viewport.setShowGroupConsensus(false);
4552 if (view.hasShowGroupConservation())
4554 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4558 af.viewport.setShowGroupConservation(false);
4561 // recover featre settings
4562 if (jms.getFeatureSettings() != null)
4564 FeaturesDisplayed fdi;
4565 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4566 String[] renderOrder = new String[jms.getFeatureSettings()
4567 .getSettingCount()];
4568 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4569 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4571 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4573 Setting setting = jms.getFeatureSettings().getSetting(fs);
4574 if (setting.hasMincolour())
4576 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4577 new Color(setting.getMincolour()), new Color(
4578 setting.getColour()), setting.getMin(),
4579 setting.getMax()) : new FeatureColour(new Color(
4580 setting.getMincolour()), new Color(setting.getColour()),
4582 if (setting.hasThreshold())
4584 gc.setThreshold(setting.getThreshold());
4585 int threshstate = setting.getThreshstate();
4586 // -1 = None, 0 = Below, 1 = Above threshold
4587 if (threshstate == 0)
4589 gc.setBelowThreshold(true);
4591 else if (threshstate == 1)
4593 gc.setAboveThreshold(true);
4596 gc.setAutoScaled(true); // default
4597 if (setting.hasAutoScale())
4599 gc.setAutoScaled(setting.getAutoScale());
4601 if (setting.hasColourByLabel())
4603 gc.setColourByLabel(setting.getColourByLabel());
4605 // and put in the feature colour table.
4606 featureColours.put(setting.getType(), gc);
4610 featureColours.put(setting.getType(), new FeatureColour(
4611 new Color(setting.getColour())));
4613 renderOrder[fs] = setting.getType();
4614 if (setting.hasOrder())
4616 featureOrder.put(setting.getType(), setting.getOrder());
4620 featureOrder.put(setting.getType(), new Float(fs
4621 / jms.getFeatureSettings().getSettingCount()));
4623 if (setting.getDisplay())
4625 fdi.setVisible(setting.getType());
4628 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4629 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4631 Group grp = jms.getFeatureSettings().getGroup(gs);
4632 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4634 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4635 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4636 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4637 FeatureRendererSettings frs = new FeatureRendererSettings(
4638 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4639 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4640 .transferSettings(frs);
4644 if (view.getHiddenColumnsCount() > 0)
4646 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4648 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4649 .getHiddenColumns(c).getEnd() // +1
4653 if (view.getCalcIdParam() != null)
4655 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4657 if (calcIdParam != null)
4659 if (recoverCalcIdParam(calcIdParam, af.viewport))
4664 warn("Couldn't recover parameters for "
4665 + calcIdParam.getCalcId());
4670 af.setMenusFromViewport(af.viewport);
4671 af.setTitle(view.getTitle());
4672 // TODO: we don't need to do this if the viewport is aready visible.
4674 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4675 * has a 'cdna/protein complement' view, in which case save it in order to
4676 * populate a SplitFrame once all views have been read in.
4678 String complementaryViewId = view.getComplementId();
4679 if (complementaryViewId == null)
4681 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4683 // recompute any autoannotation
4684 af.alignPanel.updateAnnotation(false, true);
4685 reorderAutoannotation(af, al, autoAlan);
4686 af.alignPanel.alignmentChanged();
4690 splitFrameCandidates.put(view, af);
4695 private ColourSchemeI constructAnnotationColour(
4696 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4697 JalviewModelSequence jms, boolean checkGroupAnnColour)
4699 boolean propagateAnnColour = false;
4700 ColourSchemeI cs = null;
4701 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4702 if (checkGroupAnnColour && al.getGroups() != null
4703 && al.getGroups().size() > 0)
4705 // pre 2.8.1 behaviour
4706 // check to see if we should transfer annotation colours
4707 propagateAnnColour = true;
4708 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4710 if (sg.getColourScheme() instanceof AnnotationColourGradient)
4712 propagateAnnColour = false;
4716 // int find annotation
4717 if (annAlignment.getAlignmentAnnotation() != null)
4719 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4721 if (annAlignment.getAlignmentAnnotation()[i].label
4722 .equals(viewAnnColour.getAnnotation()))
4724 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4726 annAlignment.getAlignmentAnnotation()[i]
4727 .setThreshold(new jalview.datamodel.GraphLine(
4728 viewAnnColour.getThreshold(), "Threshold",
4729 java.awt.Color.black)
4734 if (viewAnnColour.getColourScheme().equals(
4735 ResidueColourScheme.NONE))
4737 cs = new AnnotationColourGradient(
4738 annAlignment.getAlignmentAnnotation()[i],
4739 new java.awt.Color(viewAnnColour.getMinColour()),
4740 new java.awt.Color(viewAnnColour.getMaxColour()),
4741 viewAnnColour.getAboveThreshold());
4743 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4745 cs = new AnnotationColourGradient(
4746 annAlignment.getAlignmentAnnotation()[i],
4747 getUserColourScheme(jms,
4748 viewAnnColour.getColourScheme()),
4749 viewAnnColour.getAboveThreshold());
4753 cs = new AnnotationColourGradient(
4754 annAlignment.getAlignmentAnnotation()[i],
4755 ColourSchemeProperty.getColourScheme(al,
4756 viewAnnColour.getColourScheme()),
4757 viewAnnColour.getAboveThreshold());
4759 if (viewAnnColour.hasPerSequence())
4761 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4764 if (viewAnnColour.hasPredefinedColours())
4766 ((AnnotationColourGradient) cs)
4767 .setPredefinedColours(viewAnnColour
4768 .isPredefinedColours());
4770 if (propagateAnnColour && al.getGroups() != null)
4772 // Also use these settings for all the groups
4773 for (int g = 0; g < al.getGroups().size(); g++)
4775 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4783 * if (viewAnnColour.getColourScheme().equals(ResidueColourScheme.NONE)) { sg.cs =
4784 * new AnnotationColourGradient(
4785 * annAlignment.getAlignmentAnnotation()[i], new
4786 * java.awt.Color(viewAnnColour. getMinColour()), new
4787 * java.awt.Color(viewAnnColour. getMaxColour()),
4788 * viewAnnColour.getAboveThreshold()); } else
4791 sg.setColourScheme(new AnnotationColourGradient(
4792 annAlignment.getAlignmentAnnotation()[i], sg
4793 .getColourScheme(), viewAnnColour
4794 .getAboveThreshold()));
4795 if (cs instanceof AnnotationColourGradient)
4797 if (viewAnnColour.hasPerSequence())
4799 ((AnnotationColourGradient) cs)
4800 .setSeqAssociated(viewAnnColour.isPerSequence());
4802 if (viewAnnColour.hasPredefinedColours())
4804 ((AnnotationColourGradient) cs)
4805 .setPredefinedColours(viewAnnColour
4806 .isPredefinedColours());
4822 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4823 List<JvAnnotRow> autoAlan)
4825 // copy over visualization settings for autocalculated annotation in the
4827 if (al.getAlignmentAnnotation() != null)
4830 * Kludge for magic autoannotation names (see JAL-811)
4832 String[] magicNames = new String[] { "Consensus", "Quality",
4834 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4835 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4836 for (String nm : magicNames)
4838 visan.put(nm, nullAnnot);
4840 for (JvAnnotRow auan : autoAlan)
4842 visan.put(auan.template.label
4843 + (auan.template.getCalcId() == null ? "" : "\t"
4844 + auan.template.getCalcId()), auan);
4846 int hSize = al.getAlignmentAnnotation().length;
4847 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4848 // work through any autoCalculated annotation already on the view
4849 // removing it if it should be placed in a different location on the
4850 // annotation panel.
4851 List<String> remains = new ArrayList<String>(visan.keySet());
4852 for (int h = 0; h < hSize; h++)
4854 jalview.datamodel.AlignmentAnnotation jalan = al
4855 .getAlignmentAnnotation()[h];
4856 if (jalan.autoCalculated)
4859 JvAnnotRow valan = visan.get(k = jalan.label);
4860 if (jalan.getCalcId() != null)
4862 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4867 // delete the auto calculated row from the alignment
4868 al.deleteAnnotation(jalan, false);
4872 if (valan != nullAnnot)
4874 if (jalan != valan.template)
4876 // newly created autoannotation row instance
4877 // so keep a reference to the visible annotation row
4878 // and copy over all relevant attributes
4879 if (valan.template.graphHeight >= 0)
4882 jalan.graphHeight = valan.template.graphHeight;
4884 jalan.visible = valan.template.visible;
4886 reorder.add(new JvAnnotRow(valan.order, jalan));
4891 // Add any (possibly stale) autocalculated rows that were not appended to
4892 // the view during construction
4893 for (String other : remains)
4895 JvAnnotRow othera = visan.get(other);
4896 if (othera != nullAnnot && othera.template.getCalcId() != null
4897 && othera.template.getCalcId().length() > 0)
4899 reorder.add(othera);
4902 // now put the automatic annotation in its correct place
4903 int s = 0, srt[] = new int[reorder.size()];
4904 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4905 for (JvAnnotRow jvar : reorder)
4908 srt[s++] = jvar.order;
4911 jalview.util.QuickSort.sort(srt, rws);
4912 // and re-insert the annotation at its correct position
4913 for (JvAnnotRow jvar : rws)
4915 al.addAnnotation(jvar.template, jvar.order);
4917 af.alignPanel.adjustAnnotationHeight();
4921 Hashtable skipList = null;
4924 * TODO remove this method
4927 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4928 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4929 * throw new Error("Implementation Error. No skipList defined for this
4930 * Jalview2XML instance."); } return (AlignFrame)
4931 * skipList.get(view.getSequenceSetId()); }
4935 * Check if the Jalview view contained in object should be skipped or not.
4938 * @return true if view's sequenceSetId is a key in skipList
4940 private boolean skipViewport(JalviewModel object)
4942 if (skipList == null)
4947 if (skipList.containsKey(id = object.getJalviewModelSequence()
4948 .getViewport()[0].getSequenceSetId()))
4950 if (Cache.log != null && Cache.log.isDebugEnabled())
4952 Cache.log.debug("Skipping seuqence set id " + id);
4959 public void addToSkipList(AlignFrame af)
4961 if (skipList == null)
4963 skipList = new Hashtable();
4965 skipList.put(af.getViewport().getSequenceSetId(), af);
4968 public void clearSkipList()
4970 if (skipList != null)
4977 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4978 boolean ignoreUnrefed)
4980 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4982 Vector dseqs = null;
4985 // create a list of new dataset sequences
4986 dseqs = new Vector();
4988 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4990 Sequence vamsasSeq = vamsasSet.getSequence(i);
4991 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4993 // create a new dataset
4996 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4997 dseqs.copyInto(dsseqs);
4998 ds = new jalview.datamodel.Alignment(dsseqs);
4999 debug("Created new dataset " + vamsasSet.getDatasetId()
5000 + " for alignment " + System.identityHashCode(al));
5001 addDatasetRef(vamsasSet.getDatasetId(), ds);
5003 // set the dataset for the newly imported alignment.
5004 if (al.getDataset() == null && !ignoreUnrefed)
5013 * sequence definition to create/merge dataset sequence for
5017 * vector to add new dataset sequence to
5018 * @param ignoreUnrefed
5019 * - when true, don't create new sequences from vamsasSeq if it's id
5020 * doesn't already have an asssociated Jalview sequence.
5022 * - used to reorder the sequence in the alignment according to the
5023 * vamsasSeq array ordering, to preserve ordering of dataset
5025 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5026 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5028 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5030 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5031 boolean reorder = false;
5032 SequenceI dsq = null;
5033 if (sq != null && sq.getDatasetSequence() != null)
5035 dsq = sq.getDatasetSequence();
5041 if (sq == null && ignoreUnrefed)
5045 String sqid = vamsasSeq.getDsseqid();
5048 // need to create or add a new dataset sequence reference to this sequence
5051 dsq = seqRefIds.get(sqid);
5056 // make a new dataset sequence
5057 dsq = sq.createDatasetSequence();
5060 // make up a new dataset reference for this sequence
5061 sqid = seqHash(dsq);
5063 dsq.setVamsasId(uniqueSetSuffix + sqid);
5064 seqRefIds.put(sqid, dsq);
5069 dseqs.addElement(dsq);
5074 ds.addSequence(dsq);
5080 { // make this dataset sequence sq's dataset sequence
5081 sq.setDatasetSequence(dsq);
5082 // and update the current dataset alignment
5087 if (!dseqs.contains(dsq))
5094 if (ds.findIndex(dsq) < 0)
5096 ds.addSequence(dsq);
5103 // TODO: refactor this as a merge dataset sequence function
5104 // now check that sq (the dataset sequence) sequence really is the union of
5105 // all references to it
5106 // boolean pre = sq.getStart() < dsq.getStart();
5107 // boolean post = sq.getEnd() > dsq.getEnd();
5111 // StringBuffer sb = new StringBuffer();
5112 String newres = jalview.analysis.AlignSeq.extractGaps(
5113 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5114 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5115 && newres.length() > dsq.getLength())
5117 // Update with the longer sequence.
5121 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5122 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5123 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5124 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5126 dsq.setSequence(newres);
5128 // TODO: merges will never happen if we 'know' we have the real dataset
5129 // sequence - this should be detected when id==dssid
5131 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5132 // + (pre ? "prepended" : "") + " "
5133 // + (post ? "appended" : ""));
5138 // sequence refs are identical. We may need to update the existing dataset
5139 // alignment with this one, though.
5140 if (ds != null && dseqs == null)
5142 int opos = ds.findIndex(dsq);
5143 SequenceI tseq = null;
5144 if (opos != -1 && vseqpos != opos)
5146 // remove from old position
5147 ds.deleteSequence(dsq);
5149 if (vseqpos < ds.getHeight())
5151 if (vseqpos != opos)
5153 // save sequence at destination position
5154 tseq = ds.getSequenceAt(vseqpos);
5155 ds.replaceSequenceAt(vseqpos, dsq);
5156 ds.addSequence(tseq);
5161 ds.addSequence(dsq);
5168 * TODO use AlignmentI here and in related methods - needs
5169 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5171 Hashtable<String, AlignmentI> datasetIds = null;
5173 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5175 private AlignmentI getDatasetFor(String datasetId)
5177 if (datasetIds == null)
5179 datasetIds = new Hashtable<String, AlignmentI>();
5182 if (datasetIds.containsKey(datasetId))
5184 return datasetIds.get(datasetId);
5189 private void addDatasetRef(String datasetId, AlignmentI dataset)
5191 if (datasetIds == null)
5193 datasetIds = new Hashtable<String, AlignmentI>();
5195 datasetIds.put(datasetId, dataset);
5199 * make a new dataset ID for this jalview dataset alignment
5204 private String getDatasetIdRef(AlignmentI dataset)
5206 if (dataset.getDataset() != null)
5208 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5210 String datasetId = makeHashCode(dataset, null);
5211 if (datasetId == null)
5213 // make a new datasetId and record it
5214 if (dataset2Ids == null)
5216 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5220 datasetId = dataset2Ids.get(dataset);
5222 if (datasetId == null)
5224 datasetId = "ds" + dataset2Ids.size() + 1;
5225 dataset2Ids.put(dataset, datasetId);
5231 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5233 for (int d = 0; d < sequence.getDBRefCount(); d++)
5235 DBRef dr = sequence.getDBRef(d);
5236 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5237 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5238 .getVersion(), sequence.getDBRef(d).getAccessionId());
5239 if (dr.getMapping() != null)
5241 entry.setMap(addMapping(dr.getMapping()));
5243 datasetSequence.addDBRef(entry);
5247 private jalview.datamodel.Mapping addMapping(Mapping m)
5249 SequenceI dsto = null;
5250 // Mapping m = dr.getMapping();
5251 int fr[] = new int[m.getMapListFromCount() * 2];
5252 Enumeration f = m.enumerateMapListFrom();
5253 for (int _i = 0; f.hasMoreElements(); _i += 2)
5255 MapListFrom mf = (MapListFrom) f.nextElement();
5256 fr[_i] = mf.getStart();
5257 fr[_i + 1] = mf.getEnd();
5259 int fto[] = new int[m.getMapListToCount() * 2];
5260 f = m.enumerateMapListTo();
5261 for (int _i = 0; f.hasMoreElements(); _i += 2)
5263 MapListTo mf = (MapListTo) f.nextElement();
5264 fto[_i] = mf.getStart();
5265 fto[_i + 1] = mf.getEnd();
5267 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5268 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5269 if (m.getMappingChoice() != null)
5271 MappingChoice mc = m.getMappingChoice();
5272 if (mc.getDseqFor() != null)
5274 String dsfor = "" + mc.getDseqFor();
5275 if (seqRefIds.containsKey(dsfor))
5280 jmap.setTo(seqRefIds.get(dsfor));
5284 frefedSequence.add(newMappingRef(dsfor, jmap));
5290 * local sequence definition
5292 Sequence ms = mc.getSequence();
5293 SequenceI djs = null;
5294 String sqid = ms.getDsseqid();
5295 if (sqid != null && sqid.length() > 0)
5298 * recover dataset sequence
5300 djs = seqRefIds.get(sqid);
5305 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5306 sqid = ((Object) ms).toString(); // make up a new hascode for
5307 // undefined dataset sequence hash
5308 // (unlikely to happen)
5314 * make a new dataset sequence and add it to refIds hash
5316 djs = new jalview.datamodel.Sequence(ms.getName(),
5318 djs.setStart(jmap.getMap().getToLowest());
5319 djs.setEnd(jmap.getMap().getToHighest());
5320 djs.setVamsasId(uniqueSetSuffix + sqid);
5322 incompleteSeqs.put(sqid, djs);
5323 seqRefIds.put(sqid, djs);
5326 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5335 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5336 boolean keepSeqRefs)
5339 JalviewModel jm = saveState(ap, null, null, null);
5344 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5348 uniqueSetSuffix = "";
5349 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5354 if (this.frefedSequence == null)
5356 frefedSequence = new Vector();
5359 viewportsAdded.clear();
5361 AlignFrame af = loadFromObject(jm, null, false, null);
5362 af.alignPanels.clear();
5363 af.closeMenuItem_actionPerformed(true);
5366 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5367 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5368 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5369 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5370 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5373 return af.alignPanel;
5377 * flag indicating if hashtables should be cleared on finalization TODO this
5378 * flag may not be necessary
5380 private final boolean _cleartables = true;
5382 private Hashtable jvids2vobj;
5387 * @see java.lang.Object#finalize()
5390 protected void finalize() throws Throwable
5392 // really make sure we have no buried refs left.
5397 this.seqRefIds = null;
5398 this.seqsToIds = null;
5402 private void warn(String msg)
5407 private void warn(String msg, Exception e)
5409 if (Cache.log != null)
5413 Cache.log.warn(msg, e);
5417 Cache.log.warn(msg);
5422 System.err.println("Warning: " + msg);
5425 e.printStackTrace();
5430 private void debug(String string)
5432 debug(string, null);
5435 private void debug(String msg, Exception e)
5437 if (Cache.log != null)
5441 Cache.log.debug(msg, e);
5445 Cache.log.debug(msg);
5450 System.err.println("Warning: " + msg);
5453 e.printStackTrace();
5459 * set the object to ID mapping tables used to write/recover objects and XML
5460 * ID strings for the jalview project. If external tables are provided then
5461 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5462 * object goes out of scope. - also populates the datasetIds hashtable with
5463 * alignment objects containing dataset sequences
5466 * Map from ID strings to jalview datamodel
5468 * Map from jalview datamodel to ID strings
5472 public void setObjectMappingTables(Hashtable vobj2jv,
5473 IdentityHashMap jv2vobj)
5475 this.jv2vobj = jv2vobj;
5476 this.vobj2jv = vobj2jv;
5477 Iterator ds = jv2vobj.keySet().iterator();
5479 while (ds.hasNext())
5481 Object jvobj = ds.next();
5482 id = jv2vobj.get(jvobj).toString();
5483 if (jvobj instanceof jalview.datamodel.Alignment)
5485 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5487 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5490 else if (jvobj instanceof jalview.datamodel.Sequence)
5492 // register sequence object so the XML parser can recover it.
5493 if (seqRefIds == null)
5495 seqRefIds = new HashMap<String, SequenceI>();
5497 if (seqsToIds == null)
5499 seqsToIds = new IdentityHashMap<SequenceI, String>();
5501 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5502 seqsToIds.put((SequenceI) jvobj, id);
5504 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5507 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5508 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5509 if (jvann.annotationId == null)
5511 jvann.annotationId = anid;
5513 if (!jvann.annotationId.equals(anid))
5515 // TODO verify that this is the correct behaviour
5516 this.warn("Overriding Annotation ID for " + anid
5517 + " from different id : " + jvann.annotationId);
5518 jvann.annotationId = anid;
5521 else if (jvobj instanceof String)
5523 if (jvids2vobj == null)
5525 jvids2vobj = new Hashtable();
5526 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5531 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5537 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5538 * objects created from the project archive. If string is null (default for
5539 * construction) then suffix will be set automatically.
5543 public void setUniqueSetSuffix(String string)
5545 uniqueSetSuffix = string;
5550 * uses skipList2 as the skipList for skipping views on sequence sets
5551 * associated with keys in the skipList
5555 public void setSkipList(Hashtable skipList2)
5557 skipList = skipList2;
5561 * Reads the jar entry of given name and returns its contents, or null if the
5562 * entry is not found.
5565 * @param jarEntryName
5568 protected String readJarEntry(jarInputStreamProvider jprovider,
5569 String jarEntryName)
5571 String result = null;
5572 BufferedReader in = null;
5577 * Reopen the jar input stream and traverse its entries to find a matching
5580 JarInputStream jin = jprovider.getJarInputStream();
5581 JarEntry entry = null;
5584 entry = jin.getNextJarEntry();
5585 } while (entry != null && !entry.getName().equals(jarEntryName));
5589 StringBuilder out = new StringBuilder(256);
5590 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5593 while ((data = in.readLine()) != null)
5597 result = out.toString();
5601 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5603 } catch (Exception ex)
5605 ex.printStackTrace();
5613 } catch (IOException e)
5624 * Returns an incrementing counter (0, 1, 2...)
5628 private synchronized int nextCounter()