2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.analysis.Conservation;
24 import jalview.api.FeatureColourI;
25 import jalview.api.ViewStyleI;
26 import jalview.api.structures.JalviewStructureDisplayI;
27 import jalview.bin.Cache;
28 import jalview.datamodel.AlignedCodonFrame;
29 import jalview.datamodel.Alignment;
30 import jalview.datamodel.AlignmentAnnotation;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.RnaViewerModel;
34 import jalview.datamodel.SequenceGroup;
35 import jalview.datamodel.SequenceI;
36 import jalview.datamodel.StructureViewerModel;
37 import jalview.datamodel.StructureViewerModel.StructureData;
38 import jalview.ext.varna.RnaModel;
39 import jalview.gui.StructureViewer.ViewerType;
40 import jalview.schemabinding.version2.AlcodMap;
41 import jalview.schemabinding.version2.AlcodonFrame;
42 import jalview.schemabinding.version2.Annotation;
43 import jalview.schemabinding.version2.AnnotationColours;
44 import jalview.schemabinding.version2.AnnotationElement;
45 import jalview.schemabinding.version2.CalcIdParam;
46 import jalview.schemabinding.version2.DBRef;
47 import jalview.schemabinding.version2.Features;
48 import jalview.schemabinding.version2.Group;
49 import jalview.schemabinding.version2.HiddenColumns;
50 import jalview.schemabinding.version2.JGroup;
51 import jalview.schemabinding.version2.JSeq;
52 import jalview.schemabinding.version2.JalviewModel;
53 import jalview.schemabinding.version2.JalviewModelSequence;
54 import jalview.schemabinding.version2.MapListFrom;
55 import jalview.schemabinding.version2.MapListTo;
56 import jalview.schemabinding.version2.Mapping;
57 import jalview.schemabinding.version2.MappingChoice;
58 import jalview.schemabinding.version2.OtherData;
59 import jalview.schemabinding.version2.PdbentryItem;
60 import jalview.schemabinding.version2.Pdbids;
61 import jalview.schemabinding.version2.Property;
62 import jalview.schemabinding.version2.RnaViewer;
63 import jalview.schemabinding.version2.SecondaryStructure;
64 import jalview.schemabinding.version2.Sequence;
65 import jalview.schemabinding.version2.SequenceSet;
66 import jalview.schemabinding.version2.SequenceSetProperties;
67 import jalview.schemabinding.version2.Setting;
68 import jalview.schemabinding.version2.StructureState;
69 import jalview.schemabinding.version2.ThresholdLine;
70 import jalview.schemabinding.version2.Tree;
71 import jalview.schemabinding.version2.UserColours;
72 import jalview.schemabinding.version2.Viewport;
73 import jalview.schemes.AnnotationColourGradient;
74 import jalview.schemes.ColourSchemeI;
75 import jalview.schemes.ColourSchemeProperty;
76 import jalview.schemes.FeatureColour;
77 import jalview.schemes.ResidueColourScheme;
78 import jalview.schemes.ResidueProperties;
79 import jalview.schemes.UserColourScheme;
80 import jalview.structure.StructureSelectionManager;
81 import jalview.structures.models.AAStructureBindingModel;
82 import jalview.util.MessageManager;
83 import jalview.util.Platform;
84 import jalview.util.StringUtils;
85 import jalview.util.jarInputStreamProvider;
86 import jalview.viewmodel.AlignmentViewport;
87 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
88 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
89 import jalview.ws.jws2.Jws2Discoverer;
90 import jalview.ws.jws2.dm.AAConSettings;
91 import jalview.ws.jws2.jabaws2.Jws2Instance;
92 import jalview.ws.params.ArgumentI;
93 import jalview.ws.params.AutoCalcSetting;
94 import jalview.ws.params.WsParamSetI;
96 import java.awt.Color;
97 import java.awt.Rectangle;
98 import java.io.BufferedReader;
99 import java.io.DataInputStream;
100 import java.io.DataOutputStream;
102 import java.io.FileInputStream;
103 import java.io.FileOutputStream;
104 import java.io.IOException;
105 import java.io.InputStreamReader;
106 import java.io.OutputStreamWriter;
107 import java.io.PrintWriter;
108 import java.lang.reflect.InvocationTargetException;
109 import java.net.MalformedURLException;
111 import java.util.ArrayList;
112 import java.util.Arrays;
113 import java.util.Enumeration;
114 import java.util.HashMap;
115 import java.util.HashSet;
116 import java.util.Hashtable;
117 import java.util.IdentityHashMap;
118 import java.util.Iterator;
119 import java.util.LinkedHashMap;
120 import java.util.List;
121 import java.util.Map;
122 import java.util.Map.Entry;
123 import java.util.Set;
124 import java.util.Vector;
125 import java.util.jar.JarEntry;
126 import java.util.jar.JarInputStream;
127 import java.util.jar.JarOutputStream;
129 import javax.swing.JInternalFrame;
130 import javax.swing.JOptionPane;
131 import javax.swing.SwingUtilities;
133 import org.exolab.castor.xml.Marshaller;
134 import org.exolab.castor.xml.Unmarshaller;
137 * Write out the current jalview desktop state as a Jalview XML stream.
139 * Note: the vamsas objects referred to here are primitive versions of the
140 * VAMSAS project schema elements - they are not the same and most likely never
144 * @version $Revision: 1.134 $
146 public class Jalview2XML
148 private static final String VIEWER_PREFIX = "viewer_";
150 private static final String RNA_PREFIX = "rna_";
152 private static final String UTF_8 = "UTF-8";
154 // use this with nextCounter() to make unique names for entities
155 private int counter = 0;
158 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
159 * of sequence objects are created.
161 IdentityHashMap<SequenceI, String> seqsToIds = null;
164 * jalview XML Sequence ID to jalview sequence object reference (both dataset
165 * and alignment sequences. Populated as XML reps of sequence objects are
168 Map<String, SequenceI> seqRefIds = null;
170 Map<String, SequenceI> incompleteSeqs = null;
172 List<SeqFref> frefedSequence = null;
174 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
177 * Map of reconstructed AlignFrame objects that appear to have come from
178 * SplitFrame objects (have a dna/protein complement view).
180 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
183 * Map from displayed rna structure models to their saved session state jar
186 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
189 * create/return unique hash string for sq
192 * @return new or existing unique string for sq
194 String seqHash(SequenceI sq)
196 if (seqsToIds == null)
200 if (seqsToIds.containsKey(sq))
202 return seqsToIds.get(sq);
206 // create sequential key
207 String key = "sq" + (seqsToIds.size() + 1);
208 key = makeHashCode(sq, key); // check we don't have an external reference
210 seqsToIds.put(sq, key);
219 if (seqRefIds != null)
223 if (seqsToIds != null)
227 if (incompleteSeqs != null)
229 incompleteSeqs.clear();
237 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
238 // seqRefIds = new Hashtable();
239 // seqsToIds = new IdentityHashMap();
245 if (seqsToIds == null)
247 seqsToIds = new IdentityHashMap<SequenceI, String>();
249 if (seqRefIds == null)
251 seqRefIds = new HashMap<String, SequenceI>();
253 if (incompleteSeqs == null)
255 incompleteSeqs = new HashMap<String, SequenceI>();
257 if (frefedSequence == null)
259 frefedSequence = new ArrayList<SeqFref>();
267 public Jalview2XML(boolean raiseGUI)
269 this.raiseGUI = raiseGUI;
273 * base class for resolving forward references to sequences by their ID
278 abstract class SeqFref
284 public SeqFref(String _sref, String type)
290 public String getSref()
295 public SequenceI getSrefSeq()
297 return seqRefIds.get(sref);
300 public boolean isResolvable()
302 return seqRefIds.get(sref) != null;
305 public SequenceI getSrefDatasetSeq()
307 SequenceI sq = seqRefIds.get(sref);
310 while (sq.getDatasetSequence() != null)
312 sq = sq.getDatasetSequence();
319 * @return true if the forward reference was fully resolved
321 abstract boolean resolve();
324 public String toString()
326 return type + " reference to " + sref;
331 * create forward reference for a mapping
337 public SeqFref newMappingRef(final String sref,
338 final jalview.datamodel.Mapping _jmap)
340 SeqFref fref = new SeqFref(sref, "Mapping")
342 public jalview.datamodel.Mapping jmap = _jmap;
347 SequenceI seq = getSrefDatasetSeq();
359 public SeqFref newAlcodMapRef(final String sref,
360 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
363 SeqFref fref = new SeqFref(sref, "Codon Frame")
365 AlignedCodonFrame cf = _cf;
367 public jalview.datamodel.Mapping mp = _jmap;
370 public boolean isResolvable()
372 return super.isResolvable() && mp.getTo() != null;
378 SequenceI seq = getSrefDatasetSeq();
383 cf.addMap(seq, mp.getTo(), mp.getMap());
390 public void resolveFrefedSequences()
392 Iterator<SeqFref> nextFref = frefedSequence.iterator();
393 int toresolve = frefedSequence.size();
394 int unresolved = 0, failedtoresolve = 0;
395 while (nextFref.hasNext())
397 SeqFref ref = nextFref.next();
398 if (ref.isResolvable())
410 } catch (Exception x)
413 .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
426 System.err.println("Jalview Project Import: There were " + unresolved
427 + " forward references left unresolved on the stack.");
429 if (failedtoresolve > 0)
431 System.err.println("SERIOUS! " + failedtoresolve
432 + " resolvable forward references failed to resolve.");
434 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
436 System.err.println("Jalview Project Import: There are "
437 + incompleteSeqs.size()
438 + " sequences which may have incomplete metadata.");
439 if (incompleteSeqs.size() < 10)
441 for (SequenceI s : incompleteSeqs.values())
443 System.err.println(s.toString());
449 .println("Too many to report. Skipping output of incomplete sequences.");
455 * This maintains a map of viewports, the key being the seqSetId. Important to
456 * set historyItem and redoList for multiple views
458 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
460 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
462 String uniqueSetSuffix = "";
465 * List of pdbfiles added to Jar
467 List<String> pdbfiles = null;
469 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
470 public void saveState(File statefile)
472 FileOutputStream fos = null;
475 fos = new FileOutputStream(statefile);
476 JarOutputStream jout = new JarOutputStream(fos);
479 } catch (Exception e)
481 // TODO: inform user of the problem - they need to know if their data was
483 if (errorMessage == null)
485 errorMessage = "Couldn't write Jalview Archive to output file '"
486 + statefile + "' - See console error log for details";
490 errorMessage += "(output file was '" + statefile + "')";
500 } catch (IOException e)
510 * Writes a jalview project archive to the given Jar output stream.
514 public void saveState(JarOutputStream jout)
516 AlignFrame[] frames = Desktop.getAlignFrames();
522 saveAllFrames(Arrays.asList(frames), jout);
526 * core method for storing state for a set of AlignFrames.
529 * - frames involving all data to be exported (including containing
532 * - project output stream
534 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
536 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
539 * ensure cached data is clear before starting
541 // todo tidy up seqRefIds, seqsToIds initialisation / reset
543 splitFrameCandidates.clear();
548 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
549 // //////////////////////////////////////////////////
551 List<String> shortNames = new ArrayList<String>();
552 List<String> viewIds = new ArrayList<String>();
555 for (int i = frames.size() - 1; i > -1; i--)
557 AlignFrame af = frames.get(i);
561 .containsKey(af.getViewport().getSequenceSetId()))
566 String shortName = makeFilename(af, shortNames);
568 int ap, apSize = af.alignPanels.size();
570 for (ap = 0; ap < apSize; ap++)
572 AlignmentPanel apanel = af.alignPanels.get(ap);
573 String fileName = apSize == 1 ? shortName : ap + shortName;
574 if (!fileName.endsWith(".xml"))
576 fileName = fileName + ".xml";
579 saveState(apanel, fileName, jout, viewIds);
581 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
583 if (!dsses.containsKey(dssid))
585 dsses.put(dssid, af);
590 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
596 } catch (Exception foo)
601 } catch (Exception ex)
603 // TODO: inform user of the problem - they need to know if their data was
605 if (errorMessage == null)
607 errorMessage = "Couldn't write Jalview Archive - see error output for details";
609 ex.printStackTrace();
614 * Generates a distinct file name, based on the title of the AlignFrame, by
615 * appending _n for increasing n until an unused name is generated. The new
616 * name (without its extension) is added to the list.
620 * @return the generated name, with .xml extension
622 protected String makeFilename(AlignFrame af, List<String> namesUsed)
624 String shortName = af.getTitle();
626 if (shortName.indexOf(File.separatorChar) > -1)
628 shortName = shortName.substring(shortName
629 .lastIndexOf(File.separatorChar) + 1);
634 while (namesUsed.contains(shortName))
636 if (shortName.endsWith("_" + (count - 1)))
638 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
641 shortName = shortName.concat("_" + count);
645 namesUsed.add(shortName);
647 if (!shortName.endsWith(".xml"))
649 shortName = shortName + ".xml";
654 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
655 public boolean saveAlignment(AlignFrame af, String jarFile,
660 FileOutputStream fos = new FileOutputStream(jarFile);
661 JarOutputStream jout = new JarOutputStream(fos);
662 List<AlignFrame> frames = new ArrayList<AlignFrame>();
664 // resolve splitframes
665 if (af.getViewport().getCodingComplement() != null)
667 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
673 saveAllFrames(frames, jout);
677 } catch (Exception foo)
683 } catch (Exception ex)
685 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
686 ex.printStackTrace();
691 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
692 String fileName, JarOutputStream jout)
695 for (String dssids : dsses.keySet())
697 AlignFrame _af = dsses.get(dssids);
698 String jfileName = fileName + " Dataset for " + _af.getTitle();
699 if (!jfileName.endsWith(".xml"))
701 jfileName = jfileName + ".xml";
703 saveState(_af.alignPanel, jfileName, true, jout, null);
708 * create a JalviewModel from an alignment view and marshall it to a
712 * panel to create jalview model for
714 * name of alignment panel written to output stream
721 public JalviewModel saveState(AlignmentPanel ap, String fileName,
722 JarOutputStream jout, List<String> viewIds)
724 return saveState(ap, fileName, false, jout, viewIds);
728 * create a JalviewModel from an alignment view and marshall it to a
732 * panel to create jalview model for
734 * name of alignment panel written to output stream
736 * when true, only write the dataset for the alignment, not the data
737 * associated with the view.
743 public JalviewModel saveState(AlignmentPanel ap, String fileName,
744 boolean storeDS, JarOutputStream jout, List<String> viewIds)
748 viewIds = new ArrayList<String>();
753 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
755 AlignViewport av = ap.av;
757 JalviewModel object = new JalviewModel();
758 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
760 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
761 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
762 "Development Build"));
765 * rjal is full height alignment, jal is actual alignment with full metadata
766 * but excludes hidden sequences.
768 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
770 if (av.hasHiddenRows())
772 rjal = jal.getHiddenSequences().getFullAlignment();
775 SequenceSet vamsasSet = new SequenceSet();
777 JalviewModelSequence jms = new JalviewModelSequence();
779 vamsasSet.setGapChar(jal.getGapCharacter() + "");
781 if (jal.getDataset() != null)
783 // dataset id is the dataset's hashcode
784 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
787 // switch jal and the dataset
788 jal = jal.getDataset();
792 if (jal.getProperties() != null)
794 Enumeration en = jal.getProperties().keys();
795 while (en.hasMoreElements())
797 String key = en.nextElement().toString();
798 SequenceSetProperties ssp = new SequenceSetProperties();
800 ssp.setValue(jal.getProperties().get(key).toString());
801 vamsasSet.addSequenceSetProperties(ssp);
806 Set<String> calcIdSet = new HashSet<String>();
807 // record the set of vamsas sequence XML POJO we create.
808 HashMap<String, Sequence> vamsasSetIds = new HashMap<String, Sequence>();
810 for (final SequenceI jds : rjal.getSequences())
812 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
813 : jds.getDatasetSequence();
814 String id = seqHash(jds);
815 if (vamsasSetIds.get(id) == null)
817 if (seqRefIds.get(id) != null && !storeDS)
819 // This happens for two reasons: 1. multiple views are being
821 // 2. the hashCode has collided with another sequence's code. This
823 // HAPPEN! (PF00072.15.stk does this)
824 // JBPNote: Uncomment to debug writing out of files that do not read
825 // back in due to ArrayOutOfBoundExceptions.
826 // System.err.println("vamsasSeq backref: "+id+"");
827 // System.err.println(jds.getName()+"
828 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
829 // System.err.println("Hashcode: "+seqHash(jds));
830 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
831 // System.err.println(rsq.getName()+"
832 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
833 // System.err.println("Hashcode: "+seqHash(rsq));
837 vamsasSeq = createVamsasSequence(id, jds);
838 vamsasSet.addSequence(vamsasSeq);
839 vamsasSetIds.put(id, vamsasSeq);
840 seqRefIds.put(id, jds);
844 jseq.setStart(jds.getStart());
845 jseq.setEnd(jds.getEnd());
846 jseq.setColour(av.getSequenceColour(jds).getRGB());
848 jseq.setId(id); // jseq id should be a string not a number
851 // Store any sequences this sequence represents
852 if (av.hasHiddenRows())
854 // use rjal, contains the full height alignment
855 jseq.setHidden(av.getAlignment().getHiddenSequences()
858 if (av.isHiddenRepSequence(jds))
860 jalview.datamodel.SequenceI[] reps = av
861 .getRepresentedSequences(jds).getSequencesInOrder(rjal);
863 for (int h = 0; h < reps.length; h++)
867 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
872 // mark sequence as reference - if it is the reference for this view
875 jseq.setViewreference(jds == jal.getSeqrep());
879 // TODO: omit sequence features from each alignment view's XML dump if we
880 // are storing dataset
881 if (jds.getSequenceFeatures() != null)
883 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
885 while (index < sf.length)
887 Features features = new Features();
889 features.setBegin(sf[index].getBegin());
890 features.setEnd(sf[index].getEnd());
891 features.setDescription(sf[index].getDescription());
892 features.setType(sf[index].getType());
893 features.setFeatureGroup(sf[index].getFeatureGroup());
894 features.setScore(sf[index].getScore());
895 if (sf[index].links != null)
897 for (int l = 0; l < sf[index].links.size(); l++)
899 OtherData keyValue = new OtherData();
900 keyValue.setKey("LINK_" + l);
901 keyValue.setValue(sf[index].links.elementAt(l).toString());
902 features.addOtherData(keyValue);
905 if (sf[index].otherDetails != null)
908 Iterator<String> keys = sf[index].otherDetails.keySet()
910 while (keys.hasNext())
913 OtherData keyValue = new OtherData();
914 keyValue.setKey(key);
915 keyValue.setValue(sf[index].otherDetails.get(key).toString());
916 features.addOtherData(keyValue);
920 jseq.addFeatures(features);
925 if (jdatasq.getAllPDBEntries() != null)
927 Enumeration en = jdatasq.getAllPDBEntries().elements();
928 while (en.hasMoreElements())
930 Pdbids pdb = new Pdbids();
931 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
934 String pdbId = entry.getId();
936 pdb.setType(entry.getType());
939 * Store any structure views associated with this sequence. This
940 * section copes with duplicate entries in the project, so a dataset
941 * only view *should* be coped with sensibly.
943 // This must have been loaded, is it still visible?
944 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
945 String matchedFile = null;
946 for (int f = frames.length - 1; f > -1; f--)
948 if (frames[f] instanceof StructureViewerBase)
950 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
951 matchedFile = saveStructureState(ap, jds, pdb, entry,
952 viewIds, matchedFile, viewFrame);
954 * Only store each structure viewer's state once in the project
955 * jar. First time through only (storeDS==false)
957 String viewId = viewFrame.getViewId();
958 if (!storeDS && !viewIds.contains(viewId))
963 String viewerState = viewFrame.getStateInfo();
964 writeJarEntry(jout, getViewerJarEntryName(viewId),
965 viewerState.getBytes());
966 } catch (IOException e)
968 System.err.println("Error saving viewer state: "
975 if (matchedFile != null || entry.getFile() != null)
977 if (entry.getFile() != null)
980 matchedFile = entry.getFile();
982 pdb.setFile(matchedFile); // entry.getFile());
983 if (pdbfiles == null)
985 pdbfiles = new ArrayList<String>();
988 if (!pdbfiles.contains(pdbId))
991 copyFileToJar(jout, matchedFile, pdbId);
995 Enumeration<String> props = entry.getProperties();
996 if (props.hasMoreElements())
998 PdbentryItem item = new PdbentryItem();
999 while (props.hasMoreElements())
1001 Property prop = new Property();
1002 String key = props.nextElement();
1004 prop.setValue(entry.getProperty(key).toString());
1005 item.addProperty(prop);
1007 pdb.addPdbentryItem(item);
1010 jseq.addPdbids(pdb);
1014 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1019 if (!storeDS && av.hasHiddenRows())
1021 jal = av.getAlignment();
1025 if (storeDS && jal.getCodonFrames() != null)
1027 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1028 for (AlignedCodonFrame acf : jac)
1030 AlcodonFrame alc = new AlcodonFrame();
1031 if (acf.getProtMappings() != null
1032 && acf.getProtMappings().length > 0)
1034 boolean hasMap = false;
1035 SequenceI[] dnas = acf.getdnaSeqs();
1036 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1037 for (int m = 0; m < pmaps.length; m++)
1039 AlcodMap alcmap = new AlcodMap();
1040 alcmap.setDnasq(seqHash(dnas[m]));
1041 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1043 alc.addAlcodMap(alcmap);
1048 vamsasSet.addAlcodonFrame(alc);
1051 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1053 // AlcodonFrame alc = new AlcodonFrame();
1054 // vamsasSet.addAlcodonFrame(alc);
1055 // for (int p = 0; p < acf.aaWidth; p++)
1057 // Alcodon cmap = new Alcodon();
1058 // if (acf.codons[p] != null)
1060 // // Null codons indicate a gapped column in the translated peptide
1062 // cmap.setPos1(acf.codons[p][0]);
1063 // cmap.setPos2(acf.codons[p][1]);
1064 // cmap.setPos3(acf.codons[p][2]);
1066 // alc.addAlcodon(cmap);
1068 // if (acf.getProtMappings() != null
1069 // && acf.getProtMappings().length > 0)
1071 // SequenceI[] dnas = acf.getdnaSeqs();
1072 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1073 // for (int m = 0; m < pmaps.length; m++)
1075 // AlcodMap alcmap = new AlcodMap();
1076 // alcmap.setDnasq(seqHash(dnas[m]));
1077 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1079 // alc.addAlcodMap(alcmap);
1086 // /////////////////////////////////
1087 if (!storeDS && av.currentTree != null)
1089 // FIND ANY ASSOCIATED TREES
1090 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1091 if (Desktop.desktop != null)
1093 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1095 for (int t = 0; t < frames.length; t++)
1097 if (frames[t] instanceof TreePanel)
1099 TreePanel tp = (TreePanel) frames[t];
1101 if (tp.treeCanvas.av.getAlignment() == jal)
1103 Tree tree = new Tree();
1104 tree.setTitle(tp.getTitle());
1105 tree.setCurrentTree((av.currentTree == tp.getTree()));
1106 tree.setNewick(tp.getTree().toString());
1107 tree.setThreshold(tp.treeCanvas.threshold);
1109 tree.setFitToWindow(tp.fitToWindow.getState());
1110 tree.setFontName(tp.getTreeFont().getName());
1111 tree.setFontSize(tp.getTreeFont().getSize());
1112 tree.setFontStyle(tp.getTreeFont().getStyle());
1113 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1115 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1116 tree.setShowDistances(tp.distanceMenu.getState());
1118 tree.setHeight(tp.getHeight());
1119 tree.setWidth(tp.getWidth());
1120 tree.setXpos(tp.getX());
1121 tree.setYpos(tp.getY());
1122 tree.setId(makeHashCode(tp, null));
1132 * store forward refs from an annotationRow to any groups
1134 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1137 for (SequenceI sq : jal.getSequences())
1139 // Store annotation on dataset sequences only
1140 AlignmentAnnotation[] aa = sq.getAnnotation();
1141 if (aa != null && aa.length > 0)
1143 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1150 if (jal.getAlignmentAnnotation() != null)
1152 // Store the annotation shown on the alignment.
1153 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1154 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1159 if (jal.getGroups() != null)
1161 JGroup[] groups = new JGroup[jal.getGroups().size()];
1163 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1165 JGroup jGroup = new JGroup();
1166 groups[++i] = jGroup;
1168 jGroup.setStart(sg.getStartRes());
1169 jGroup.setEnd(sg.getEndRes());
1170 jGroup.setName(sg.getName());
1171 if (groupRefs.containsKey(sg))
1173 // group has references so set its ID field
1174 jGroup.setId(groupRefs.get(sg));
1178 if (sg.cs.conservationApplied())
1180 jGroup.setConsThreshold(sg.cs.getConservationInc());
1182 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1184 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1188 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1191 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1193 jGroup.setColour("AnnotationColourGradient");
1194 jGroup.setAnnotationColours(constructAnnotationColours(
1195 (jalview.schemes.AnnotationColourGradient) sg.cs,
1198 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1200 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1204 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1207 jGroup.setPidThreshold(sg.cs.getThreshold());
1210 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1211 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1212 jGroup.setDisplayText(sg.getDisplayText());
1213 jGroup.setColourText(sg.getColourText());
1214 jGroup.setTextCol1(sg.textColour.getRGB());
1215 jGroup.setTextCol2(sg.textColour2.getRGB());
1216 jGroup.setTextColThreshold(sg.thresholdTextColour);
1217 jGroup.setShowUnconserved(sg.getShowNonconserved());
1218 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1219 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1220 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1221 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1222 for (SequenceI seq : sg.getSequences())
1224 jGroup.addSeq(seqHash(seq));
1228 jms.setJGroup(groups);
1232 // /////////SAVE VIEWPORT
1233 Viewport view = new Viewport();
1234 view.setTitle(ap.alignFrame.getTitle());
1235 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1236 av.getSequenceSetId()));
1237 view.setId(av.getViewId());
1238 if (av.getCodingComplement() != null)
1240 view.setComplementId(av.getCodingComplement().getViewId());
1242 view.setViewName(av.viewName);
1243 view.setGatheredViews(av.isGatherViewsHere());
1245 Rectangle size = ap.av.getExplodedGeometry();
1246 Rectangle position = size;
1249 size = ap.alignFrame.getBounds();
1250 if (av.getCodingComplement() != null)
1252 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1260 view.setXpos(position.x);
1261 view.setYpos(position.y);
1263 view.setWidth(size.width);
1264 view.setHeight(size.height);
1266 view.setStartRes(av.startRes);
1267 view.setStartSeq(av.startSeq);
1269 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1271 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1274 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1276 AnnotationColours ac = constructAnnotationColours(
1277 (jalview.schemes.AnnotationColourGradient) av
1278 .getGlobalColourScheme(),
1281 view.setAnnotationColours(ac);
1282 view.setBgColour("AnnotationColourGradient");
1286 view.setBgColour(ColourSchemeProperty.getColourName(av
1287 .getGlobalColourScheme()));
1290 ColourSchemeI cs = av.getGlobalColourScheme();
1294 if (cs.conservationApplied())
1296 view.setConsThreshold(cs.getConservationInc());
1297 if (cs instanceof jalview.schemes.UserColourScheme)
1299 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1303 if (cs instanceof ResidueColourScheme)
1305 view.setPidThreshold(cs.getThreshold());
1309 view.setConservationSelected(av.getConservationSelected());
1310 view.setPidSelected(av.getAbovePIDThreshold());
1311 view.setFontName(av.font.getName());
1312 view.setFontSize(av.font.getSize());
1313 view.setFontStyle(av.font.getStyle());
1314 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1315 view.setRenderGaps(av.isRenderGaps());
1316 view.setShowAnnotation(av.isShowAnnotation());
1317 view.setShowBoxes(av.getShowBoxes());
1318 view.setShowColourText(av.getColourText());
1319 view.setShowFullId(av.getShowJVSuffix());
1320 view.setRightAlignIds(av.isRightAlignIds());
1321 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1322 view.setShowText(av.getShowText());
1323 view.setShowUnconserved(av.getShowUnconserved());
1324 view.setWrapAlignment(av.getWrapAlignment());
1325 view.setTextCol1(av.getTextColour().getRGB());
1326 view.setTextCol2(av.getTextColour2().getRGB());
1327 view.setTextColThreshold(av.getThresholdTextColour());
1328 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1329 view.setShowSequenceLogo(av.isShowSequenceLogo());
1330 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1331 view.setShowGroupConsensus(av.isShowGroupConsensus());
1332 view.setShowGroupConservation(av.isShowGroupConservation());
1333 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1334 view.setShowDbRefTooltip(av.isShowDBRefs());
1335 view.setFollowHighlight(av.isFollowHighlight());
1336 view.setFollowSelection(av.followSelection);
1337 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1338 if (av.getFeaturesDisplayed() != null)
1340 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1342 String[] renderOrder = ap.getSeqPanel().seqCanvas
1343 .getFeatureRenderer().getRenderOrder()
1344 .toArray(new String[0]);
1346 Vector<String> settingsAdded = new Vector<String>();
1347 if (renderOrder != null)
1349 for (String featureType : renderOrder)
1351 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1352 .getFeatureRenderer().getFeatureStyle(featureType);
1353 Setting setting = new Setting();
1354 setting.setType(featureType);
1355 if (!fcol.isSimpleColour())
1357 setting.setColour(fcol.getMaxColour().getRGB());
1358 setting.setMincolour(fcol.getMinColour().getRGB());
1359 setting.setMin(fcol.getMin());
1360 setting.setMax(fcol.getMax());
1361 setting.setColourByLabel(fcol.isColourByLabel());
1362 setting.setAutoScale(fcol.isAutoScaled());
1363 setting.setThreshold(fcol.getThreshold());
1364 // -1 = No threshold, 0 = Below, 1 = Above
1365 setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
1366 .isBelowThreshold() ? 0 : -1));
1370 setting.setColour(fcol.getColour().getRGB());
1373 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1375 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1376 .getOrder(featureType);
1379 setting.setOrder(rorder);
1381 fs.addSetting(setting);
1382 settingsAdded.addElement(featureType);
1386 // is groups actually supposed to be a map here ?
1387 Iterator<String> en = ap.getSeqPanel().seqCanvas
1388 .getFeatureRenderer().getFeatureGroups().iterator();
1389 Vector<String> groupsAdded = new Vector<String>();
1390 while (en.hasNext())
1392 String grp = en.next();
1393 if (groupsAdded.contains(grp))
1397 Group g = new Group();
1399 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1400 .getFeatureRenderer().checkGroupVisibility(grp, false))
1403 groupsAdded.addElement(grp);
1405 jms.setFeatureSettings(fs);
1408 if (av.hasHiddenColumns())
1410 if (av.getColumnSelection() == null
1411 || av.getColumnSelection().getHiddenColumns() == null)
1413 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1417 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1420 int[] region = av.getColumnSelection().getHiddenColumns()
1422 HiddenColumns hc = new HiddenColumns();
1423 hc.setStart(region[0]);
1424 hc.setEnd(region[1]);
1425 view.addHiddenColumns(hc);
1429 if (calcIdSet.size() > 0)
1431 for (String calcId : calcIdSet)
1433 if (calcId.trim().length() > 0)
1435 CalcIdParam cidp = createCalcIdParam(calcId, av);
1436 // Some calcIds have no parameters.
1439 view.addCalcIdParam(cidp);
1445 jms.addViewport(view);
1447 object.setJalviewModelSequence(jms);
1448 object.getVamsasModel().addSequenceSet(vamsasSet);
1450 if (jout != null && fileName != null)
1452 // We may not want to write the object to disk,
1453 // eg we can copy the alignViewport to a new view object
1454 // using save and then load
1457 System.out.println("Writing jar entry " + fileName);
1458 JarEntry entry = new JarEntry(fileName);
1459 jout.putNextEntry(entry);
1460 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1462 Marshaller marshaller = new Marshaller(pout);
1463 marshaller.marshal(object);
1466 } catch (Exception ex)
1468 // TODO: raise error in GUI if marshalling failed.
1469 ex.printStackTrace();
1476 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1477 * for each viewer, with
1479 * <li>viewer geometry (position, size, split pane divider location)</li>
1480 * <li>index of the selected structure in the viewer (currently shows gapped
1482 * <li>the id of the annotation holding RNA secondary structure</li>
1483 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1485 * Varna viewer state is also written out (in native Varna XML) to separate
1486 * project jar entries. A separate entry is written for each RNA structure
1487 * displayed, with the naming convention
1489 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1497 * @param storeDataset
1499 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1500 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1501 boolean storeDataset)
1503 if (Desktop.desktop == null)
1507 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1508 for (int f = frames.length - 1; f > -1; f--)
1510 if (frames[f] instanceof AppVarna)
1512 AppVarna varna = (AppVarna) frames[f];
1514 * link the sequence to every viewer that is showing it and is linked to
1515 * its alignment panel
1517 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1519 String viewId = varna.getViewId();
1520 RnaViewer rna = new RnaViewer();
1521 rna.setViewId(viewId);
1522 rna.setTitle(varna.getTitle());
1523 rna.setXpos(varna.getX());
1524 rna.setYpos(varna.getY());
1525 rna.setWidth(varna.getWidth());
1526 rna.setHeight(varna.getHeight());
1527 rna.setDividerLocation(varna.getDividerLocation());
1528 rna.setSelectedRna(varna.getSelectedIndex());
1529 jseq.addRnaViewer(rna);
1532 * Store each Varna panel's state once in the project per sequence.
1533 * First time through only (storeDataset==false)
1535 // boolean storeSessions = false;
1536 // String sequenceViewId = viewId + seqsToIds.get(jds);
1537 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1539 // viewIds.add(sequenceViewId);
1540 // storeSessions = true;
1542 for (RnaModel model : varna.getModels())
1544 if (model.seq == jds)
1547 * VARNA saves each view (sequence or alignment secondary
1548 * structure, gapped or trimmed) as a separate XML file
1550 String jarEntryName = rnaSessions.get(model);
1551 if (jarEntryName == null)
1554 String varnaStateFile = varna.getStateInfo(model.rna);
1555 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1556 copyFileToJar(jout, varnaStateFile, jarEntryName);
1557 rnaSessions.put(model, jarEntryName);
1559 SecondaryStructure ss = new SecondaryStructure();
1560 String annotationId = varna.getAnnotation(jds).annotationId;
1561 ss.setAnnotationId(annotationId);
1562 ss.setViewerState(jarEntryName);
1563 ss.setGapped(model.gapped);
1564 ss.setTitle(model.title);
1565 rna.addSecondaryStructure(ss);
1574 * Copy the contents of a file to a new entry added to the output jar
1578 * @param jarEntryName
1580 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1581 String jarEntryName)
1583 DataInputStream dis = null;
1586 File file = new File(infilePath);
1587 if (file.exists() && jout != null)
1589 dis = new DataInputStream(new FileInputStream(file));
1590 byte[] data = new byte[(int) file.length()];
1591 dis.readFully(data);
1592 writeJarEntry(jout, jarEntryName, data);
1594 } catch (Exception ex)
1596 ex.printStackTrace();
1604 } catch (IOException e)
1613 * Write the data to a new entry of given name in the output jar file
1616 * @param jarEntryName
1618 * @throws IOException
1620 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1621 byte[] data) throws IOException
1625 System.out.println("Writing jar entry " + jarEntryName);
1626 jout.putNextEntry(new JarEntry(jarEntryName));
1627 DataOutputStream dout = new DataOutputStream(jout);
1628 dout.write(data, 0, data.length);
1635 * Save the state of a structure viewer
1640 * the archive XML element under which to save the state
1643 * @param matchedFile
1647 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1648 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1649 String matchedFile, StructureViewerBase viewFrame)
1651 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1654 * Look for any bindings for this viewer to the PDB file of interest
1655 * (including part matches excluding chain id)
1657 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1659 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1660 final String pdbId = pdbentry.getId();
1661 if (!pdbId.equals(entry.getId())
1662 && !(entry.getId().length() > 4 && entry.getId()
1663 .toLowerCase().startsWith(pdbId.toLowerCase())))
1666 * not interested in a binding to a different PDB entry here
1670 if (matchedFile == null)
1672 matchedFile = pdbentry.getFile();
1674 else if (!matchedFile.equals(pdbentry.getFile()))
1677 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1678 + pdbentry.getFile());
1682 // can get at it if the ID
1683 // match is ambiguous (e.g.
1686 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1688 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1689 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1691 StructureState state = new StructureState();
1692 state.setVisible(true);
1693 state.setXpos(viewFrame.getX());
1694 state.setYpos(viewFrame.getY());
1695 state.setWidth(viewFrame.getWidth());
1696 state.setHeight(viewFrame.getHeight());
1697 final String viewId = viewFrame.getViewId();
1698 state.setViewId(viewId);
1699 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1700 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1701 state.setColourByJmol(viewFrame.isColouredByViewer());
1702 state.setType(viewFrame.getViewerType().toString());
1703 pdb.addStructureState(state);
1710 private AnnotationColours constructAnnotationColours(
1711 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1712 JalviewModelSequence jms)
1714 AnnotationColours ac = new AnnotationColours();
1715 ac.setAboveThreshold(acg.getAboveThreshold());
1716 ac.setThreshold(acg.getAnnotationThreshold());
1717 ac.setAnnotation(acg.getAnnotation());
1718 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1720 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1725 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1729 ac.setMaxColour(acg.getMaxColour().getRGB());
1730 ac.setMinColour(acg.getMinColour().getRGB());
1731 ac.setPerSequence(acg.isSeqAssociated());
1732 ac.setPredefinedColours(acg.isPredefinedColours());
1736 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1737 IdentityHashMap<SequenceGroup, String> groupRefs,
1738 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1739 SequenceSet vamsasSet)
1742 for (int i = 0; i < aa.length; i++)
1744 Annotation an = new Annotation();
1746 AlignmentAnnotation annotation = aa[i];
1747 if (annotation.annotationId != null)
1749 annotationIds.put(annotation.annotationId, annotation);
1752 an.setId(annotation.annotationId);
1754 an.setVisible(annotation.visible);
1756 an.setDescription(annotation.description);
1758 if (annotation.sequenceRef != null)
1760 // 2.9 JAL-1781 xref on sequence id rather than name
1761 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1763 if (annotation.groupRef != null)
1765 String groupIdr = groupRefs.get(annotation.groupRef);
1766 if (groupIdr == null)
1768 // make a locally unique String
1770 annotation.groupRef,
1771 groupIdr = ("" + System.currentTimeMillis()
1772 + annotation.groupRef.getName() + groupRefs
1775 an.setGroupRef(groupIdr.toString());
1778 // store all visualization attributes for annotation
1779 an.setGraphHeight(annotation.graphHeight);
1780 an.setCentreColLabels(annotation.centreColLabels);
1781 an.setScaleColLabels(annotation.scaleColLabel);
1782 an.setShowAllColLabels(annotation.showAllColLabels);
1783 an.setBelowAlignment(annotation.belowAlignment);
1785 if (annotation.graph > 0)
1788 an.setGraphType(annotation.graph);
1789 an.setGraphGroup(annotation.graphGroup);
1790 if (annotation.getThreshold() != null)
1792 ThresholdLine line = new ThresholdLine();
1793 line.setLabel(annotation.getThreshold().label);
1794 line.setValue(annotation.getThreshold().value);
1795 line.setColour(annotation.getThreshold().colour.getRGB());
1796 an.setThresholdLine(line);
1804 an.setLabel(annotation.label);
1806 if (annotation == av.getAlignmentQualityAnnot()
1807 || annotation == av.getAlignmentConservationAnnotation()
1808 || annotation == av.getAlignmentConsensusAnnotation()
1809 || annotation.autoCalculated)
1811 // new way of indicating autocalculated annotation -
1812 an.setAutoCalculated(annotation.autoCalculated);
1814 if (annotation.hasScore())
1816 an.setScore(annotation.getScore());
1819 if (annotation.getCalcId() != null)
1821 calcIdSet.add(annotation.getCalcId());
1822 an.setCalcId(annotation.getCalcId());
1824 if (annotation.hasProperties())
1826 for (String pr : annotation.getProperties())
1828 Property prop = new Property();
1830 prop.setValue(annotation.getProperty(pr));
1831 an.addProperty(prop);
1835 AnnotationElement ae;
1836 if (annotation.annotations != null)
1838 an.setScoreOnly(false);
1839 for (int a = 0; a < annotation.annotations.length; a++)
1841 if ((annotation == null) || (annotation.annotations[a] == null))
1846 ae = new AnnotationElement();
1847 if (annotation.annotations[a].description != null)
1849 ae.setDescription(annotation.annotations[a].description);
1851 if (annotation.annotations[a].displayCharacter != null)
1853 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1856 if (!Float.isNaN(annotation.annotations[a].value))
1858 ae.setValue(annotation.annotations[a].value);
1862 if (annotation.annotations[a].secondaryStructure > ' ')
1864 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1868 if (annotation.annotations[a].colour != null
1869 && annotation.annotations[a].colour != java.awt.Color.black)
1871 ae.setColour(annotation.annotations[a].colour.getRGB());
1874 an.addAnnotationElement(ae);
1875 if (annotation.autoCalculated)
1877 // only write one non-null entry into the annotation row -
1878 // sufficient to get the visualization attributes necessary to
1886 an.setScoreOnly(true);
1888 if (!storeDS || (storeDS && !annotation.autoCalculated))
1890 // skip autocalculated annotation - these are only provided for
1892 vamsasSet.addAnnotation(an);
1898 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1900 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1901 if (settings != null)
1903 CalcIdParam vCalcIdParam = new CalcIdParam();
1904 vCalcIdParam.setCalcId(calcId);
1905 vCalcIdParam.addServiceURL(settings.getServiceURI());
1906 // generic URI allowing a third party to resolve another instance of the
1907 // service used for this calculation
1908 for (String urls : settings.getServiceURLs())
1910 vCalcIdParam.addServiceURL(urls);
1912 vCalcIdParam.setVersion("1.0");
1913 if (settings.getPreset() != null)
1915 WsParamSetI setting = settings.getPreset();
1916 vCalcIdParam.setName(setting.getName());
1917 vCalcIdParam.setDescription(setting.getDescription());
1921 vCalcIdParam.setName("");
1922 vCalcIdParam.setDescription("Last used parameters");
1924 // need to be able to recover 1) settings 2) user-defined presets or
1925 // recreate settings from preset 3) predefined settings provided by
1926 // service - or settings that can be transferred (or discarded)
1927 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1929 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1930 // todo - decide if updateImmediately is needed for any projects.
1932 return vCalcIdParam;
1937 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1940 if (calcIdParam.getVersion().equals("1.0"))
1942 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1943 .getPreferredServiceFor(calcIdParam.getServiceURL());
1944 if (service != null)
1946 WsParamSetI parmSet = null;
1949 parmSet = service.getParamStore().parseServiceParameterFile(
1950 calcIdParam.getName(), calcIdParam.getDescription(),
1951 calcIdParam.getServiceURL(),
1952 calcIdParam.getParameters().replace("|\\n|", "\n"));
1953 } catch (IOException x)
1955 warn("Couldn't parse parameter data for "
1956 + calcIdParam.getCalcId(), x);
1959 List<ArgumentI> argList = null;
1960 if (calcIdParam.getName().length() > 0)
1962 parmSet = service.getParamStore()
1963 .getPreset(calcIdParam.getName());
1964 if (parmSet != null)
1966 // TODO : check we have a good match with settings in AACon -
1967 // otherwise we'll need to create a new preset
1972 argList = parmSet.getArguments();
1975 AAConSettings settings = new AAConSettings(
1976 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1977 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1978 calcIdParam.isNeedsUpdate());
1983 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1987 throw new Error(MessageManager.formatMessage(
1988 "error.unsupported_version_calcIdparam",
1989 new Object[] { calcIdParam.toString() }));
1993 * External mapping between jalview objects and objects yielding a valid and
1994 * unique object ID string. This is null for normal Jalview project IO, but
1995 * non-null when a jalview project is being read or written as part of a
1998 IdentityHashMap jv2vobj = null;
2001 * Construct a unique ID for jvobj using either existing bindings or if none
2002 * exist, the result of the hashcode call for the object.
2005 * jalview data object
2006 * @return unique ID for referring to jvobj
2008 private String makeHashCode(Object jvobj, String altCode)
2010 if (jv2vobj != null)
2012 Object id = jv2vobj.get(jvobj);
2015 return id.toString();
2017 // check string ID mappings
2018 if (jvids2vobj != null && jvobj instanceof String)
2020 id = jvids2vobj.get(jvobj);
2024 return id.toString();
2026 // give up and warn that something has gone wrong
2027 warn("Cannot find ID for object in external mapping : " + jvobj);
2033 * return local jalview object mapped to ID, if it exists
2037 * @return null or object bound to idcode
2039 private Object retrieveExistingObj(String idcode)
2041 if (idcode != null && vobj2jv != null)
2043 return vobj2jv.get(idcode);
2049 * binding from ID strings from external mapping table to jalview data model
2052 private Hashtable vobj2jv;
2054 private Sequence createVamsasSequence(String id, SequenceI jds)
2056 return createVamsasSequence(true, id, jds, null);
2059 private Sequence createVamsasSequence(boolean recurse, String id,
2060 SequenceI jds, SequenceI parentseq)
2062 Sequence vamsasSeq = new Sequence();
2063 vamsasSeq.setId(id);
2064 vamsasSeq.setName(jds.getName());
2065 vamsasSeq.setSequence(jds.getSequenceAsString());
2066 vamsasSeq.setDescription(jds.getDescription());
2067 jalview.datamodel.DBRefEntry[] dbrefs = null;
2068 if (jds.getDatasetSequence() != null)
2070 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2074 // seqId==dsseqid so we can tell which sequences really are
2075 // dataset sequences only
2076 vamsasSeq.setDsseqid(id);
2077 dbrefs = jds.getDBRefs();
2078 if (parentseq == null)
2085 for (int d = 0; d < dbrefs.length; d++)
2087 DBRef dbref = new DBRef();
2088 dbref.setSource(dbrefs[d].getSource());
2089 dbref.setVersion(dbrefs[d].getVersion());
2090 dbref.setAccessionId(dbrefs[d].getAccessionId());
2091 if (dbrefs[d].hasMap())
2093 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2095 dbref.setMapping(mp);
2097 vamsasSeq.addDBRef(dbref);
2103 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2104 SequenceI parentseq, SequenceI jds, boolean recurse)
2107 if (jmp.getMap() != null)
2111 jalview.util.MapList mlst = jmp.getMap();
2112 List<int[]> r = mlst.getFromRanges();
2113 for (int[] range : r)
2115 MapListFrom mfrom = new MapListFrom();
2116 mfrom.setStart(range[0]);
2117 mfrom.setEnd(range[1]);
2118 mp.addMapListFrom(mfrom);
2120 r = mlst.getToRanges();
2121 for (int[] range : r)
2123 MapListTo mto = new MapListTo();
2124 mto.setStart(range[0]);
2125 mto.setEnd(range[1]);
2126 mp.addMapListTo(mto);
2128 mp.setMapFromUnit(mlst.getFromRatio());
2129 mp.setMapToUnit(mlst.getToRatio());
2130 if (jmp.getTo() != null)
2132 MappingChoice mpc = new MappingChoice();
2134 // check/create ID for the sequence referenced by getTo()
2137 SequenceI ps = null;
2138 if (parentseq != jmp.getTo()
2139 && parentseq.getDatasetSequence() != jmp.getTo())
2141 // chaining dbref rather than a handshaking one
2142 jmpid = seqHash(ps = jmp.getTo());
2146 jmpid = seqHash(ps = parentseq);
2148 mpc.setDseqFor(jmpid);
2149 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2151 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2152 seqRefIds.put(mpc.getDseqFor(), ps);
2156 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2159 mp.setMappingChoice(mpc);
2165 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2166 List<UserColourScheme> userColours, JalviewModelSequence jms)
2169 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2170 boolean newucs = false;
2171 if (!userColours.contains(ucs))
2173 userColours.add(ucs);
2176 id = "ucs" + userColours.indexOf(ucs);
2179 // actually create the scheme's entry in the XML model
2180 java.awt.Color[] colours = ucs.getColours();
2181 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2182 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2184 for (int i = 0; i < colours.length; i++)
2186 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2187 col.setName(ResidueProperties.aa[i]);
2188 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2189 jbucs.addColour(col);
2191 if (ucs.getLowerCaseColours() != null)
2193 colours = ucs.getLowerCaseColours();
2194 for (int i = 0; i < colours.length; i++)
2196 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2197 col.setName(ResidueProperties.aa[i].toLowerCase());
2198 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2199 jbucs.addColour(col);
2204 uc.setUserColourScheme(jbucs);
2205 jms.addUserColours(uc);
2211 jalview.schemes.UserColourScheme getUserColourScheme(
2212 JalviewModelSequence jms, String id)
2214 UserColours[] uc = jms.getUserColours();
2215 UserColours colours = null;
2217 for (int i = 0; i < uc.length; i++)
2219 if (uc[i].getId().equals(id))
2227 java.awt.Color[] newColours = new java.awt.Color[24];
2229 for (int i = 0; i < 24; i++)
2231 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2232 .getUserColourScheme().getColour(i).getRGB(), 16));
2235 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2238 if (colours.getUserColourScheme().getColourCount() > 24)
2240 newColours = new java.awt.Color[23];
2241 for (int i = 0; i < 23; i++)
2243 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2244 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2246 ucs.setLowerCaseColours(newColours);
2253 * contains last error message (if any) encountered by XML loader.
2255 String errorMessage = null;
2258 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2259 * exceptions are raised during project XML parsing
2261 public boolean attemptversion1parse = true;
2264 * Load a jalview project archive from a jar file
2267 * - HTTP URL or filename
2269 public AlignFrame loadJalviewAlign(final String file)
2272 jalview.gui.AlignFrame af = null;
2276 // create list to store references for any new Jmol viewers created
2277 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2278 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2279 // Workaround is to make sure caller implements the JarInputStreamProvider
2281 // so we can re-open the jar input stream for each entry.
2283 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2284 af = loadJalviewAlign(jprovider);
2286 } catch (MalformedURLException e)
2288 errorMessage = "Invalid URL format for '" + file + "'";
2294 SwingUtilities.invokeAndWait(new Runnable()
2299 setLoadingFinishedForNewStructureViewers();
2302 } catch (Exception x)
2304 System.err.println("Error loading alignment: " + x.getMessage());
2310 private jarInputStreamProvider createjarInputStreamProvider(
2311 final String file) throws MalformedURLException
2314 errorMessage = null;
2315 uniqueSetSuffix = null;
2317 viewportsAdded.clear();
2318 frefedSequence = null;
2320 if (file.startsWith("http://"))
2322 url = new URL(file);
2324 final URL _url = url;
2325 return new jarInputStreamProvider()
2329 public JarInputStream getJarInputStream() throws IOException
2333 return new JarInputStream(_url.openStream());
2337 return new JarInputStream(new FileInputStream(file));
2342 public String getFilename()
2350 * Recover jalview session from a jalview project archive. Caller may
2351 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2352 * themselves. Any null fields will be initialised with default values,
2353 * non-null fields are left alone.
2358 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2360 errorMessage = null;
2361 if (uniqueSetSuffix == null)
2363 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2365 if (seqRefIds == null)
2369 AlignFrame af = null, _af = null;
2370 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2371 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2372 final String file = jprovider.getFilename();
2375 JarInputStream jin = null;
2376 JarEntry jarentry = null;
2381 jin = jprovider.getJarInputStream();
2382 for (int i = 0; i < entryCount; i++)
2384 jarentry = jin.getNextJarEntry();
2387 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2389 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2390 JalviewModel object = new JalviewModel();
2392 Unmarshaller unmar = new Unmarshaller(object);
2393 unmar.setValidation(false);
2394 object = (JalviewModel) unmar.unmarshal(in);
2395 if (true) // !skipViewport(object))
2397 _af = loadFromObject(object, file, true, jprovider);
2399 && object.getJalviewModelSequence().getViewportCount() > 0)
2403 // store a reference to the first view
2406 if (_af.viewport.isGatherViewsHere())
2408 // if this is a gathered view, keep its reference since
2409 // after gathering views, only this frame will remain
2411 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2413 // Save dataset to register mappings once all resolved
2414 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2415 af.viewport.getAlignment().getDataset());
2420 else if (jarentry != null)
2422 // Some other file here.
2425 } while (jarentry != null);
2426 resolveFrefedSequences();
2427 } catch (IOException ex)
2429 ex.printStackTrace();
2430 errorMessage = "Couldn't locate Jalview XML file : " + file;
2431 System.err.println("Exception whilst loading jalview XML file : "
2433 } catch (Exception ex)
2435 System.err.println("Parsing as Jalview Version 2 file failed.");
2436 ex.printStackTrace(System.err);
2437 if (attemptversion1parse)
2439 // Is Version 1 Jar file?
2442 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2443 } catch (Exception ex2)
2445 System.err.println("Exception whilst loading as jalviewXMLV1:");
2446 ex2.printStackTrace();
2450 if (Desktop.instance != null)
2452 Desktop.instance.stopLoading();
2456 System.out.println("Successfully loaded archive file");
2459 ex.printStackTrace();
2461 System.err.println("Exception whilst loading jalview XML file : "
2463 } catch (OutOfMemoryError e)
2465 // Don't use the OOM Window here
2466 errorMessage = "Out of memory loading jalview XML file";
2467 System.err.println("Out of memory whilst loading jalview XML file");
2468 e.printStackTrace();
2472 * Regather multiple views (with the same sequence set id) to the frame (if
2473 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2474 * views instead of separate frames. Note this doesn't restore a state where
2475 * some expanded views in turn have tabbed views - the last "first tab" read
2476 * in will play the role of gatherer for all.
2478 for (AlignFrame fr : gatherToThisFrame.values())
2480 Desktop.instance.gatherViews(fr);
2483 restoreSplitFrames();
2484 for (AlignmentI ds : importedDatasets.keySet())
2486 if (ds.getCodonFrames() != null)
2488 StructureSelectionManager.getStructureSelectionManager(
2489 Desktop.instance).registerMappings(ds.getCodonFrames());
2492 if (errorMessage != null)
2497 if (Desktop.instance != null)
2499 Desktop.instance.stopLoading();
2506 * Try to reconstruct and display SplitFrame windows, where each contains
2507 * complementary dna and protein alignments. Done by pairing up AlignFrame
2508 * objects (created earlier) which have complementary viewport ids associated.
2510 protected void restoreSplitFrames()
2512 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2513 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2514 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2517 * Identify the DNA alignments
2519 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2522 AlignFrame af = candidate.getValue();
2523 if (af.getViewport().getAlignment().isNucleotide())
2525 dna.put(candidate.getKey().getId(), af);
2530 * Try to match up the protein complements
2532 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2535 AlignFrame af = candidate.getValue();
2536 if (!af.getViewport().getAlignment().isNucleotide())
2538 String complementId = candidate.getKey().getComplementId();
2539 // only non-null complements should be in the Map
2540 if (complementId != null && dna.containsKey(complementId))
2542 final AlignFrame dnaFrame = dna.get(complementId);
2543 SplitFrame sf = createSplitFrame(dnaFrame, af);
2544 addedToSplitFrames.add(dnaFrame);
2545 addedToSplitFrames.add(af);
2546 dnaFrame.setMenusForViewport();
2547 af.setMenusForViewport();
2548 if (af.viewport.isGatherViewsHere())
2557 * Open any that we failed to pair up (which shouldn't happen!) as
2558 * standalone AlignFrame's.
2560 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2563 AlignFrame af = candidate.getValue();
2564 if (!addedToSplitFrames.contains(af))
2566 Viewport view = candidate.getKey();
2567 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2569 af.setMenusForViewport();
2570 System.err.println("Failed to restore view " + view.getTitle()
2571 + " to split frame");
2576 * Gather back into tabbed views as flagged.
2578 for (SplitFrame sf : gatherTo)
2580 Desktop.instance.gatherViews(sf);
2583 splitFrameCandidates.clear();
2587 * Construct and display one SplitFrame holding DNA and protein alignments.
2590 * @param proteinFrame
2593 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2594 AlignFrame proteinFrame)
2596 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2597 String title = MessageManager.getString("label.linked_view_title");
2598 int width = (int) dnaFrame.getBounds().getWidth();
2599 int height = (int) (dnaFrame.getBounds().getHeight()
2600 + proteinFrame.getBounds().getHeight() + 50);
2603 * SplitFrame location is saved to both enclosed frames
2605 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2606 Desktop.addInternalFrame(splitFrame, title, width, height);
2609 * And compute cDNA consensus (couldn't do earlier with consensus as
2610 * mappings were not yet present)
2612 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2618 * check errorMessage for a valid error message and raise an error box in the
2619 * GUI or write the current errorMessage to stderr and then clear the error
2622 protected void reportErrors()
2624 reportErrors(false);
2627 protected void reportErrors(final boolean saving)
2629 if (errorMessage != null)
2631 final String finalErrorMessage = errorMessage;
2634 javax.swing.SwingUtilities.invokeLater(new Runnable()
2639 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2640 finalErrorMessage, "Error "
2641 + (saving ? "saving" : "loading")
2642 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2648 System.err.println("Problem loading Jalview file: " + errorMessage);
2651 errorMessage = null;
2654 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2657 * when set, local views will be updated from view stored in JalviewXML
2658 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2659 * sync if this is set to true.
2661 private final boolean updateLocalViews = false;
2664 * Returns the path to a temporary file holding the PDB file for the given PDB
2665 * id. The first time of asking, searches for a file of that name in the
2666 * Jalview project jar, and copies it to a new temporary file. Any repeat
2667 * requests just return the path to the file previously created.
2673 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2676 if (alreadyLoadedPDB.containsKey(pdbId))
2678 return alreadyLoadedPDB.get(pdbId).toString();
2681 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2683 if (tempFile != null)
2685 alreadyLoadedPDB.put(pdbId, tempFile);
2691 * Copies the jar entry of given name to a new temporary file and returns the
2692 * path to the file, or null if the entry is not found.
2695 * @param jarEntryName
2697 * a prefix for the temporary file name, must be at least three
2700 * null or original file - so new file can be given the same suffix
2704 protected String copyJarEntry(jarInputStreamProvider jprovider,
2705 String jarEntryName, String prefix, String origFile)
2707 BufferedReader in = null;
2708 PrintWriter out = null;
2709 String suffix = ".tmp";
2710 if (origFile == null)
2712 origFile = jarEntryName;
2714 int sfpos = origFile.lastIndexOf(".");
2715 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2717 suffix = "." + origFile.substring(sfpos + 1);
2721 JarInputStream jin = jprovider.getJarInputStream();
2723 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2724 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2725 * FileInputStream(jprovider)); }
2728 JarEntry entry = null;
2731 entry = jin.getNextJarEntry();
2732 } while (entry != null && !entry.getName().equals(jarEntryName));
2735 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2736 File outFile = File.createTempFile(prefix, suffix);
2737 outFile.deleteOnExit();
2738 out = new PrintWriter(new FileOutputStream(outFile));
2741 while ((data = in.readLine()) != null)
2746 String t = outFile.getAbsolutePath();
2751 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2753 } catch (Exception ex)
2755 ex.printStackTrace();
2763 } catch (IOException e)
2777 private class JvAnnotRow
2779 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2786 * persisted version of annotation row from which to take vis properties
2788 public jalview.datamodel.AlignmentAnnotation template;
2791 * original position of the annotation row in the alignment
2797 * Load alignment frame from jalview XML DOM object
2802 * filename source string
2803 * @param loadTreesAndStructures
2804 * when false only create Viewport
2806 * data source provider
2807 * @return alignment frame created from view stored in DOM
2809 AlignFrame loadFromObject(JalviewModel object, String file,
2810 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2812 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2813 Sequence[] vamsasSeq = vamsasSet.getSequence();
2815 JalviewModelSequence jms = object.getJalviewModelSequence();
2817 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2820 // ////////////////////////////////
2823 List<SequenceI> hiddenSeqs = null;
2825 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2827 boolean multipleView = false;
2828 SequenceI referenceseqForView = null;
2829 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2830 int vi = 0; // counter in vamsasSeq array
2831 for (int i = 0; i < jseqs.length; i++)
2833 String seqId = jseqs[i].getId();
2835 SequenceI tmpSeq = seqRefIds.get(seqId);
2838 if (!incompleteSeqs.containsKey(seqId))
2840 // may not need this check, but keep it for at least 2.9,1 release
2841 if (tmpSeq.getStart() != jseqs[i].getStart()
2842 || tmpSeq.getEnd() != jseqs[i].getEnd())
2845 .println("Warning JAL-2154 regression: updating start/end for sequence "
2846 + tmpSeq.toString() + " to " + jseqs[i]);
2851 incompleteSeqs.remove(seqId);
2853 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2855 // most likely we are reading a dataset XML document so
2856 // update from vamsasSeq section of XML for this sequence
2857 tmpSeq.setName(vamsasSeq[vi].getName());
2858 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2859 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2864 // reading multiple views, so vamsasSeq set is a subset of JSeq
2865 multipleView = true;
2867 tmpSeq.setStart(jseqs[i].getStart());
2868 tmpSeq.setEnd(jseqs[i].getEnd());
2869 tmpseqs.add(tmpSeq);
2873 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2874 vamsasSeq[vi].getSequence());
2875 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2876 tmpSeq.setStart(jseqs[i].getStart());
2877 tmpSeq.setEnd(jseqs[i].getEnd());
2878 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2879 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2880 tmpseqs.add(tmpSeq);
2884 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2886 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2889 if (jseqs[i].getHidden())
2891 if (hiddenSeqs == null)
2893 hiddenSeqs = new ArrayList<SequenceI>();
2896 hiddenSeqs.add(tmpSeq);
2901 // Create the alignment object from the sequence set
2902 // ///////////////////////////////
2903 SequenceI[] orderedSeqs = tmpseqs
2904 .toArray(new SequenceI[tmpseqs.size()]);
2906 AlignmentI al = null;
2907 // so we must create or recover the dataset alignment before going further
2908 // ///////////////////////////////
2909 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2911 // older jalview projects do not have a dataset - so creat alignment and
2913 al = new Alignment(orderedSeqs);
2914 al.setDataset(null);
2918 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2921 // we are importing a dataset record, so
2922 // recover reference to an alignment already materialsed as dataset
2923 al = getDatasetFor(vamsasSet.getDatasetId());
2927 // materialse the alignment
2928 al = new Alignment(orderedSeqs);
2932 addDatasetRef(vamsasSet.getDatasetId(), al);
2935 // finally, verify all data in vamsasSet is actually present in al
2936 // passing on flag indicating if it is actually a stored dataset
2937 recoverDatasetFor(vamsasSet, al, isdsal);
2940 if (referenceseqForView != null)
2942 al.setSeqrep(referenceseqForView);
2944 // / Add the alignment properties
2945 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2947 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2948 al.setProperty(ssp.getKey(), ssp.getValue());
2951 // ///////////////////////////////
2953 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2956 // load sequence features, database references and any associated PDB
2957 // structures for the alignment
2959 // prior to 2.10, this part would only be executed the first time a
2960 // sequence was encountered, but not afterwards.
2961 // now, for 2.10 projects, this is also done if the xml doc includes
2962 // dataset sequences not actually present in any particular view.
2964 for (int i = 0; i < vamsasSeq.length; i++)
2966 if (jseqs[i].getFeaturesCount() > 0)
2968 Features[] features = jseqs[i].getFeatures();
2969 for (int f = 0; f < features.length; f++)
2971 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2972 features[f].getType(), features[f].getDescription(),
2973 features[f].getStatus(), features[f].getBegin(),
2974 features[f].getEnd(), features[f].getFeatureGroup());
2976 sf.setScore(features[f].getScore());
2977 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2979 OtherData keyValue = features[f].getOtherData(od);
2980 if (keyValue.getKey().startsWith("LINK"))
2982 sf.addLink(keyValue.getValue());
2986 sf.setValue(keyValue.getKey(), keyValue.getValue());
2990 // adds feature to datasequence's feature set (since Jalview 2.10)
2991 al.getSequenceAt(i).addSequenceFeature(sf);
2994 if (vamsasSeq[i].getDBRefCount() > 0)
2996 // adds dbrefs to datasequence's set (since Jalview 2.10)
2998 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
2999 : al.getSequenceAt(i).getDatasetSequence(),
3002 if (jseqs[i].getPdbidsCount() > 0)
3004 Pdbids[] ids = jseqs[i].getPdbids();
3005 for (int p = 0; p < ids.length; p++)
3007 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
3008 entry.setId(ids[p].getId());
3009 if (ids[p].getType() != null)
3011 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3013 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3017 entry.setType(PDBEntry.Type.FILE);
3020 if (ids[p].getFile() != null)
3022 if (!pdbloaded.containsKey(ids[p].getFile()))
3024 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3029 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3032 if (ids[p].getPdbentryItem() != null)
3034 for (PdbentryItem item : ids[p].getPdbentryItem())
3036 for (Property pr : item.getProperty())
3038 entry.setProperty(pr.getName(), pr.getValue());
3042 StructureSelectionManager.getStructureSelectionManager(
3043 Desktop.instance).registerPDBEntry(entry);
3044 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3045 if (al.getSequenceAt(i).getDatasetSequence() != null)
3047 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3051 al.getSequenceAt(i).addPDBId(entry);
3056 } // end !multipleview
3058 // ///////////////////////////////
3059 // LOAD SEQUENCE MAPPINGS
3061 if (vamsasSet.getAlcodonFrameCount() > 0)
3063 // TODO Potentially this should only be done once for all views of an
3065 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3066 for (int i = 0; i < alc.length; i++)
3068 AlignedCodonFrame cf = new AlignedCodonFrame();
3069 if (alc[i].getAlcodMapCount() > 0)
3071 AlcodMap[] maps = alc[i].getAlcodMap();
3072 for (int m = 0; m < maps.length; m++)
3074 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3076 jalview.datamodel.Mapping mapping = null;
3077 // attach to dna sequence reference.
3078 if (maps[m].getMapping() != null)
3080 mapping = addMapping(maps[m].getMapping());
3081 if (dnaseq != null && mapping.getTo() != null)
3083 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3088 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3093 al.addCodonFrame(cf);
3098 // ////////////////////////////////
3100 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3103 * store any annotations which forward reference a group's ID
3105 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3107 if (vamsasSet.getAnnotationCount() > 0)
3109 Annotation[] an = vamsasSet.getAnnotation();
3111 for (int i = 0; i < an.length; i++)
3113 Annotation annotation = an[i];
3116 * test if annotation is automatically calculated for this view only
3118 boolean autoForView = false;
3119 if (annotation.getLabel().equals("Quality")
3120 || annotation.getLabel().equals("Conservation")
3121 || annotation.getLabel().equals("Consensus"))
3123 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3125 if (!annotation.hasAutoCalculated())
3127 annotation.setAutoCalculated(true);
3131 || (annotation.hasAutoCalculated() && annotation
3132 .isAutoCalculated()))
3134 // remove ID - we don't recover annotation from other views for
3135 // view-specific annotation
3136 annotation.setId(null);
3139 // set visiblity for other annotation in this view
3140 String annotationId = annotation.getId();
3141 if (annotationId != null && annotationIds.containsKey(annotationId))
3143 AlignmentAnnotation jda = annotationIds.get(annotationId);
3144 // in principle Visible should always be true for annotation displayed
3145 // in multiple views
3146 if (annotation.hasVisible())
3148 jda.visible = annotation.getVisible();
3151 al.addAnnotation(jda);
3155 // Construct new annotation from model.
3156 AnnotationElement[] ae = annotation.getAnnotationElement();
3157 jalview.datamodel.Annotation[] anot = null;
3158 java.awt.Color firstColour = null;
3160 if (!annotation.getScoreOnly())
3162 anot = new jalview.datamodel.Annotation[al.getWidth()];
3163 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3165 anpos = ae[aa].getPosition();
3167 if (anpos >= anot.length)
3172 anot[anpos] = new jalview.datamodel.Annotation(
3174 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3175 (ae[aa].getSecondaryStructure() == null || ae[aa]
3176 .getSecondaryStructure().length() == 0) ? ' '
3177 : ae[aa].getSecondaryStructure().charAt(0),
3181 // JBPNote: Consider verifying dataflow for IO of secondary
3182 // structure annotation read from Stockholm files
3183 // this was added to try to ensure that
3184 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3186 // anot[ae[aa].getPosition()].displayCharacter = "";
3188 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3189 if (firstColour == null)
3191 firstColour = anot[anpos].colour;
3195 jalview.datamodel.AlignmentAnnotation jaa = null;
3197 if (annotation.getGraph())
3199 float llim = 0, hlim = 0;
3200 // if (autoForView || an[i].isAutoCalculated()) {
3203 jaa = new jalview.datamodel.AlignmentAnnotation(
3204 annotation.getLabel(), annotation.getDescription(), anot,
3205 llim, hlim, annotation.getGraphType());
3207 jaa.graphGroup = annotation.getGraphGroup();
3208 jaa._linecolour = firstColour;
3209 if (annotation.getThresholdLine() != null)
3211 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3212 .getThresholdLine().getValue(), annotation
3213 .getThresholdLine().getLabel(), new java.awt.Color(
3214 annotation.getThresholdLine().getColour())));
3217 if (autoForView || annotation.isAutoCalculated())
3219 // Hardwire the symbol display line to ensure that labels for
3220 // histograms are displayed
3226 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3227 an[i].getDescription(), anot);
3228 jaa._linecolour = firstColour;
3230 // register new annotation
3231 if (an[i].getId() != null)
3233 annotationIds.put(an[i].getId(), jaa);
3234 jaa.annotationId = an[i].getId();
3236 // recover sequence association
3237 String sequenceRef = an[i].getSequenceRef();
3238 if (sequenceRef != null)
3240 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3241 SequenceI sequence = seqRefIds.get(sequenceRef);
3242 if (sequence == null)
3244 // in pre-2.9 projects sequence ref is to sequence name
3245 sequence = al.findName(sequenceRef);
3247 if (sequence != null)
3249 jaa.createSequenceMapping(sequence, 1, true);
3250 sequence.addAlignmentAnnotation(jaa);
3253 // and make a note of any group association
3254 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3256 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3257 .get(an[i].getGroupRef());
3260 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3261 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3266 if (an[i].hasScore())
3268 jaa.setScore(an[i].getScore());
3270 if (an[i].hasVisible())
3272 jaa.visible = an[i].getVisible();
3275 if (an[i].hasCentreColLabels())
3277 jaa.centreColLabels = an[i].getCentreColLabels();
3280 if (an[i].hasScaleColLabels())
3282 jaa.scaleColLabel = an[i].getScaleColLabels();
3284 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3286 // newer files have an 'autoCalculated' flag and store calculation
3287 // state in viewport properties
3288 jaa.autoCalculated = true; // means annotation will be marked for
3289 // update at end of load.
3291 if (an[i].hasGraphHeight())
3293 jaa.graphHeight = an[i].getGraphHeight();
3295 if (an[i].hasBelowAlignment())
3297 jaa.belowAlignment = an[i].isBelowAlignment();
3299 jaa.setCalcId(an[i].getCalcId());
3300 if (an[i].getPropertyCount() > 0)
3302 for (jalview.schemabinding.version2.Property prop : an[i]
3305 jaa.setProperty(prop.getName(), prop.getValue());
3308 if (jaa.autoCalculated)
3310 autoAlan.add(new JvAnnotRow(i, jaa));
3313 // if (!autoForView)
3315 // add autocalculated group annotation and any user created annotation
3317 al.addAnnotation(jaa);
3321 // ///////////////////////
3323 // Create alignment markup and styles for this view
3324 if (jms.getJGroupCount() > 0)
3326 JGroup[] groups = jms.getJGroup();
3327 boolean addAnnotSchemeGroup = false;
3328 for (int i = 0; i < groups.length; i++)
3330 JGroup jGroup = groups[i];
3331 ColourSchemeI cs = null;
3332 if (jGroup.getColour() != null)
3334 if (jGroup.getColour().startsWith("ucs"))
3336 cs = getUserColourScheme(jms, jGroup.getColour());
3338 else if (jGroup.getColour().equals("AnnotationColourGradient")
3339 && jGroup.getAnnotationColours() != null)
3341 addAnnotSchemeGroup = true;
3346 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3351 cs.setThreshold(jGroup.getPidThreshold(), true);
3355 Vector<SequenceI> seqs = new Vector<SequenceI>();
3357 for (int s = 0; s < jGroup.getSeqCount(); s++)
3359 String seqId = jGroup.getSeq(s) + "";
3360 SequenceI ts = seqRefIds.get(seqId);
3364 seqs.addElement(ts);
3368 if (seqs.size() < 1)
3373 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3374 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3375 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3377 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3379 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3380 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3381 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3382 .isShowUnconserved() : false);
3383 sg.thresholdTextColour = jGroup.getTextColThreshold();
3384 if (jGroup.hasShowConsensusHistogram())
3386 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3389 if (jGroup.hasShowSequenceLogo())
3391 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3393 if (jGroup.hasNormaliseSequenceLogo())
3395 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3397 if (jGroup.hasIgnoreGapsinConsensus())
3399 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3401 if (jGroup.getConsThreshold() != 0)
3403 Conservation c = new Conservation("All", 3,
3404 sg.getSequences(null), 0, sg.getWidth() - 1);
3406 c.verdict(false, 25);
3407 sg.cs.setConservation(c);
3410 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3412 // re-instate unique group/annotation row reference
3413 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3417 for (AlignmentAnnotation jaa : jaal)
3420 if (jaa.autoCalculated)
3422 // match up and try to set group autocalc alignment row for this
3424 if (jaa.label.startsWith("Consensus for "))
3426 sg.setConsensus(jaa);
3428 // match up and try to set group autocalc alignment row for this
3430 if (jaa.label.startsWith("Conservation for "))
3432 sg.setConservationRow(jaa);
3439 if (addAnnotSchemeGroup)
3441 // reconstruct the annotation colourscheme
3442 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3443 null, al, jms, false);
3449 // only dataset in this model, so just return.
3452 // ///////////////////////////////
3455 // If we just load in the same jar file again, the sequenceSetId
3456 // will be the same, and we end up with multiple references
3457 // to the same sequenceSet. We must modify this id on load
3458 // so that each load of the file gives a unique id
3459 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3460 String viewId = (view.getId() == null ? null : view.getId()
3462 AlignFrame af = null;
3463 AlignViewport av = null;
3464 // now check to see if we really need to create a new viewport.
3465 if (multipleView && viewportsAdded.size() == 0)
3467 // We recovered an alignment for which a viewport already exists.
3468 // TODO: fix up any settings necessary for overlaying stored state onto
3469 // state recovered from another document. (may not be necessary).
3470 // we may need a binding from a viewport in memory to one recovered from
3472 // and then recover its containing af to allow the settings to be applied.
3473 // TODO: fix for vamsas demo
3475 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3477 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3478 if (seqsetobj != null)
3480 if (seqsetobj instanceof String)
3482 uniqueSeqSetId = (String) seqsetobj;
3484 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3490 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3496 * indicate that annotation colours are applied across all groups (pre
3497 * Jalview 2.8.1 behaviour)
3499 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3500 "2.8.1", object.getVersion());
3502 AlignmentPanel ap = null;
3503 boolean isnewview = true;
3506 // Check to see if this alignment already has a view id == viewId
3507 jalview.gui.AlignmentPanel views[] = Desktop
3508 .getAlignmentPanels(uniqueSeqSetId);
3509 if (views != null && views.length > 0)
3511 for (int v = 0; v < views.length; v++)
3513 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3515 // recover the existing alignpanel, alignframe, viewport
3516 af = views[v].alignFrame;
3519 // TODO: could even skip resetting view settings if we don't want to
3520 // change the local settings from other jalview processes
3529 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3530 uniqueSeqSetId, viewId, autoAlan);
3536 * Load any trees, PDB structures and viewers
3538 * Not done if flag is false (when this method is used for New View)
3540 if (loadTreesAndStructures)
3542 loadTrees(jms, view, af, av, ap);
3543 loadPDBStructures(jprovider, jseqs, af, ap);
3544 loadRnaViewers(jprovider, jseqs, ap);
3546 // and finally return.
3551 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3552 * panel is restored from separate jar entries, two (gapped and trimmed) per
3553 * sequence and secondary structure.
3555 * Currently each viewer shows just one sequence and structure (gapped and
3556 * trimmed), however this method is designed to support multiple sequences or
3557 * structures in viewers if wanted in future.
3563 private void loadRnaViewers(jarInputStreamProvider jprovider,
3564 JSeq[] jseqs, AlignmentPanel ap)
3567 * scan the sequences for references to viewers; create each one the first
3568 * time it is referenced, add Rna models to existing viewers
3570 for (JSeq jseq : jseqs)
3572 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3574 RnaViewer viewer = jseq.getRnaViewer(i);
3575 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3576 uniqueSetSuffix, ap);
3578 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3580 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3581 SequenceI seq = seqRefIds.get(jseq.getId());
3582 AlignmentAnnotation ann = this.annotationIds.get(ss
3583 .getAnnotationId());
3586 * add the structure to the Varna display (with session state copied
3587 * from the jar to a temporary file)
3589 boolean gapped = ss.isGapped();
3590 String rnaTitle = ss.getTitle();
3591 String sessionState = ss.getViewerState();
3592 String tempStateFile = copyJarEntry(jprovider, sessionState,
3594 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3595 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3597 appVarna.setInitialSelection(viewer.getSelectedRna());
3603 * Locate and return an already instantiated matching AppVarna, or create one
3607 * @param viewIdSuffix
3611 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3612 String viewIdSuffix, AlignmentPanel ap)
3615 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3616 * if load is repeated
3618 String postLoadId = viewer.getViewId() + viewIdSuffix;
3619 for (JInternalFrame frame : getAllFrames())
3621 if (frame instanceof AppVarna)
3623 AppVarna varna = (AppVarna) frame;
3624 if (postLoadId.equals(varna.getViewId()))
3626 // this viewer is already instantiated
3627 // could in future here add ap as another 'parent' of the
3628 // AppVarna window; currently just 1-to-many
3635 * viewer not found - make it
3637 RnaViewerModel model = new RnaViewerModel(postLoadId,
3638 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3639 viewer.getWidth(), viewer.getHeight(),
3640 viewer.getDividerLocation());
3641 AppVarna varna = new AppVarna(model, ap);
3647 * Load any saved trees
3655 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3656 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3658 // TODO result of automated refactoring - are all these parameters needed?
3661 for (int t = 0; t < jms.getTreeCount(); t++)
3664 Tree tree = jms.getTree(t);
3666 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3669 tp = af.ShowNewickTree(
3670 new jalview.io.NewickFile(tree.getNewick()),
3671 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3672 tree.getXpos(), tree.getYpos());
3673 if (tree.getId() != null)
3675 // perhaps bind the tree id to something ?
3680 // update local tree attributes ?
3681 // TODO: should check if tp has been manipulated by user - if so its
3682 // settings shouldn't be modified
3683 tp.setTitle(tree.getTitle());
3684 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3685 .getWidth(), tree.getHeight()));
3686 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3689 tp.treeCanvas.av = av; // af.viewport;
3690 tp.treeCanvas.ap = ap; // af.alignPanel;
3695 warn("There was a problem recovering stored Newick tree: \n"
3696 + tree.getNewick());
3700 tp.fitToWindow.setState(tree.getFitToWindow());
3701 tp.fitToWindow_actionPerformed(null);
3703 if (tree.getFontName() != null)
3705 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3706 .getFontStyle(), tree.getFontSize()));
3710 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3711 .getFontStyle(), tree.getFontSize()));
3714 tp.showPlaceholders(tree.getMarkUnlinked());
3715 tp.showBootstrap(tree.getShowBootstrap());
3716 tp.showDistances(tree.getShowDistances());
3718 tp.treeCanvas.threshold = tree.getThreshold();
3720 if (tree.getCurrentTree())
3722 af.viewport.setCurrentTree(tp.getTree());
3726 } catch (Exception ex)
3728 ex.printStackTrace();
3733 * Load and link any saved structure viewers.
3740 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3741 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3744 * Run through all PDB ids on the alignment, and collect mappings between
3745 * distinct view ids and all sequences referring to that view.
3747 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3749 for (int i = 0; i < jseqs.length; i++)
3751 if (jseqs[i].getPdbidsCount() > 0)
3753 Pdbids[] ids = jseqs[i].getPdbids();
3754 for (int p = 0; p < ids.length; p++)
3756 final int structureStateCount = ids[p].getStructureStateCount();
3757 for (int s = 0; s < structureStateCount; s++)
3759 // check to see if we haven't already created this structure view
3760 final StructureState structureState = ids[p]
3761 .getStructureState(s);
3762 String sviewid = (structureState.getViewId() == null) ? null
3763 : structureState.getViewId() + uniqueSetSuffix;
3764 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3765 // Originally : ids[p].getFile()
3766 // : TODO: verify external PDB file recovery still works in normal
3767 // jalview project load
3768 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3770 jpdb.setId(ids[p].getId());
3772 int x = structureState.getXpos();
3773 int y = structureState.getYpos();
3774 int width = structureState.getWidth();
3775 int height = structureState.getHeight();
3777 // Probably don't need to do this anymore...
3778 // Desktop.desktop.getComponentAt(x, y);
3779 // TODO: NOW: check that this recovers the PDB file correctly.
3780 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3782 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3784 if (sviewid == null)
3786 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3789 if (!structureViewers.containsKey(sviewid))
3791 structureViewers.put(sviewid,
3792 new StructureViewerModel(x, y, width, height, false,
3793 false, true, structureState.getViewId(),
3794 structureState.getType()));
3795 // Legacy pre-2.7 conversion JAL-823 :
3796 // do not assume any view has to be linked for colour by
3800 // assemble String[] { pdb files }, String[] { id for each
3801 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3802 // seqs_file 2}, boolean[] {
3803 // linkAlignPanel,superposeWithAlignpanel}} from hash
3804 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3805 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3806 | (structureState.hasAlignwithAlignPanel() ? structureState
3807 .getAlignwithAlignPanel() : false));
3810 * Default colour by linked panel to false if not specified (e.g.
3811 * for pre-2.7 projects)
3813 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3814 colourWithAlignPanel |= (structureState
3815 .hasColourwithAlignPanel() ? structureState
3816 .getColourwithAlignPanel() : false);
3817 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3820 * Default colour by viewer to true if not specified (e.g. for
3823 boolean colourByViewer = jmoldat.isColourByViewer();
3824 colourByViewer &= structureState.hasColourByJmol() ? structureState
3825 .getColourByJmol() : true;
3826 jmoldat.setColourByViewer(colourByViewer);
3828 if (jmoldat.getStateData().length() < structureState
3829 .getContent().length())
3832 jmoldat.setStateData(structureState.getContent());
3835 if (ids[p].getFile() != null)
3837 File mapkey = new File(ids[p].getFile());
3838 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3839 if (seqstrmaps == null)
3841 jmoldat.getFileData().put(
3843 seqstrmaps = jmoldat.new StructureData(pdbFile,
3846 if (!seqstrmaps.getSeqList().contains(seq))
3848 seqstrmaps.getSeqList().add(seq);
3854 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");
3861 // Instantiate the associated structure views
3862 for (Entry<String, StructureViewerModel> entry : structureViewers
3867 createOrLinkStructureViewer(entry, af, ap, jprovider);
3868 } catch (Exception e)
3870 System.err.println("Error loading structure viewer: "
3872 // failed - try the next one
3884 protected void createOrLinkStructureViewer(
3885 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3886 AlignmentPanel ap, jarInputStreamProvider jprovider)
3888 final StructureViewerModel stateData = viewerData.getValue();
3891 * Search for any viewer windows already open from other alignment views
3892 * that exactly match the stored structure state
3894 StructureViewerBase comp = findMatchingViewer(viewerData);
3898 linkStructureViewer(ap, comp, stateData);
3903 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3904 * "viewer_"+stateData.viewId
3906 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3908 createChimeraViewer(viewerData, af, jprovider);
3913 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3915 createJmolViewer(viewerData, af, jprovider);
3920 * Create a new Chimera viewer.
3926 protected void createChimeraViewer(
3927 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3928 jarInputStreamProvider jprovider)
3930 StructureViewerModel data = viewerData.getValue();
3931 String chimeraSessionFile = data.getStateData();
3934 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3936 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3937 * 'uniquified' sviewid used to reconstruct the viewer here
3939 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3940 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3943 Set<Entry<File, StructureData>> fileData = data.getFileData()
3945 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3946 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3947 for (Entry<File, StructureData> pdb : fileData)
3949 String filePath = pdb.getValue().getFilePath();
3950 String pdbId = pdb.getValue().getPdbId();
3951 // pdbs.add(new PDBEntry(filePath, pdbId));
3952 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3953 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3954 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3958 boolean colourByChimera = data.isColourByViewer();
3959 boolean colourBySequence = data.isColourWithAlignPanel();
3961 // TODO use StructureViewer as a factory here, see JAL-1761
3962 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3963 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3965 String newViewId = viewerData.getKey();
3967 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3968 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3969 colourBySequence, newViewId);
3970 cvf.setSize(data.getWidth(), data.getHeight());
3971 cvf.setLocation(data.getX(), data.getY());
3975 * Create a new Jmol window. First parse the Jmol state to translate filenames
3976 * loaded into the view, and record the order in which files are shown in the
3977 * Jmol view, so we can add the sequence mappings in same order.
3983 protected void createJmolViewer(
3984 final Entry<String, StructureViewerModel> viewerData,
3985 AlignFrame af, jarInputStreamProvider jprovider)
3987 final StructureViewerModel svattrib = viewerData.getValue();
3988 String state = svattrib.getStateData();
3991 * Pre-2.9: state element value is the Jmol state string
3993 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3996 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3998 state = readJarEntry(jprovider,
3999 getViewerJarEntryName(svattrib.getViewId()));
4002 List<String> pdbfilenames = new ArrayList<String>();
4003 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
4004 List<String> pdbids = new ArrayList<String>();
4005 StringBuilder newFileLoc = new StringBuilder(64);
4006 int cp = 0, ncp, ecp;
4007 Map<File, StructureData> oldFiles = svattrib.getFileData();
4008 while ((ncp = state.indexOf("load ", cp)) > -1)
4012 // look for next filename in load statement
4013 newFileLoc.append(state.substring(cp,
4014 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4015 String oldfilenam = state.substring(ncp,
4016 ecp = state.indexOf("\"", ncp));
4017 // recover the new mapping data for this old filename
4018 // have to normalize filename - since Jmol and jalview do
4020 // translation differently.
4021 StructureData filedat = oldFiles.get(new File(oldfilenam));
4022 if (filedat == null)
4024 String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
4025 filedat = oldFiles.get(new File(reformatedOldFilename));
4027 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4028 pdbfilenames.add(filedat.getFilePath());
4029 pdbids.add(filedat.getPdbId());
4030 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4031 newFileLoc.append("\"");
4032 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4033 // look for next file statement.
4034 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4038 // just append rest of state
4039 newFileLoc.append(state.substring(cp));
4043 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4044 newFileLoc = new StringBuilder(state);
4045 newFileLoc.append("; load append ");
4046 for (File id : oldFiles.keySet())
4048 // add this and any other pdb files that should be present in
4050 StructureData filedat = oldFiles.get(id);
4051 newFileLoc.append(filedat.getFilePath());
4052 pdbfilenames.add(filedat.getFilePath());
4053 pdbids.add(filedat.getPdbId());
4054 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4055 newFileLoc.append(" \"");
4056 newFileLoc.append(filedat.getFilePath());
4057 newFileLoc.append("\"");
4060 newFileLoc.append(";");
4063 if (newFileLoc.length() == 0)
4067 int histbug = newFileLoc.indexOf("history = ");
4071 * change "history = [true|false];" to "history = [1|0];"
4074 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4075 String val = (diff == -1) ? null : newFileLoc
4076 .substring(histbug, diff);
4077 if (val != null && val.length() >= 4)
4079 if (val.contains("e")) // eh? what can it be?
4081 if (val.trim().equals("true"))
4089 newFileLoc.replace(histbug, diff, val);
4094 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4096 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4097 final SequenceI[][] sq = seqmaps
4098 .toArray(new SequenceI[seqmaps.size()][]);
4099 final String fileloc = newFileLoc.toString();
4100 final String sviewid = viewerData.getKey();
4101 final AlignFrame alf = af;
4102 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4103 svattrib.getWidth(), svattrib.getHeight());
4106 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4111 JalviewStructureDisplayI sview = null;
4114 sview = new StructureViewer(alf.alignPanel
4115 .getStructureSelectionManager()).createView(
4116 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4117 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4118 addNewStructureViewer(sview);
4119 } catch (OutOfMemoryError ex)
4121 new OOMWarning("restoring structure view for PDB id " + id,
4122 (OutOfMemoryError) ex.getCause());
4123 if (sview != null && sview.isVisible())
4125 sview.closeViewer(false);
4126 sview.setVisible(false);
4132 } catch (InvocationTargetException ex)
4134 warn("Unexpected error when opening Jmol view.", ex);
4136 } catch (InterruptedException e)
4138 // e.printStackTrace();
4144 * Generates a name for the entry in the project jar file to hold state
4145 * information for a structure viewer
4150 protected String getViewerJarEntryName(String viewId)
4152 return VIEWER_PREFIX + viewId;
4156 * Returns any open frame that matches given structure viewer data. The match
4157 * is based on the unique viewId, or (for older project versions) the frame's
4163 protected StructureViewerBase findMatchingViewer(
4164 Entry<String, StructureViewerModel> viewerData)
4166 final String sviewid = viewerData.getKey();
4167 final StructureViewerModel svattrib = viewerData.getValue();
4168 StructureViewerBase comp = null;
4169 JInternalFrame[] frames = getAllFrames();
4170 for (JInternalFrame frame : frames)
4172 if (frame instanceof StructureViewerBase)
4175 * Post jalview 2.4 schema includes structure view id
4178 && ((StructureViewerBase) frame).getViewId()
4181 comp = (StructureViewerBase) frame;
4182 break; // break added in 2.9
4185 * Otherwise test for matching position and size of viewer frame
4187 else if (frame.getX() == svattrib.getX()
4188 && frame.getY() == svattrib.getY()
4189 && frame.getHeight() == svattrib.getHeight()
4190 && frame.getWidth() == svattrib.getWidth())
4192 comp = (StructureViewerBase) frame;
4193 // no break in faint hope of an exact match on viewId
4201 * Link an AlignmentPanel to an existing structure viewer.
4206 * @param useinViewerSuperpos
4207 * @param usetoColourbyseq
4208 * @param viewerColouring
4210 protected void linkStructureViewer(AlignmentPanel ap,
4211 StructureViewerBase viewer, StructureViewerModel stateData)
4213 // NOTE: if the jalview project is part of a shared session then
4214 // view synchronization should/could be done here.
4216 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4217 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4218 final boolean viewerColouring = stateData.isColourByViewer();
4219 Map<File, StructureData> oldFiles = stateData.getFileData();
4222 * Add mapping for sequences in this view to an already open viewer
4224 final AAStructureBindingModel binding = viewer.getBinding();
4225 for (File id : oldFiles.keySet())
4227 // add this and any other pdb files that should be present in the
4229 StructureData filedat = oldFiles.get(id);
4230 String pdbFile = filedat.getFilePath();
4231 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4232 binding.getSsm().setMapping(seq, null, pdbFile,
4233 jalview.io.AppletFormatAdapter.FILE);
4234 binding.addSequenceForStructFile(pdbFile, seq);
4236 // and add the AlignmentPanel's reference to the view panel
4237 viewer.addAlignmentPanel(ap);
4238 if (useinViewerSuperpos)
4240 viewer.useAlignmentPanelForSuperposition(ap);
4244 viewer.excludeAlignmentPanelForSuperposition(ap);
4246 if (usetoColourbyseq)
4248 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4252 viewer.excludeAlignmentPanelForColourbyseq(ap);
4257 * Get all frames within the Desktop.
4261 protected JInternalFrame[] getAllFrames()
4263 JInternalFrame[] frames = null;
4264 // TODO is this necessary - is it safe - risk of hanging?
4269 frames = Desktop.desktop.getAllFrames();
4270 } catch (ArrayIndexOutOfBoundsException e)
4272 // occasional No such child exceptions are thrown here...
4276 } catch (InterruptedException f)
4280 } while (frames == null);
4285 * Answers true if 'version' is equal to or later than 'supported', where each
4286 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4287 * changes. Development and test values for 'version' are leniently treated
4291 * - minimum version we are comparing against
4293 * - version of data being processsed
4296 public static boolean isVersionStringLaterThan(String supported,
4299 if (supported == null || version == null
4300 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4301 || version.equalsIgnoreCase("Test")
4302 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4304 System.err.println("Assuming project file with "
4305 + (version == null ? "null" : version)
4306 + " is compatible with Jalview version " + supported);
4311 return StringUtils.compareVersions(version, supported, "b") >= 0;
4315 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4317 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4319 if (newStructureViewers != null)
4321 sview.getBinding().setFinishedLoadingFromArchive(false);
4322 newStructureViewers.add(sview);
4326 protected void setLoadingFinishedForNewStructureViewers()
4328 if (newStructureViewers != null)
4330 for (JalviewStructureDisplayI sview : newStructureViewers)
4332 sview.getBinding().setFinishedLoadingFromArchive(true);
4334 newStructureViewers.clear();
4335 newStructureViewers = null;
4339 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4340 List<SequenceI> hiddenSeqs, AlignmentI al,
4341 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4342 String viewId, List<JvAnnotRow> autoAlan)
4344 AlignFrame af = null;
4345 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4346 uniqueSeqSetId, viewId);
4348 af.setFileName(file, "Jalview");
4350 for (int i = 0; i < JSEQ.length; i++)
4352 af.viewport.setSequenceColour(af.viewport.getAlignment()
4353 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4358 af.getViewport().setColourByReferenceSeq(true);
4359 af.getViewport().setDisplayReferenceSeq(true);
4362 af.viewport.setGatherViewsHere(view.getGatheredViews());
4364 if (view.getSequenceSetId() != null)
4366 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4368 af.viewport.setSequenceSetId(uniqueSeqSetId);
4371 // propagate shared settings to this new view
4372 af.viewport.setHistoryList(av.getHistoryList());
4373 af.viewport.setRedoList(av.getRedoList());
4377 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4379 // TODO: check if this method can be called repeatedly without
4380 // side-effects if alignpanel already registered.
4381 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4383 // apply Hidden regions to view.
4384 if (hiddenSeqs != null)
4386 for (int s = 0; s < JSEQ.length; s++)
4388 SequenceGroup hidden = new SequenceGroup();
4389 boolean isRepresentative = false;
4390 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4392 isRepresentative = true;
4393 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4394 .getHiddenSequences(r));
4395 hidden.addSequence(sequenceToHide, false);
4396 // remove from hiddenSeqs list so we don't try to hide it twice
4397 hiddenSeqs.remove(sequenceToHide);
4399 if (isRepresentative)
4401 SequenceI representativeSequence = al.getSequenceAt(s);
4402 hidden.addSequence(representativeSequence, false);
4403 af.viewport.hideRepSequences(representativeSequence, hidden);
4407 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4409 af.viewport.hideSequence(hseqs);
4412 // recover view properties and display parameters
4413 if (view.getViewName() != null)
4415 af.viewport.viewName = view.getViewName();
4416 af.setInitialTabVisible();
4418 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4421 af.viewport.setShowAnnotation(view.getShowAnnotation());
4422 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4424 af.viewport.setColourText(view.getShowColourText());
4426 af.viewport.setConservationSelected(view.getConservationSelected());
4427 af.viewport.setShowJVSuffix(view.getShowFullId());
4428 af.viewport.setRightAlignIds(view.getRightAlignIds());
4429 af.viewport.setFont(
4430 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4431 .getFontSize()), true);
4432 ViewStyleI vs = af.viewport.getViewStyle();
4433 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4434 af.viewport.setViewStyle(vs);
4435 // TODO: allow custom charWidth/Heights to be restored by updating them
4436 // after setting font - which means set above to false
4437 af.viewport.setRenderGaps(view.getRenderGaps());
4438 af.viewport.setWrapAlignment(view.getWrapAlignment());
4439 af.viewport.setShowAnnotation(view.getShowAnnotation());
4441 af.viewport.setShowBoxes(view.getShowBoxes());
4443 af.viewport.setShowText(view.getShowText());
4445 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4446 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4447 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4448 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4449 .isShowUnconserved() : false);
4450 af.viewport.setStartRes(view.getStartRes());
4451 af.viewport.setStartSeq(view.getStartSeq());
4452 af.alignPanel.updateLayout();
4453 ColourSchemeI cs = null;
4454 // apply colourschemes
4455 if (view.getBgColour() != null)
4457 if (view.getBgColour().startsWith("ucs"))
4459 cs = getUserColourScheme(jms, view.getBgColour());
4461 else if (view.getBgColour().startsWith("Annotation"))
4463 AnnotationColours viewAnnColour = view.getAnnotationColours();
4464 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4471 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4476 cs.setThreshold(view.getPidThreshold(), true);
4477 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4481 af.viewport.setGlobalColourScheme(cs);
4482 af.viewport.setColourAppliesToAllGroups(false);
4484 if (view.getConservationSelected() && cs != null)
4486 cs.setConservationInc(view.getConsThreshold());
4489 af.changeColour(cs);
4491 af.viewport.setColourAppliesToAllGroups(true);
4493 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4495 if (view.hasCentreColumnLabels())
4497 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4499 if (view.hasIgnoreGapsinConsensus())
4501 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4504 if (view.hasFollowHighlight())
4506 af.viewport.setFollowHighlight(view.getFollowHighlight());
4508 if (view.hasFollowSelection())
4510 af.viewport.followSelection = view.getFollowSelection();
4512 if (view.hasShowConsensusHistogram())
4514 af.viewport.setShowConsensusHistogram(view
4515 .getShowConsensusHistogram());
4519 af.viewport.setShowConsensusHistogram(true);
4521 if (view.hasShowSequenceLogo())
4523 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4527 af.viewport.setShowSequenceLogo(false);
4529 if (view.hasNormaliseSequenceLogo())
4531 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4533 if (view.hasShowDbRefTooltip())
4535 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4537 if (view.hasShowNPfeatureTooltip())
4539 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4541 if (view.hasShowGroupConsensus())
4543 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4547 af.viewport.setShowGroupConsensus(false);
4549 if (view.hasShowGroupConservation())
4551 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4555 af.viewport.setShowGroupConservation(false);
4558 // recover featre settings
4559 if (jms.getFeatureSettings() != null)
4561 FeaturesDisplayed fdi;
4562 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4563 String[] renderOrder = new String[jms.getFeatureSettings()
4564 .getSettingCount()];
4565 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4566 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4568 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4570 Setting setting = jms.getFeatureSettings().getSetting(fs);
4571 if (setting.hasMincolour())
4573 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4574 new Color(setting.getMincolour()), new Color(
4575 setting.getColour()), setting.getMin(),
4576 setting.getMax()) : new FeatureColour(new Color(
4577 setting.getMincolour()), new Color(setting.getColour()),
4579 if (setting.hasThreshold())
4581 gc.setThreshold(setting.getThreshold());
4582 int threshstate = setting.getThreshstate();
4583 // -1 = None, 0 = Below, 1 = Above threshold
4584 if (threshstate == 0)
4586 gc.setBelowThreshold(true);
4588 else if (threshstate == 1)
4590 gc.setAboveThreshold(true);
4593 gc.setAutoScaled(true); // default
4594 if (setting.hasAutoScale())
4596 gc.setAutoScaled(setting.getAutoScale());
4598 if (setting.hasColourByLabel())
4600 gc.setColourByLabel(setting.getColourByLabel());
4602 // and put in the feature colour table.
4603 featureColours.put(setting.getType(), gc);
4607 featureColours.put(setting.getType(), new FeatureColour(
4608 new Color(setting.getColour())));
4610 renderOrder[fs] = setting.getType();
4611 if (setting.hasOrder())
4613 featureOrder.put(setting.getType(), setting.getOrder());
4617 featureOrder.put(setting.getType(), new Float(fs
4618 / jms.getFeatureSettings().getSettingCount()));
4620 if (setting.getDisplay())
4622 fdi.setVisible(setting.getType());
4625 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4626 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4628 Group grp = jms.getFeatureSettings().getGroup(gs);
4629 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4631 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4632 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4633 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4634 FeatureRendererSettings frs = new FeatureRendererSettings(
4635 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4636 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4637 .transferSettings(frs);
4641 if (view.getHiddenColumnsCount() > 0)
4643 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4645 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4646 .getHiddenColumns(c).getEnd() // +1
4650 if (view.getCalcIdParam() != null)
4652 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4654 if (calcIdParam != null)
4656 if (recoverCalcIdParam(calcIdParam, af.viewport))
4661 warn("Couldn't recover parameters for "
4662 + calcIdParam.getCalcId());
4667 af.setMenusFromViewport(af.viewport);
4668 af.setTitle(view.getTitle());
4669 // TODO: we don't need to do this if the viewport is aready visible.
4671 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4672 * has a 'cdna/protein complement' view, in which case save it in order to
4673 * populate a SplitFrame once all views have been read in.
4675 String complementaryViewId = view.getComplementId();
4676 if (complementaryViewId == null)
4678 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4680 // recompute any autoannotation
4681 af.alignPanel.updateAnnotation(false, true);
4682 reorderAutoannotation(af, al, autoAlan);
4683 af.alignPanel.alignmentChanged();
4687 splitFrameCandidates.put(view, af);
4692 private ColourSchemeI constructAnnotationColour(
4693 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4694 JalviewModelSequence jms, boolean checkGroupAnnColour)
4696 boolean propagateAnnColour = false;
4697 ColourSchemeI cs = null;
4698 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4699 if (checkGroupAnnColour && al.getGroups() != null
4700 && al.getGroups().size() > 0)
4702 // pre 2.8.1 behaviour
4703 // check to see if we should transfer annotation colours
4704 propagateAnnColour = true;
4705 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4707 if (sg.cs instanceof AnnotationColourGradient)
4709 propagateAnnColour = false;
4713 // int find annotation
4714 if (annAlignment.getAlignmentAnnotation() != null)
4716 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4718 if (annAlignment.getAlignmentAnnotation()[i].label
4719 .equals(viewAnnColour.getAnnotation()))
4721 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4723 annAlignment.getAlignmentAnnotation()[i]
4724 .setThreshold(new jalview.datamodel.GraphLine(
4725 viewAnnColour.getThreshold(), "Threshold",
4726 java.awt.Color.black)
4731 if (viewAnnColour.getColourScheme().equals("None"))
4733 cs = new AnnotationColourGradient(
4734 annAlignment.getAlignmentAnnotation()[i],
4735 new java.awt.Color(viewAnnColour.getMinColour()),
4736 new java.awt.Color(viewAnnColour.getMaxColour()),
4737 viewAnnColour.getAboveThreshold());
4739 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4741 cs = new AnnotationColourGradient(
4742 annAlignment.getAlignmentAnnotation()[i],
4743 getUserColourScheme(jms,
4744 viewAnnColour.getColourScheme()),
4745 viewAnnColour.getAboveThreshold());
4749 cs = new AnnotationColourGradient(
4750 annAlignment.getAlignmentAnnotation()[i],
4751 ColourSchemeProperty.getColour(al,
4752 viewAnnColour.getColourScheme()),
4753 viewAnnColour.getAboveThreshold());
4755 if (viewAnnColour.hasPerSequence())
4757 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4760 if (viewAnnColour.hasPredefinedColours())
4762 ((AnnotationColourGradient) cs)
4763 .setPredefinedColours(viewAnnColour
4764 .isPredefinedColours());
4766 if (propagateAnnColour && al.getGroups() != null)
4768 // Also use these settings for all the groups
4769 for (int g = 0; g < al.getGroups().size(); g++)
4771 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4779 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4780 * new AnnotationColourGradient(
4781 * annAlignment.getAlignmentAnnotation()[i], new
4782 * java.awt.Color(viewAnnColour. getMinColour()), new
4783 * java.awt.Color(viewAnnColour. getMaxColour()),
4784 * viewAnnColour.getAboveThreshold()); } else
4787 sg.cs = new AnnotationColourGradient(
4788 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4789 viewAnnColour.getAboveThreshold());
4790 if (cs instanceof AnnotationColourGradient)
4792 if (viewAnnColour.hasPerSequence())
4794 ((AnnotationColourGradient) cs)
4795 .setSeqAssociated(viewAnnColour.isPerSequence());
4797 if (viewAnnColour.hasPredefinedColours())
4799 ((AnnotationColourGradient) cs)
4800 .setPredefinedColours(viewAnnColour
4801 .isPredefinedColours());
4817 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4818 List<JvAnnotRow> autoAlan)
4820 // copy over visualization settings for autocalculated annotation in the
4822 if (al.getAlignmentAnnotation() != null)
4825 * Kludge for magic autoannotation names (see JAL-811)
4827 String[] magicNames = new String[] { "Consensus", "Quality",
4829 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4830 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4831 for (String nm : magicNames)
4833 visan.put(nm, nullAnnot);
4835 for (JvAnnotRow auan : autoAlan)
4837 visan.put(auan.template.label
4838 + (auan.template.getCalcId() == null ? "" : "\t"
4839 + auan.template.getCalcId()), auan);
4841 int hSize = al.getAlignmentAnnotation().length;
4842 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4843 // work through any autoCalculated annotation already on the view
4844 // removing it if it should be placed in a different location on the
4845 // annotation panel.
4846 List<String> remains = new ArrayList<String>(visan.keySet());
4847 for (int h = 0; h < hSize; h++)
4849 jalview.datamodel.AlignmentAnnotation jalan = al
4850 .getAlignmentAnnotation()[h];
4851 if (jalan.autoCalculated)
4854 JvAnnotRow valan = visan.get(k = jalan.label);
4855 if (jalan.getCalcId() != null)
4857 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4862 // delete the auto calculated row from the alignment
4863 al.deleteAnnotation(jalan, false);
4867 if (valan != nullAnnot)
4869 if (jalan != valan.template)
4871 // newly created autoannotation row instance
4872 // so keep a reference to the visible annotation row
4873 // and copy over all relevant attributes
4874 if (valan.template.graphHeight >= 0)
4877 jalan.graphHeight = valan.template.graphHeight;
4879 jalan.visible = valan.template.visible;
4881 reorder.add(new JvAnnotRow(valan.order, jalan));
4886 // Add any (possibly stale) autocalculated rows that were not appended to
4887 // the view during construction
4888 for (String other : remains)
4890 JvAnnotRow othera = visan.get(other);
4891 if (othera != nullAnnot && othera.template.getCalcId() != null
4892 && othera.template.getCalcId().length() > 0)
4894 reorder.add(othera);
4897 // now put the automatic annotation in its correct place
4898 int s = 0, srt[] = new int[reorder.size()];
4899 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4900 for (JvAnnotRow jvar : reorder)
4903 srt[s++] = jvar.order;
4906 jalview.util.QuickSort.sort(srt, rws);
4907 // and re-insert the annotation at its correct position
4908 for (JvAnnotRow jvar : rws)
4910 al.addAnnotation(jvar.template, jvar.order);
4912 af.alignPanel.adjustAnnotationHeight();
4916 Hashtable skipList = null;
4919 * TODO remove this method
4922 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4923 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4924 * throw new Error("Implementation Error. No skipList defined for this
4925 * Jalview2XML instance."); } return (AlignFrame)
4926 * skipList.get(view.getSequenceSetId()); }
4930 * Check if the Jalview view contained in object should be skipped or not.
4933 * @return true if view's sequenceSetId is a key in skipList
4935 private boolean skipViewport(JalviewModel object)
4937 if (skipList == null)
4942 if (skipList.containsKey(id = object.getJalviewModelSequence()
4943 .getViewport()[0].getSequenceSetId()))
4945 if (Cache.log != null && Cache.log.isDebugEnabled())
4947 Cache.log.debug("Skipping seuqence set id " + id);
4954 public void addToSkipList(AlignFrame af)
4956 if (skipList == null)
4958 skipList = new Hashtable();
4960 skipList.put(af.getViewport().getSequenceSetId(), af);
4963 public void clearSkipList()
4965 if (skipList != null)
4972 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4973 boolean ignoreUnrefed)
4975 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4977 Vector dseqs = null;
4980 // create a list of new dataset sequences
4981 dseqs = new Vector();
4983 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4985 Sequence vamsasSeq = vamsasSet.getSequence(i);
4986 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4988 // create a new dataset
4991 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4992 dseqs.copyInto(dsseqs);
4993 ds = new jalview.datamodel.Alignment(dsseqs);
4994 debug("Created new dataset " + vamsasSet.getDatasetId()
4995 + " for alignment " + System.identityHashCode(al));
4996 addDatasetRef(vamsasSet.getDatasetId(), ds);
4998 // set the dataset for the newly imported alignment.
4999 if (al.getDataset() == null && !ignoreUnrefed)
5008 * sequence definition to create/merge dataset sequence for
5012 * vector to add new dataset sequence to
5013 * @param ignoreUnrefed
5014 * - when true, don't create new sequences from vamsasSeq if it's id
5015 * doesn't already have an asssociated Jalview sequence.
5017 * - used to reorder the sequence in the alignment according to the
5018 * vamsasSeq array ordering, to preserve ordering of dataset
5020 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5021 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5023 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5025 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5026 boolean reorder = false;
5027 SequenceI dsq = null;
5028 if (sq != null && sq.getDatasetSequence() != null)
5030 dsq = sq.getDatasetSequence();
5036 if (sq == null && ignoreUnrefed)
5040 String sqid = vamsasSeq.getDsseqid();
5043 // need to create or add a new dataset sequence reference to this sequence
5046 dsq = seqRefIds.get(sqid);
5051 // make a new dataset sequence
5052 dsq = sq.createDatasetSequence();
5055 // make up a new dataset reference for this sequence
5056 sqid = seqHash(dsq);
5058 dsq.setVamsasId(uniqueSetSuffix + sqid);
5059 seqRefIds.put(sqid, dsq);
5064 dseqs.addElement(dsq);
5069 ds.addSequence(dsq);
5075 { // make this dataset sequence sq's dataset sequence
5076 sq.setDatasetSequence(dsq);
5077 // and update the current dataset alignment
5082 if (!dseqs.contains(dsq))
5089 if (ds.findIndex(dsq) < 0)
5091 ds.addSequence(dsq);
5098 // TODO: refactor this as a merge dataset sequence function
5099 // now check that sq (the dataset sequence) sequence really is the union of
5100 // all references to it
5101 // boolean pre = sq.getStart() < dsq.getStart();
5102 // boolean post = sq.getEnd() > dsq.getEnd();
5106 // StringBuffer sb = new StringBuffer();
5107 String newres = jalview.analysis.AlignSeq.extractGaps(
5108 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5109 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5110 && newres.length() > dsq.getLength())
5112 // Update with the longer sequence.
5116 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5117 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5118 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5119 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5121 dsq.setSequence(newres);
5123 // TODO: merges will never happen if we 'know' we have the real dataset
5124 // sequence - this should be detected when id==dssid
5126 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5127 // + (pre ? "prepended" : "") + " "
5128 // + (post ? "appended" : ""));
5133 // sequence refs are identical. We may need to update the existing dataset
5134 // alignment with this one, though.
5135 if (ds != null && dseqs == null)
5137 int opos = ds.findIndex(dsq);
5138 SequenceI tseq = null;
5139 if (opos != -1 && vseqpos != opos)
5141 // remove from old position
5142 ds.deleteSequence(dsq);
5144 if (vseqpos < ds.getHeight())
5146 if (vseqpos != opos)
5148 // save sequence at destination position
5149 tseq = ds.getSequenceAt(vseqpos);
5150 ds.replaceSequenceAt(vseqpos, dsq);
5151 ds.addSequence(tseq);
5156 ds.addSequence(dsq);
5163 * TODO use AlignmentI here and in related methods - needs
5164 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5166 Hashtable<String, AlignmentI> datasetIds = null;
5168 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5170 private AlignmentI getDatasetFor(String datasetId)
5172 if (datasetIds == null)
5174 datasetIds = new Hashtable<String, AlignmentI>();
5177 if (datasetIds.containsKey(datasetId))
5179 return datasetIds.get(datasetId);
5184 private void addDatasetRef(String datasetId, AlignmentI dataset)
5186 if (datasetIds == null)
5188 datasetIds = new Hashtable<String, AlignmentI>();
5190 datasetIds.put(datasetId, dataset);
5194 * make a new dataset ID for this jalview dataset alignment
5199 private String getDatasetIdRef(AlignmentI dataset)
5201 if (dataset.getDataset() != null)
5203 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5205 String datasetId = makeHashCode(dataset, null);
5206 if (datasetId == null)
5208 // make a new datasetId and record it
5209 if (dataset2Ids == null)
5211 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5215 datasetId = dataset2Ids.get(dataset);
5217 if (datasetId == null)
5219 datasetId = "ds" + dataset2Ids.size() + 1;
5220 dataset2Ids.put(dataset, datasetId);
5226 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5228 for (int d = 0; d < sequence.getDBRefCount(); d++)
5230 DBRef dr = sequence.getDBRef(d);
5231 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5232 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5233 .getVersion(), sequence.getDBRef(d).getAccessionId());
5234 if (dr.getMapping() != null)
5236 entry.setMap(addMapping(dr.getMapping()));
5238 datasetSequence.addDBRef(entry);
5242 private jalview.datamodel.Mapping addMapping(Mapping m)
5244 SequenceI dsto = null;
5245 // Mapping m = dr.getMapping();
5246 int fr[] = new int[m.getMapListFromCount() * 2];
5247 Enumeration f = m.enumerateMapListFrom();
5248 for (int _i = 0; f.hasMoreElements(); _i += 2)
5250 MapListFrom mf = (MapListFrom) f.nextElement();
5251 fr[_i] = mf.getStart();
5252 fr[_i + 1] = mf.getEnd();
5254 int fto[] = new int[m.getMapListToCount() * 2];
5255 f = m.enumerateMapListTo();
5256 for (int _i = 0; f.hasMoreElements(); _i += 2)
5258 MapListTo mf = (MapListTo) f.nextElement();
5259 fto[_i] = mf.getStart();
5260 fto[_i + 1] = mf.getEnd();
5262 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5263 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5264 if (m.getMappingChoice() != null)
5266 MappingChoice mc = m.getMappingChoice();
5267 if (mc.getDseqFor() != null)
5269 String dsfor = "" + mc.getDseqFor();
5270 if (seqRefIds.containsKey(dsfor))
5275 jmap.setTo(seqRefIds.get(dsfor));
5279 frefedSequence.add(newMappingRef(dsfor, jmap));
5285 * local sequence definition
5287 Sequence ms = mc.getSequence();
5288 SequenceI djs = null;
5289 String sqid = ms.getDsseqid();
5290 if (sqid != null && sqid.length() > 0)
5293 * recover dataset sequence
5295 djs = seqRefIds.get(sqid);
5300 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5301 sqid = ((Object) ms).toString(); // make up a new hascode for
5302 // undefined dataset sequence hash
5303 // (unlikely to happen)
5309 * make a new dataset sequence and add it to refIds hash
5311 djs = new jalview.datamodel.Sequence(ms.getName(),
5313 djs.setStart(jmap.getMap().getToLowest());
5314 djs.setEnd(jmap.getMap().getToHighest());
5315 djs.setVamsasId(uniqueSetSuffix + sqid);
5317 incompleteSeqs.put(sqid, djs);
5318 seqRefIds.put(sqid, djs);
5321 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5330 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5331 boolean keepSeqRefs)
5334 JalviewModel jm = saveState(ap, null, null, null);
5339 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5343 uniqueSetSuffix = "";
5344 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5349 if (this.frefedSequence == null)
5351 frefedSequence = new Vector();
5354 viewportsAdded.clear();
5356 AlignFrame af = loadFromObject(jm, null, false, null);
5357 af.alignPanels.clear();
5358 af.closeMenuItem_actionPerformed(true);
5361 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5362 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5363 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5364 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5365 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5368 return af.alignPanel;
5372 * flag indicating if hashtables should be cleared on finalization TODO this
5373 * flag may not be necessary
5375 private final boolean _cleartables = true;
5377 private Hashtable jvids2vobj;
5382 * @see java.lang.Object#finalize()
5385 protected void finalize() throws Throwable
5387 // really make sure we have no buried refs left.
5392 this.seqRefIds = null;
5393 this.seqsToIds = null;
5397 private void warn(String msg)
5402 private void warn(String msg, Exception e)
5404 if (Cache.log != null)
5408 Cache.log.warn(msg, e);
5412 Cache.log.warn(msg);
5417 System.err.println("Warning: " + msg);
5420 e.printStackTrace();
5425 private void debug(String string)
5427 debug(string, null);
5430 private void debug(String msg, Exception e)
5432 if (Cache.log != null)
5436 Cache.log.debug(msg, e);
5440 Cache.log.debug(msg);
5445 System.err.println("Warning: " + msg);
5448 e.printStackTrace();
5454 * set the object to ID mapping tables used to write/recover objects and XML
5455 * ID strings for the jalview project. If external tables are provided then
5456 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5457 * object goes out of scope. - also populates the datasetIds hashtable with
5458 * alignment objects containing dataset sequences
5461 * Map from ID strings to jalview datamodel
5463 * Map from jalview datamodel to ID strings
5467 public void setObjectMappingTables(Hashtable vobj2jv,
5468 IdentityHashMap jv2vobj)
5470 this.jv2vobj = jv2vobj;
5471 this.vobj2jv = vobj2jv;
5472 Iterator ds = jv2vobj.keySet().iterator();
5474 while (ds.hasNext())
5476 Object jvobj = ds.next();
5477 id = jv2vobj.get(jvobj).toString();
5478 if (jvobj instanceof jalview.datamodel.Alignment)
5480 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5482 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5485 else if (jvobj instanceof jalview.datamodel.Sequence)
5487 // register sequence object so the XML parser can recover it.
5488 if (seqRefIds == null)
5490 seqRefIds = new HashMap<String, SequenceI>();
5492 if (seqsToIds == null)
5494 seqsToIds = new IdentityHashMap<SequenceI, String>();
5496 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5497 seqsToIds.put((SequenceI) jvobj, id);
5499 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5502 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5503 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5504 if (jvann.annotationId == null)
5506 jvann.annotationId = anid;
5508 if (!jvann.annotationId.equals(anid))
5510 // TODO verify that this is the correct behaviour
5511 this.warn("Overriding Annotation ID for " + anid
5512 + " from different id : " + jvann.annotationId);
5513 jvann.annotationId = anid;
5516 else if (jvobj instanceof String)
5518 if (jvids2vobj == null)
5520 jvids2vobj = new Hashtable();
5521 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5526 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5532 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5533 * objects created from the project archive. If string is null (default for
5534 * construction) then suffix will be set automatically.
5538 public void setUniqueSetSuffix(String string)
5540 uniqueSetSuffix = string;
5545 * uses skipList2 as the skipList for skipping views on sequence sets
5546 * associated with keys in the skipList
5550 public void setSkipList(Hashtable skipList2)
5552 skipList = skipList2;
5556 * Reads the jar entry of given name and returns its contents, or null if the
5557 * entry is not found.
5560 * @param jarEntryName
5563 protected String readJarEntry(jarInputStreamProvider jprovider,
5564 String jarEntryName)
5566 String result = null;
5567 BufferedReader in = null;
5572 * Reopen the jar input stream and traverse its entries to find a matching
5575 JarInputStream jin = jprovider.getJarInputStream();
5576 JarEntry entry = null;
5579 entry = jin.getNextJarEntry();
5580 } while (entry != null && !entry.getName().equals(jarEntryName));
5584 StringBuilder out = new StringBuilder(256);
5585 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5588 while ((data = in.readLine()) != null)
5592 result = out.toString();
5596 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5598 } catch (Exception ex)
5600 ex.printStackTrace();
5608 } catch (IOException e)
5619 * Returns an incrementing counter (0, 1, 2...)
5623 private synchronized int nextCounter()