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.api.FeatureColourI;
24 import jalview.api.ViewStyleI;
25 import jalview.api.structures.JalviewStructureDisplayI;
26 import jalview.bin.Cache;
27 import jalview.datamodel.AlignedCodonFrame;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.PDBEntry;
32 import jalview.datamodel.RnaViewerModel;
33 import jalview.datamodel.SequenceGroup;
34 import jalview.datamodel.SequenceI;
35 import jalview.datamodel.StructureViewerModel;
36 import jalview.datamodel.StructureViewerModel.StructureData;
37 import jalview.ext.varna.RnaModel;
38 import jalview.gui.StructureViewer.ViewerType;
39 import jalview.schemabinding.version2.AlcodMap;
40 import jalview.schemabinding.version2.AlcodonFrame;
41 import jalview.schemabinding.version2.Annotation;
42 import jalview.schemabinding.version2.AnnotationColours;
43 import jalview.schemabinding.version2.AnnotationElement;
44 import jalview.schemabinding.version2.CalcIdParam;
45 import jalview.schemabinding.version2.DBRef;
46 import jalview.schemabinding.version2.Features;
47 import jalview.schemabinding.version2.Group;
48 import jalview.schemabinding.version2.HiddenColumns;
49 import jalview.schemabinding.version2.JGroup;
50 import jalview.schemabinding.version2.JSeq;
51 import jalview.schemabinding.version2.JalviewModel;
52 import jalview.schemabinding.version2.JalviewModelSequence;
53 import jalview.schemabinding.version2.MapListFrom;
54 import jalview.schemabinding.version2.MapListTo;
55 import jalview.schemabinding.version2.Mapping;
56 import jalview.schemabinding.version2.MappingChoice;
57 import jalview.schemabinding.version2.OtherData;
58 import jalview.schemabinding.version2.PdbentryItem;
59 import jalview.schemabinding.version2.Pdbids;
60 import jalview.schemabinding.version2.Property;
61 import jalview.schemabinding.version2.RnaViewer;
62 import jalview.schemabinding.version2.SecondaryStructure;
63 import jalview.schemabinding.version2.Sequence;
64 import jalview.schemabinding.version2.SequenceSet;
65 import jalview.schemabinding.version2.SequenceSetProperties;
66 import jalview.schemabinding.version2.Setting;
67 import jalview.schemabinding.version2.StructureState;
68 import jalview.schemabinding.version2.ThresholdLine;
69 import jalview.schemabinding.version2.Tree;
70 import jalview.schemabinding.version2.UserColours;
71 import jalview.schemabinding.version2.Viewport;
72 import jalview.schemes.AnnotationColourGradient;
73 import jalview.schemes.ColourSchemeI;
74 import jalview.schemes.ColourSchemeProperty;
75 import jalview.schemes.FeatureColour;
76 import jalview.schemes.ResidueColourScheme;
77 import jalview.schemes.ResidueProperties;
78 import jalview.schemes.UserColourScheme;
79 import jalview.structure.StructureSelectionManager;
80 import jalview.structures.models.AAStructureBindingModel;
81 import jalview.util.MessageManager;
82 import jalview.util.Platform;
83 import jalview.util.StringUtils;
84 import jalview.util.jarInputStreamProvider;
85 import jalview.viewmodel.AlignmentViewport;
86 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
87 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
88 import jalview.ws.jws2.Jws2Discoverer;
89 import jalview.ws.jws2.dm.AAConSettings;
90 import jalview.ws.jws2.jabaws2.Jws2Instance;
91 import jalview.ws.params.ArgumentI;
92 import jalview.ws.params.AutoCalcSetting;
93 import jalview.ws.params.WsParamSetI;
95 import java.awt.Color;
96 import java.awt.Rectangle;
97 import java.io.BufferedReader;
98 import java.io.DataInputStream;
99 import java.io.DataOutputStream;
101 import java.io.FileInputStream;
102 import java.io.FileOutputStream;
103 import java.io.IOException;
104 import java.io.InputStreamReader;
105 import java.io.OutputStreamWriter;
106 import java.io.PrintWriter;
107 import java.lang.reflect.InvocationTargetException;
108 import java.net.MalformedURLException;
110 import java.util.ArrayList;
111 import java.util.Arrays;
112 import java.util.Enumeration;
113 import java.util.HashMap;
114 import java.util.HashSet;
115 import java.util.Hashtable;
116 import java.util.IdentityHashMap;
117 import java.util.Iterator;
118 import java.util.LinkedHashMap;
119 import java.util.List;
120 import java.util.Map;
121 import java.util.Map.Entry;
122 import java.util.Set;
123 import java.util.Vector;
124 import java.util.jar.JarEntry;
125 import java.util.jar.JarInputStream;
126 import java.util.jar.JarOutputStream;
128 import javax.swing.JInternalFrame;
129 import javax.swing.JOptionPane;
130 import javax.swing.SwingUtilities;
132 import org.exolab.castor.xml.Marshaller;
133 import org.exolab.castor.xml.Unmarshaller;
136 * Write out the current jalview desktop state as a Jalview XML stream.
138 * Note: the vamsas objects referred to here are primitive versions of the
139 * VAMSAS project schema elements - they are not the same and most likely never
143 * @version $Revision: 1.134 $
145 public class Jalview2XML
147 private static final String VIEWER_PREFIX = "viewer_";
149 private static final String RNA_PREFIX = "rna_";
151 private static final String UTF_8 = "UTF-8";
153 // use this with nextCounter() to make unique names for entities
154 private int counter = 0;
157 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
158 * of sequence objects are created.
160 IdentityHashMap<SequenceI, String> seqsToIds = null;
163 * jalview XML Sequence ID to jalview sequence object reference (both dataset
164 * and alignment sequences. Populated as XML reps of sequence objects are
167 Map<String, SequenceI> seqRefIds = null;
169 Map<String, SequenceI> incompleteSeqs = null;
171 List<SeqFref> frefedSequence = null;
173 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
176 * Map of reconstructed AlignFrame objects that appear to have come from
177 * SplitFrame objects (have a dna/protein complement view).
179 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
182 * Map from displayed rna structure models to their saved session state jar
185 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
188 * create/return unique hash string for sq
191 * @return new or existing unique string for sq
193 String seqHash(SequenceI sq)
195 if (seqsToIds == null)
199 if (seqsToIds.containsKey(sq))
201 return seqsToIds.get(sq);
205 // create sequential key
206 String key = "sq" + (seqsToIds.size() + 1);
207 key = makeHashCode(sq, key); // check we don't have an external reference
209 seqsToIds.put(sq, key);
218 if (seqRefIds != null)
222 if (seqsToIds != null)
226 if (incompleteSeqs != null)
228 incompleteSeqs.clear();
236 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
237 // seqRefIds = new Hashtable();
238 // seqsToIds = new IdentityHashMap();
244 if (seqsToIds == null)
246 seqsToIds = new IdentityHashMap<SequenceI, String>();
248 if (seqRefIds == null)
250 seqRefIds = new HashMap<String, SequenceI>();
252 if (incompleteSeqs == null)
254 incompleteSeqs = new HashMap<String, SequenceI>();
256 if (frefedSequence == null)
258 frefedSequence = new ArrayList<SeqFref>();
266 public Jalview2XML(boolean raiseGUI)
268 this.raiseGUI = raiseGUI;
272 * base class for resolving forward references to sequences by their ID
277 abstract class SeqFref
283 public SeqFref(String _sref, String type)
289 public String getSref()
294 public SequenceI getSrefSeq()
296 return seqRefIds.get(sref);
299 public boolean isResolvable()
301 return seqRefIds.get(sref) != null;
304 public SequenceI getSrefDatasetSeq()
306 SequenceI sq = seqRefIds.get(sref);
309 while (sq.getDatasetSequence() != null)
311 sq = sq.getDatasetSequence();
317 * @return true if the forward reference was fully resolved
319 abstract boolean resolve();
322 public String toString()
324 return type + " reference to " + sref;
329 * create forward reference for a mapping
335 public SeqFref newMappingRef(final String sref,
336 final jalview.datamodel.Mapping _jmap)
338 SeqFref fref = new SeqFref(sref, "Mapping")
340 public jalview.datamodel.Mapping jmap = _jmap;
345 SequenceI seq = getSrefDatasetSeq();
357 public SeqFref newAlcodMapRef(final String sref,
358 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
361 SeqFref fref = new SeqFref(sref, "Codon Frame")
363 AlignedCodonFrame cf = _cf;
365 public jalview.datamodel.Mapping mp = _jmap;
368 public boolean isResolvable()
370 return super.isResolvable() && mp.getTo() != null;
376 SequenceI seq = getSrefDatasetSeq();
381 cf.addMap(seq, mp.getTo(), mp.getMap());
388 public void resolveFrefedSequences()
390 Iterator<SeqFref> nextFref=frefedSequence.iterator();
391 int toresolve=frefedSequence.size();
392 int unresolved=0,failedtoresolve=0;
393 while (nextFref.hasNext()) {
394 SeqFref ref = nextFref.next();
395 if (ref.isResolvable())
404 } catch (Exception x) {
405 System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
415 System.err.println("Jalview Project Import: There were " + unresolved
416 + " forward references left unresolved on the stack.");
418 if (failedtoresolve>0)
420 System.err.println("SERIOUS! " + failedtoresolve
421 + " resolvable forward references failed to resolve.");
423 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
425 System.err.println("Jalview Project Import: There are "
426 + incompleteSeqs.size()
427 + " sequences which may have incomplete metadata.");
428 if (incompleteSeqs.size() < 10)
430 for (SequenceI s : incompleteSeqs.values())
432 System.err.println(s.toString());
438 .println("Too many to report. Skipping output of incomplete sequences.");
444 * This maintains a map of viewports, the key being the seqSetId. Important to
445 * set historyItem and redoList for multiple views
447 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
449 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
451 String uniqueSetSuffix = "";
454 * List of pdbfiles added to Jar
456 List<String> pdbfiles = null;
458 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
459 public void saveState(File statefile)
461 FileOutputStream fos = null;
464 fos = new FileOutputStream(statefile);
465 JarOutputStream jout = new JarOutputStream(fos);
468 } catch (Exception e)
470 // TODO: inform user of the problem - they need to know if their data was
472 if (errorMessage == null)
474 errorMessage = "Couldn't write Jalview Archive to output file '"
475 + statefile + "' - See console error log for details";
479 errorMessage += "(output file was '" + statefile + "')";
489 } catch (IOException e)
499 * Writes a jalview project archive to the given Jar output stream.
503 public void saveState(JarOutputStream jout)
505 AlignFrame[] frames = Desktop.getAlignFrames();
511 saveAllFrames(Arrays.asList(frames), jout);
515 * core method for storing state for a set of AlignFrames.
518 * - frames involving all data to be exported (including containing
521 * - project output stream
523 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
525 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
528 * ensure cached data is clear before starting
530 // todo tidy up seqRefIds, seqsToIds initialisation / reset
532 splitFrameCandidates.clear();
537 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
538 // //////////////////////////////////////////////////
540 List<String> shortNames = new ArrayList<String>();
541 List<String> viewIds = new ArrayList<String>();
544 for (int i = frames.size() - 1; i > -1; i--)
546 AlignFrame af = frames.get(i);
550 .containsKey(af.getViewport().getSequenceSetId()))
555 String shortName = makeFilename(af, shortNames);
557 int ap, apSize = af.alignPanels.size();
559 for (ap = 0; ap < apSize; ap++)
561 AlignmentPanel apanel = af.alignPanels.get(ap);
562 String fileName = apSize == 1 ? shortName : ap + shortName;
563 if (!fileName.endsWith(".xml"))
565 fileName = fileName + ".xml";
568 saveState(apanel, fileName, jout, viewIds);
570 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
572 if (!dsses.containsKey(dssid))
574 dsses.put(dssid, af);
579 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
585 } catch (Exception foo)
590 } catch (Exception ex)
592 // TODO: inform user of the problem - they need to know if their data was
594 if (errorMessage == null)
596 errorMessage = "Couldn't write Jalview Archive - see error output for details";
598 ex.printStackTrace();
603 * Generates a distinct file name, based on the title of the AlignFrame, by
604 * appending _n for increasing n until an unused name is generated. The new
605 * name (without its extension) is added to the list.
609 * @return the generated name, with .xml extension
611 protected String makeFilename(AlignFrame af, List<String> namesUsed)
613 String shortName = af.getTitle();
615 if (shortName.indexOf(File.separatorChar) > -1)
617 shortName = shortName.substring(shortName
618 .lastIndexOf(File.separatorChar) + 1);
623 while (namesUsed.contains(shortName))
625 if (shortName.endsWith("_" + (count - 1)))
627 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
630 shortName = shortName.concat("_" + count);
634 namesUsed.add(shortName);
636 if (!shortName.endsWith(".xml"))
638 shortName = shortName + ".xml";
643 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
644 public boolean saveAlignment(AlignFrame af, String jarFile,
649 FileOutputStream fos = new FileOutputStream(jarFile);
650 JarOutputStream jout = new JarOutputStream(fos);
651 List<AlignFrame> frames = new ArrayList<AlignFrame>();
653 // resolve splitframes
654 if (af.getViewport().getCodingComplement() != null)
656 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
662 saveAllFrames(frames, jout);
666 } catch (Exception foo)
672 } catch (Exception ex)
674 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
675 ex.printStackTrace();
680 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
681 String fileName, JarOutputStream jout)
684 for (String dssids : dsses.keySet())
686 AlignFrame _af = dsses.get(dssids);
687 String jfileName = fileName + " Dataset for " + _af.getTitle();
688 if (!jfileName.endsWith(".xml"))
690 jfileName = jfileName + ".xml";
692 saveState(_af.alignPanel, jfileName, true, jout, null);
697 * create a JalviewModel from an alignment view and marshall it to a
701 * panel to create jalview model for
703 * name of alignment panel written to output stream
710 public JalviewModel saveState(AlignmentPanel ap, String fileName,
711 JarOutputStream jout, List<String> viewIds)
713 return saveState(ap, fileName, false, jout, viewIds);
717 * create a JalviewModel from an alignment view and marshall it to a
721 * panel to create jalview model for
723 * name of alignment panel written to output stream
725 * when true, only write the dataset for the alignment, not the data
726 * associated with the view.
732 public JalviewModel saveState(AlignmentPanel ap, String fileName,
733 boolean storeDS, JarOutputStream jout, List<String> viewIds)
737 viewIds = new ArrayList<String>();
742 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
744 AlignViewport av = ap.av;
746 JalviewModel object = new JalviewModel();
747 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
749 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
750 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
751 "Development Build"));
754 * rjal is full height alignment, jal is actual alignment with full metadata
755 * but excludes hidden sequences.
757 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
759 if (av.hasHiddenRows())
761 rjal = jal.getHiddenSequences().getFullAlignment();
764 SequenceSet vamsasSet = new SequenceSet();
766 JalviewModelSequence jms = new JalviewModelSequence();
768 vamsasSet.setGapChar(jal.getGapCharacter() + "");
770 if (jal.getDataset() != null)
772 // dataset id is the dataset's hashcode
773 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
776 // switch jal and the dataset
777 jal = jal.getDataset();
781 if (jal.getProperties() != null)
783 Enumeration en = jal.getProperties().keys();
784 while (en.hasMoreElements())
786 String key = en.nextElement().toString();
787 SequenceSetProperties ssp = new SequenceSetProperties();
789 ssp.setValue(jal.getProperties().get(key).toString());
790 vamsasSet.addSequenceSetProperties(ssp);
795 Set<String> calcIdSet = new HashSet<String>();
796 // record the set of vamsas sequence XML POJO we create.
797 HashMap<String,Sequence> vamsasSetIds = new HashMap<String,Sequence>();
799 for (final SequenceI jds : rjal.getSequences())
801 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
802 : jds.getDatasetSequence();
803 String id = seqHash(jds);
804 if (vamsasSetIds.get(id) == null)
806 if (seqRefIds.get(id) != null && !storeDS)
808 // This happens for two reasons: 1. multiple views are being
810 // 2. the hashCode has collided with another sequence's code. This
812 // HAPPEN! (PF00072.15.stk does this)
813 // JBPNote: Uncomment to debug writing out of files that do not read
814 // back in due to ArrayOutOfBoundExceptions.
815 // System.err.println("vamsasSeq backref: "+id+"");
816 // System.err.println(jds.getName()+"
817 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
818 // System.err.println("Hashcode: "+seqHash(jds));
819 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
820 // System.err.println(rsq.getName()+"
821 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
822 // System.err.println("Hashcode: "+seqHash(rsq));
826 vamsasSeq = createVamsasSequence(id, jds);
827 vamsasSet.addSequence(vamsasSeq);
828 vamsasSetIds.put(id, vamsasSeq);
829 seqRefIds.put(id, jds);
833 jseq.setStart(jds.getStart());
834 jseq.setEnd(jds.getEnd());
835 jseq.setColour(av.getSequenceColour(jds).getRGB());
837 jseq.setId(id); // jseq id should be a string not a number
840 // Store any sequences this sequence represents
841 if (av.hasHiddenRows())
843 // use rjal, contains the full height alignment
844 jseq.setHidden(av.getAlignment().getHiddenSequences()
847 if (av.isHiddenRepSequence(jds))
849 jalview.datamodel.SequenceI[] reps = av
850 .getRepresentedSequences(jds)
851 .getSequencesInOrder(rjal);
853 for (int h = 0; h < reps.length; h++)
857 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
862 // mark sequence as reference - if it is the reference for this view
865 jseq.setViewreference(jds == jal.getSeqrep());
869 // TODO: omit sequence features from each alignment view's XML dump if we
870 // are storing dataset
871 if (jds.getSequenceFeatures() != null)
873 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
875 while (index < sf.length)
877 Features features = new Features();
879 features.setBegin(sf[index].getBegin());
880 features.setEnd(sf[index].getEnd());
881 features.setDescription(sf[index].getDescription());
882 features.setType(sf[index].getType());
883 features.setFeatureGroup(sf[index].getFeatureGroup());
884 features.setScore(sf[index].getScore());
885 if (sf[index].links != null)
887 for (int l = 0; l < sf[index].links.size(); l++)
889 OtherData keyValue = new OtherData();
890 keyValue.setKey("LINK_" + l);
891 keyValue.setValue(sf[index].links.elementAt(l).toString());
892 features.addOtherData(keyValue);
895 if (sf[index].otherDetails != null)
898 Iterator<String> keys = sf[index].otherDetails.keySet()
900 while (keys.hasNext())
903 OtherData keyValue = new OtherData();
904 keyValue.setKey(key);
905 keyValue.setValue(sf[index].otherDetails.get(key).toString());
906 features.addOtherData(keyValue);
910 jseq.addFeatures(features);
915 if (jdatasq.getAllPDBEntries() != null)
917 Enumeration en = jdatasq.getAllPDBEntries().elements();
918 while (en.hasMoreElements())
920 Pdbids pdb = new Pdbids();
921 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
924 String pdbId = entry.getId();
926 pdb.setType(entry.getType());
929 * Store any structure views associated with this sequence. This
930 * section copes with duplicate entries in the project, so a dataset
931 * only view *should* be coped with sensibly.
933 // This must have been loaded, is it still visible?
934 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
935 String matchedFile = null;
936 for (int f = frames.length - 1; f > -1; f--)
938 if (frames[f] instanceof StructureViewerBase)
940 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
941 matchedFile = saveStructureState(ap, jds, pdb, entry,
942 viewIds, matchedFile, viewFrame);
944 * Only store each structure viewer's state once in the project
945 * jar. First time through only (storeDS==false)
947 String viewId = viewFrame.getViewId();
948 if (!storeDS && !viewIds.contains(viewId))
953 String viewerState = viewFrame.getStateInfo();
954 writeJarEntry(jout, getViewerJarEntryName(viewId),
955 viewerState.getBytes());
956 } catch (IOException e)
958 System.err.println("Error saving viewer state: "
965 if (matchedFile != null || entry.getFile() != null)
967 if (entry.getFile() != null)
970 matchedFile = entry.getFile();
972 pdb.setFile(matchedFile); // entry.getFile());
973 if (pdbfiles == null)
975 pdbfiles = new ArrayList<String>();
978 if (!pdbfiles.contains(pdbId))
981 copyFileToJar(jout, matchedFile, pdbId);
985 Enumeration<String> props = entry.getProperties();
986 if (props.hasMoreElements())
988 PdbentryItem item = new PdbentryItem();
989 while (props.hasMoreElements())
991 Property prop = new Property();
992 String key = props.nextElement();
994 prop.setValue(entry.getProperty(key).toString());
995 item.addProperty(prop);
997 pdb.addPdbentryItem(item);
1000 jseq.addPdbids(pdb);
1004 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1009 if (!storeDS && av.hasHiddenRows())
1011 jal = av.getAlignment();
1015 if (storeDS && jal.getCodonFrames() != null)
1017 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1018 for (AlignedCodonFrame acf : jac)
1020 AlcodonFrame alc = new AlcodonFrame();
1021 if (acf.getProtMappings() != null
1022 && acf.getProtMappings().length > 0)
1024 boolean hasMap = false;
1025 SequenceI[] dnas = acf.getdnaSeqs();
1026 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1027 for (int m = 0; m < pmaps.length; m++)
1029 AlcodMap alcmap = new AlcodMap();
1030 alcmap.setDnasq(seqHash(dnas[m]));
1031 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1033 alc.addAlcodMap(alcmap);
1038 vamsasSet.addAlcodonFrame(alc);
1041 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1043 // AlcodonFrame alc = new AlcodonFrame();
1044 // vamsasSet.addAlcodonFrame(alc);
1045 // for (int p = 0; p < acf.aaWidth; p++)
1047 // Alcodon cmap = new Alcodon();
1048 // if (acf.codons[p] != null)
1050 // // Null codons indicate a gapped column in the translated peptide
1052 // cmap.setPos1(acf.codons[p][0]);
1053 // cmap.setPos2(acf.codons[p][1]);
1054 // cmap.setPos3(acf.codons[p][2]);
1056 // alc.addAlcodon(cmap);
1058 // if (acf.getProtMappings() != null
1059 // && acf.getProtMappings().length > 0)
1061 // SequenceI[] dnas = acf.getdnaSeqs();
1062 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1063 // for (int m = 0; m < pmaps.length; m++)
1065 // AlcodMap alcmap = new AlcodMap();
1066 // alcmap.setDnasq(seqHash(dnas[m]));
1067 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1069 // alc.addAlcodMap(alcmap);
1076 // /////////////////////////////////
1077 if (!storeDS && av.currentTree != null)
1079 // FIND ANY ASSOCIATED TREES
1080 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1081 if (Desktop.desktop != null)
1083 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1085 for (int t = 0; t < frames.length; t++)
1087 if (frames[t] instanceof TreePanel)
1089 TreePanel tp = (TreePanel) frames[t];
1091 if (tp.treeCanvas.av.getAlignment() == jal)
1093 Tree tree = new Tree();
1094 tree.setTitle(tp.getTitle());
1095 tree.setCurrentTree((av.currentTree == tp.getTree()));
1096 tree.setNewick(tp.getTree().toString());
1097 tree.setThreshold(tp.treeCanvas.threshold);
1099 tree.setFitToWindow(tp.fitToWindow.getState());
1100 tree.setFontName(tp.getTreeFont().getName());
1101 tree.setFontSize(tp.getTreeFont().getSize());
1102 tree.setFontStyle(tp.getTreeFont().getStyle());
1103 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1105 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1106 tree.setShowDistances(tp.distanceMenu.getState());
1108 tree.setHeight(tp.getHeight());
1109 tree.setWidth(tp.getWidth());
1110 tree.setXpos(tp.getX());
1111 tree.setYpos(tp.getY());
1112 tree.setId(makeHashCode(tp, null));
1122 * store forward refs from an annotationRow to any groups
1124 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1127 for (SequenceI sq : jal.getSequences())
1129 // Store annotation on dataset sequences only
1130 AlignmentAnnotation[] aa = sq.getAnnotation();
1131 if (aa != null && aa.length > 0)
1133 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1140 if (jal.getAlignmentAnnotation() != null)
1142 // Store the annotation shown on the alignment.
1143 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1144 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1149 if (jal.getGroups() != null)
1151 JGroup[] groups = new JGroup[jal.getGroups().size()];
1153 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1155 JGroup jGroup = new JGroup();
1156 groups[++i] = jGroup;
1158 jGroup.setStart(sg.getStartRes());
1159 jGroup.setEnd(sg.getEndRes());
1160 jGroup.setName(sg.getName());
1161 if (groupRefs.containsKey(sg))
1163 // group has references so set its ID field
1164 jGroup.setId(groupRefs.get(sg));
1168 if (sg.cs.conservationApplied())
1170 jGroup.setConsThreshold(sg.cs.getConservationInc());
1172 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1174 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1178 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1181 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1183 jGroup.setColour("AnnotationColourGradient");
1184 jGroup.setAnnotationColours(constructAnnotationColours(
1185 (jalview.schemes.AnnotationColourGradient) sg.cs,
1188 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1190 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1194 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1197 jGroup.setPidThreshold(sg.cs.getThreshold());
1200 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1201 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1202 jGroup.setDisplayText(sg.getDisplayText());
1203 jGroup.setColourText(sg.getColourText());
1204 jGroup.setTextCol1(sg.textColour.getRGB());
1205 jGroup.setTextCol2(sg.textColour2.getRGB());
1206 jGroup.setTextColThreshold(sg.thresholdTextColour);
1207 jGroup.setShowUnconserved(sg.getShowNonconserved());
1208 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1209 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1210 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1211 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1212 for (SequenceI seq : sg.getSequences())
1214 jGroup.addSeq(seqHash(seq));
1218 jms.setJGroup(groups);
1222 // /////////SAVE VIEWPORT
1223 Viewport view = new Viewport();
1224 view.setTitle(ap.alignFrame.getTitle());
1225 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1226 av.getSequenceSetId()));
1227 view.setId(av.getViewId());
1228 if (av.getCodingComplement() != null)
1230 view.setComplementId(av.getCodingComplement().getViewId());
1232 view.setViewName(av.viewName);
1233 view.setGatheredViews(av.isGatherViewsHere());
1235 Rectangle size = ap.av.getExplodedGeometry();
1236 Rectangle position = size;
1239 size = ap.alignFrame.getBounds();
1240 if (av.getCodingComplement() != null)
1242 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1250 view.setXpos(position.x);
1251 view.setYpos(position.y);
1253 view.setWidth(size.width);
1254 view.setHeight(size.height);
1256 view.setStartRes(av.startRes);
1257 view.setStartSeq(av.startSeq);
1259 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1261 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1264 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1266 AnnotationColours ac = constructAnnotationColours(
1267 (jalview.schemes.AnnotationColourGradient) av
1268 .getGlobalColourScheme(),
1271 view.setAnnotationColours(ac);
1272 view.setBgColour("AnnotationColourGradient");
1276 view.setBgColour(ColourSchemeProperty.getColourName(av
1277 .getGlobalColourScheme()));
1280 ColourSchemeI cs = av.getGlobalColourScheme();
1284 if (cs.conservationApplied())
1286 view.setConsThreshold(cs.getConservationInc());
1287 if (cs instanceof jalview.schemes.UserColourScheme)
1289 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1293 if (cs instanceof ResidueColourScheme)
1295 view.setPidThreshold(cs.getThreshold());
1299 view.setConservationSelected(av.getConservationSelected());
1300 view.setPidSelected(av.getAbovePIDThreshold());
1301 view.setFontName(av.font.getName());
1302 view.setFontSize(av.font.getSize());
1303 view.setFontStyle(av.font.getStyle());
1304 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1305 view.setRenderGaps(av.isRenderGaps());
1306 view.setShowAnnotation(av.isShowAnnotation());
1307 view.setShowBoxes(av.getShowBoxes());
1308 view.setShowColourText(av.getColourText());
1309 view.setShowFullId(av.getShowJVSuffix());
1310 view.setRightAlignIds(av.isRightAlignIds());
1311 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1312 view.setShowText(av.getShowText());
1313 view.setShowUnconserved(av.getShowUnconserved());
1314 view.setWrapAlignment(av.getWrapAlignment());
1315 view.setTextCol1(av.getTextColour().getRGB());
1316 view.setTextCol2(av.getTextColour2().getRGB());
1317 view.setTextColThreshold(av.getThresholdTextColour());
1318 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1319 view.setShowSequenceLogo(av.isShowSequenceLogo());
1320 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1321 view.setShowGroupConsensus(av.isShowGroupConsensus());
1322 view.setShowGroupConservation(av.isShowGroupConservation());
1323 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1324 view.setShowDbRefTooltip(av.isShowDBRefs());
1325 view.setFollowHighlight(av.isFollowHighlight());
1326 view.setFollowSelection(av.followSelection);
1327 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1328 if (av.getFeaturesDisplayed() != null)
1330 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1332 String[] renderOrder = ap.getSeqPanel().seqCanvas
1333 .getFeatureRenderer().getRenderOrder()
1334 .toArray(new String[0]);
1336 Vector<String> settingsAdded = new Vector<String>();
1337 if (renderOrder != null)
1339 for (String featureType : renderOrder)
1341 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1342 .getFeatureRenderer()
1343 .getFeatureStyle(featureType);
1344 Setting setting = new Setting();
1345 setting.setType(featureType);
1346 if (!fcol.isSimpleColour())
1348 setting.setColour(fcol.getMaxColour().getRGB());
1349 setting.setMincolour(fcol.getMinColour().getRGB());
1350 setting.setMin(fcol.getMin());
1351 setting.setMax(fcol.getMax());
1352 setting.setColourByLabel(fcol.isColourByLabel());
1353 setting.setAutoScale(fcol.isAutoScaled());
1354 setting.setThreshold(fcol.getThreshold());
1355 // -1 = No threshold, 0 = Below, 1 = Above
1356 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1357 : (fcol.isBelowThreshold() ? 0 : -1));
1361 setting.setColour(fcol.getColour().getRGB());
1364 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1366 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1367 .getOrder(featureType);
1370 setting.setOrder(rorder);
1372 fs.addSetting(setting);
1373 settingsAdded.addElement(featureType);
1377 // is groups actually supposed to be a map here ?
1378 Iterator<String> en = ap.getSeqPanel().seqCanvas
1379 .getFeatureRenderer()
1380 .getFeatureGroups().iterator();
1381 Vector<String> groupsAdded = new Vector<String>();
1382 while (en.hasNext())
1384 String grp = en.next();
1385 if (groupsAdded.contains(grp))
1389 Group g = new Group();
1391 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1392 .getFeatureRenderer().checkGroupVisibility(grp, false))
1395 groupsAdded.addElement(grp);
1397 jms.setFeatureSettings(fs);
1400 if (av.hasHiddenColumns())
1402 if (av.getColumnSelection() == null
1403 || av.getColumnSelection().getHiddenColumns() == null)
1405 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1409 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1412 int[] region = av.getColumnSelection().getHiddenColumns()
1414 HiddenColumns hc = new HiddenColumns();
1415 hc.setStart(region[0]);
1416 hc.setEnd(region[1]);
1417 view.addHiddenColumns(hc);
1421 if (calcIdSet.size() > 0)
1423 for (String calcId : calcIdSet)
1425 if (calcId.trim().length() > 0)
1427 CalcIdParam cidp = createCalcIdParam(calcId, av);
1428 // Some calcIds have no parameters.
1431 view.addCalcIdParam(cidp);
1437 jms.addViewport(view);
1439 object.setJalviewModelSequence(jms);
1440 object.getVamsasModel().addSequenceSet(vamsasSet);
1442 if (jout != null && fileName != null)
1444 // We may not want to write the object to disk,
1445 // eg we can copy the alignViewport to a new view object
1446 // using save and then load
1449 System.out.println("Writing jar entry " + fileName);
1450 JarEntry entry = new JarEntry(fileName);
1451 jout.putNextEntry(entry);
1452 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1454 Marshaller marshaller = new Marshaller(pout);
1455 marshaller.marshal(object);
1458 } catch (Exception ex)
1460 // TODO: raise error in GUI if marshalling failed.
1461 ex.printStackTrace();
1468 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1469 * for each viewer, with
1471 * <li>viewer geometry (position, size, split pane divider location)</li>
1472 * <li>index of the selected structure in the viewer (currently shows gapped
1474 * <li>the id of the annotation holding RNA secondary structure</li>
1475 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1477 * Varna viewer state is also written out (in native Varna XML) to separate
1478 * project jar entries. A separate entry is written for each RNA structure
1479 * displayed, with the naming convention
1481 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1489 * @param storeDataset
1491 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1492 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1493 boolean storeDataset)
1495 if (Desktop.desktop == null)
1499 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1500 for (int f = frames.length - 1; f > -1; f--)
1502 if (frames[f] instanceof AppVarna)
1504 AppVarna varna = (AppVarna) frames[f];
1506 * link the sequence to every viewer that is showing it and is linked to
1507 * its alignment panel
1509 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1511 String viewId = varna.getViewId();
1512 RnaViewer rna = new RnaViewer();
1513 rna.setViewId(viewId);
1514 rna.setTitle(varna.getTitle());
1515 rna.setXpos(varna.getX());
1516 rna.setYpos(varna.getY());
1517 rna.setWidth(varna.getWidth());
1518 rna.setHeight(varna.getHeight());
1519 rna.setDividerLocation(varna.getDividerLocation());
1520 rna.setSelectedRna(varna.getSelectedIndex());
1521 jseq.addRnaViewer(rna);
1524 * Store each Varna panel's state once in the project per sequence.
1525 * First time through only (storeDataset==false)
1527 // boolean storeSessions = false;
1528 // String sequenceViewId = viewId + seqsToIds.get(jds);
1529 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1531 // viewIds.add(sequenceViewId);
1532 // storeSessions = true;
1534 for (RnaModel model : varna.getModels())
1536 if (model.seq == jds)
1539 * VARNA saves each view (sequence or alignment secondary
1540 * structure, gapped or trimmed) as a separate XML file
1542 String jarEntryName = rnaSessions.get(model);
1543 if (jarEntryName == null)
1546 String varnaStateFile = varna.getStateInfo(model.rna);
1547 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1548 copyFileToJar(jout, varnaStateFile, jarEntryName);
1549 rnaSessions.put(model, jarEntryName);
1551 SecondaryStructure ss = new SecondaryStructure();
1552 String annotationId = varna.getAnnotation(jds).annotationId;
1553 ss.setAnnotationId(annotationId);
1554 ss.setViewerState(jarEntryName);
1555 ss.setGapped(model.gapped);
1556 ss.setTitle(model.title);
1557 rna.addSecondaryStructure(ss);
1566 * Copy the contents of a file to a new entry added to the output jar
1570 * @param jarEntryName
1572 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1573 String jarEntryName)
1575 DataInputStream dis = null;
1578 File file = new File(infilePath);
1579 if (file.exists() && jout != null)
1581 dis = new DataInputStream(new FileInputStream(file));
1582 byte[] data = new byte[(int) file.length()];
1583 dis.readFully(data);
1584 writeJarEntry(jout, jarEntryName, data);
1586 } catch (Exception ex)
1588 ex.printStackTrace();
1596 } catch (IOException e)
1605 * Write the data to a new entry of given name in the output jar file
1608 * @param jarEntryName
1610 * @throws IOException
1612 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1613 byte[] data) throws IOException
1617 System.out.println("Writing jar entry " + jarEntryName);
1618 jout.putNextEntry(new JarEntry(jarEntryName));
1619 DataOutputStream dout = new DataOutputStream(jout);
1620 dout.write(data, 0, data.length);
1627 * Save the state of a structure viewer
1632 * the archive XML element under which to save the state
1635 * @param matchedFile
1639 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1640 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1641 String matchedFile, StructureViewerBase viewFrame)
1643 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1646 * Look for any bindings for this viewer to the PDB file of interest
1647 * (including part matches excluding chain id)
1649 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1651 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1652 final String pdbId = pdbentry.getId();
1653 if (!pdbId.equals(entry.getId())
1654 && !(entry.getId().length() > 4 && entry.getId()
1655 .toLowerCase().startsWith(pdbId.toLowerCase())))
1658 * not interested in a binding to a different PDB entry here
1662 if (matchedFile == null)
1664 matchedFile = pdbentry.getFile();
1666 else if (!matchedFile.equals(pdbentry.getFile()))
1669 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1670 + pdbentry.getFile());
1674 // can get at it if the ID
1675 // match is ambiguous (e.g.
1678 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1680 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1681 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1683 StructureState state = new StructureState();
1684 state.setVisible(true);
1685 state.setXpos(viewFrame.getX());
1686 state.setYpos(viewFrame.getY());
1687 state.setWidth(viewFrame.getWidth());
1688 state.setHeight(viewFrame.getHeight());
1689 final String viewId = viewFrame.getViewId();
1690 state.setViewId(viewId);
1691 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1692 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1693 state.setColourByJmol(viewFrame.isColouredByViewer());
1694 state.setType(viewFrame.getViewerType().toString());
1695 pdb.addStructureState(state);
1702 private AnnotationColours constructAnnotationColours(
1703 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1704 JalviewModelSequence jms)
1706 AnnotationColours ac = new AnnotationColours();
1707 ac.setAboveThreshold(acg.getAboveThreshold());
1708 ac.setThreshold(acg.getAnnotationThreshold());
1709 ac.setAnnotation(acg.getAnnotation());
1710 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1712 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1717 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1721 ac.setMaxColour(acg.getMaxColour().getRGB());
1722 ac.setMinColour(acg.getMinColour().getRGB());
1723 ac.setPerSequence(acg.isSeqAssociated());
1724 ac.setPredefinedColours(acg.isPredefinedColours());
1728 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1729 IdentityHashMap<SequenceGroup, String> groupRefs,
1730 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1731 SequenceSet vamsasSet)
1734 for (int i = 0; i < aa.length; i++)
1736 Annotation an = new Annotation();
1738 AlignmentAnnotation annotation = aa[i];
1739 if (annotation.annotationId != null)
1741 annotationIds.put(annotation.annotationId, annotation);
1744 an.setId(annotation.annotationId);
1746 an.setVisible(annotation.visible);
1748 an.setDescription(annotation.description);
1750 if (annotation.sequenceRef != null)
1752 // 2.9 JAL-1781 xref on sequence id rather than name
1753 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1755 if (annotation.groupRef != null)
1757 String groupIdr = groupRefs.get(annotation.groupRef);
1758 if (groupIdr == null)
1760 // make a locally unique String
1762 annotation.groupRef,
1763 groupIdr = ("" + System.currentTimeMillis()
1764 + annotation.groupRef.getName() + groupRefs
1767 an.setGroupRef(groupIdr.toString());
1770 // store all visualization attributes for annotation
1771 an.setGraphHeight(annotation.graphHeight);
1772 an.setCentreColLabels(annotation.centreColLabels);
1773 an.setScaleColLabels(annotation.scaleColLabel);
1774 an.setShowAllColLabels(annotation.showAllColLabels);
1775 an.setBelowAlignment(annotation.belowAlignment);
1777 if (annotation.graph > 0)
1780 an.setGraphType(annotation.graph);
1781 an.setGraphGroup(annotation.graphGroup);
1782 if (annotation.getThreshold() != null)
1784 ThresholdLine line = new ThresholdLine();
1785 line.setLabel(annotation.getThreshold().label);
1786 line.setValue(annotation.getThreshold().value);
1787 line.setColour(annotation.getThreshold().colour.getRGB());
1788 an.setThresholdLine(line);
1796 an.setLabel(annotation.label);
1798 if (annotation == av.getAlignmentQualityAnnot()
1799 || annotation == av.getAlignmentConservationAnnotation()
1800 || annotation == av.getAlignmentConsensusAnnotation()
1801 || annotation.autoCalculated)
1803 // new way of indicating autocalculated annotation -
1804 an.setAutoCalculated(annotation.autoCalculated);
1806 if (annotation.hasScore())
1808 an.setScore(annotation.getScore());
1811 if (annotation.getCalcId() != null)
1813 calcIdSet.add(annotation.getCalcId());
1814 an.setCalcId(annotation.getCalcId());
1816 if (annotation.hasProperties())
1818 for (String pr : annotation.getProperties())
1820 Property prop = new Property();
1822 prop.setValue(annotation.getProperty(pr));
1823 an.addProperty(prop);
1827 AnnotationElement ae;
1828 if (annotation.annotations != null)
1830 an.setScoreOnly(false);
1831 for (int a = 0; a < annotation.annotations.length; a++)
1833 if ((annotation == null) || (annotation.annotations[a] == null))
1838 ae = new AnnotationElement();
1839 if (annotation.annotations[a].description != null)
1841 ae.setDescription(annotation.annotations[a].description);
1843 if (annotation.annotations[a].displayCharacter != null)
1845 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1848 if (!Float.isNaN(annotation.annotations[a].value))
1850 ae.setValue(annotation.annotations[a].value);
1854 if (annotation.annotations[a].secondaryStructure > ' ')
1856 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1860 if (annotation.annotations[a].colour != null
1861 && annotation.annotations[a].colour != java.awt.Color.black)
1863 ae.setColour(annotation.annotations[a].colour.getRGB());
1866 an.addAnnotationElement(ae);
1867 if (annotation.autoCalculated)
1869 // only write one non-null entry into the annotation row -
1870 // sufficient to get the visualization attributes necessary to
1878 an.setScoreOnly(true);
1880 if (!storeDS || (storeDS && !annotation.autoCalculated))
1882 // skip autocalculated annotation - these are only provided for
1884 vamsasSet.addAnnotation(an);
1890 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1892 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1893 if (settings != null)
1895 CalcIdParam vCalcIdParam = new CalcIdParam();
1896 vCalcIdParam.setCalcId(calcId);
1897 vCalcIdParam.addServiceURL(settings.getServiceURI());
1898 // generic URI allowing a third party to resolve another instance of the
1899 // service used for this calculation
1900 for (String urls : settings.getServiceURLs())
1902 vCalcIdParam.addServiceURL(urls);
1904 vCalcIdParam.setVersion("1.0");
1905 if (settings.getPreset() != null)
1907 WsParamSetI setting = settings.getPreset();
1908 vCalcIdParam.setName(setting.getName());
1909 vCalcIdParam.setDescription(setting.getDescription());
1913 vCalcIdParam.setName("");
1914 vCalcIdParam.setDescription("Last used parameters");
1916 // need to be able to recover 1) settings 2) user-defined presets or
1917 // recreate settings from preset 3) predefined settings provided by
1918 // service - or settings that can be transferred (or discarded)
1919 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1921 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1922 // todo - decide if updateImmediately is needed for any projects.
1924 return vCalcIdParam;
1929 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1932 if (calcIdParam.getVersion().equals("1.0"))
1934 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1935 .getPreferredServiceFor(calcIdParam.getServiceURL());
1936 if (service != null)
1938 WsParamSetI parmSet = null;
1941 parmSet = service.getParamStore().parseServiceParameterFile(
1942 calcIdParam.getName(), calcIdParam.getDescription(),
1943 calcIdParam.getServiceURL(),
1944 calcIdParam.getParameters().replace("|\\n|", "\n"));
1945 } catch (IOException x)
1947 warn("Couldn't parse parameter data for "
1948 + calcIdParam.getCalcId(), x);
1951 List<ArgumentI> argList = null;
1952 if (calcIdParam.getName().length() > 0)
1954 parmSet = service.getParamStore()
1955 .getPreset(calcIdParam.getName());
1956 if (parmSet != null)
1958 // TODO : check we have a good match with settings in AACon -
1959 // otherwise we'll need to create a new preset
1964 argList = parmSet.getArguments();
1967 AAConSettings settings = new AAConSettings(
1968 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1969 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1970 calcIdParam.isNeedsUpdate());
1975 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1979 throw new Error(MessageManager.formatMessage(
1980 "error.unsupported_version_calcIdparam",
1981 new Object[] { calcIdParam.toString() }));
1985 * External mapping between jalview objects and objects yielding a valid and
1986 * unique object ID string. This is null for normal Jalview project IO, but
1987 * non-null when a jalview project is being read or written as part of a
1990 IdentityHashMap jv2vobj = null;
1993 * Construct a unique ID for jvobj using either existing bindings or if none
1994 * exist, the result of the hashcode call for the object.
1997 * jalview data object
1998 * @return unique ID for referring to jvobj
2000 private String makeHashCode(Object jvobj, String altCode)
2002 if (jv2vobj != null)
2004 Object id = jv2vobj.get(jvobj);
2007 return id.toString();
2009 // check string ID mappings
2010 if (jvids2vobj != null && jvobj instanceof String)
2012 id = jvids2vobj.get(jvobj);
2016 return id.toString();
2018 // give up and warn that something has gone wrong
2019 warn("Cannot find ID for object in external mapping : " + jvobj);
2025 * return local jalview object mapped to ID, if it exists
2029 * @return null or object bound to idcode
2031 private Object retrieveExistingObj(String idcode)
2033 if (idcode != null && vobj2jv != null)
2035 return vobj2jv.get(idcode);
2041 * binding from ID strings from external mapping table to jalview data model
2044 private Hashtable vobj2jv;
2046 private Sequence createVamsasSequence(String id, SequenceI jds)
2048 return createVamsasSequence(true, id, jds, null);
2051 private Sequence createVamsasSequence(boolean recurse, String id,
2052 SequenceI jds, SequenceI parentseq)
2054 Sequence vamsasSeq = new Sequence();
2055 vamsasSeq.setId(id);
2056 vamsasSeq.setName(jds.getName());
2057 vamsasSeq.setSequence(jds.getSequenceAsString());
2058 vamsasSeq.setDescription(jds.getDescription());
2059 jalview.datamodel.DBRefEntry[] dbrefs = null;
2060 if (jds.getDatasetSequence() != null)
2062 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2066 // seqId==dsseqid so we can tell which sequences really are
2067 // dataset sequences only
2068 vamsasSeq.setDsseqid(id);
2069 dbrefs = jds.getDBRefs();
2070 if (parentseq == null)
2077 for (int d = 0; d < dbrefs.length; d++)
2079 DBRef dbref = new DBRef();
2080 dbref.setSource(dbrefs[d].getSource());
2081 dbref.setVersion(dbrefs[d].getVersion());
2082 dbref.setAccessionId(dbrefs[d].getAccessionId());
2083 if (dbrefs[d].hasMap())
2085 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2087 dbref.setMapping(mp);
2089 vamsasSeq.addDBRef(dbref);
2095 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2096 SequenceI parentseq, SequenceI jds, boolean recurse)
2099 if (jmp.getMap() != null)
2103 jalview.util.MapList mlst = jmp.getMap();
2104 List<int[]> r = mlst.getFromRanges();
2105 for (int[] range : r)
2107 MapListFrom mfrom = new MapListFrom();
2108 mfrom.setStart(range[0]);
2109 mfrom.setEnd(range[1]);
2110 mp.addMapListFrom(mfrom);
2112 r = mlst.getToRanges();
2113 for (int[] range : r)
2115 MapListTo mto = new MapListTo();
2116 mto.setStart(range[0]);
2117 mto.setEnd(range[1]);
2118 mp.addMapListTo(mto);
2120 mp.setMapFromUnit(mlst.getFromRatio());
2121 mp.setMapToUnit(mlst.getToRatio());
2122 if (jmp.getTo() != null)
2124 MappingChoice mpc = new MappingChoice();
2126 // check/create ID for the sequence referenced by getTo()
2129 SequenceI ps = null;
2130 if (parentseq != jmp.getTo()
2131 && parentseq.getDatasetSequence() != jmp.getTo())
2133 // chaining dbref rather than a handshaking one
2134 jmpid = seqHash(ps = jmp.getTo());
2138 jmpid = seqHash(ps = parentseq);
2140 mpc.setDseqFor(jmpid);
2141 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2143 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2144 seqRefIds.put(mpc.getDseqFor(), ps);
2148 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2151 mp.setMappingChoice(mpc);
2157 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2158 List<UserColourScheme> userColours, JalviewModelSequence jms)
2161 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2162 boolean newucs = false;
2163 if (!userColours.contains(ucs))
2165 userColours.add(ucs);
2168 id = "ucs" + userColours.indexOf(ucs);
2171 // actually create the scheme's entry in the XML model
2172 java.awt.Color[] colours = ucs.getColours();
2173 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2174 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2176 for (int i = 0; i < colours.length; i++)
2178 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2179 col.setName(ResidueProperties.aa[i]);
2180 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2181 jbucs.addColour(col);
2183 if (ucs.getLowerCaseColours() != null)
2185 colours = ucs.getLowerCaseColours();
2186 for (int i = 0; i < colours.length; i++)
2188 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2189 col.setName(ResidueProperties.aa[i].toLowerCase());
2190 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2191 jbucs.addColour(col);
2196 uc.setUserColourScheme(jbucs);
2197 jms.addUserColours(uc);
2203 jalview.schemes.UserColourScheme getUserColourScheme(
2204 JalviewModelSequence jms, String id)
2206 UserColours[] uc = jms.getUserColours();
2207 UserColours colours = null;
2209 for (int i = 0; i < uc.length; i++)
2211 if (uc[i].getId().equals(id))
2219 java.awt.Color[] newColours = new java.awt.Color[24];
2221 for (int i = 0; i < 24; i++)
2223 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2224 .getUserColourScheme().getColour(i).getRGB(), 16));
2227 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2230 if (colours.getUserColourScheme().getColourCount() > 24)
2232 newColours = new java.awt.Color[23];
2233 for (int i = 0; i < 23; i++)
2235 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2236 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2238 ucs.setLowerCaseColours(newColours);
2245 * contains last error message (if any) encountered by XML loader.
2247 String errorMessage = null;
2250 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2251 * exceptions are raised during project XML parsing
2253 public boolean attemptversion1parse = true;
2256 * Load a jalview project archive from a jar file
2259 * - HTTP URL or filename
2261 public AlignFrame loadJalviewAlign(final String file)
2264 jalview.gui.AlignFrame af = null;
2268 // create list to store references for any new Jmol viewers created
2269 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2270 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2271 // Workaround is to make sure caller implements the JarInputStreamProvider
2273 // so we can re-open the jar input stream for each entry.
2275 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2276 af = loadJalviewAlign(jprovider);
2278 } catch (MalformedURLException e)
2280 errorMessage = "Invalid URL format for '" + file + "'";
2286 SwingUtilities.invokeAndWait(new Runnable()
2291 setLoadingFinishedForNewStructureViewers();
2294 } catch (Exception x)
2296 System.err.println("Error loading alignment: " + x.getMessage());
2302 private jarInputStreamProvider createjarInputStreamProvider(
2303 final String file) throws MalformedURLException
2306 errorMessage = null;
2307 uniqueSetSuffix = null;
2309 viewportsAdded.clear();
2310 frefedSequence = null;
2312 if (file.startsWith("http://"))
2314 url = new URL(file);
2316 final URL _url = url;
2317 return new jarInputStreamProvider()
2321 public JarInputStream getJarInputStream() throws IOException
2325 return new JarInputStream(_url.openStream());
2329 return new JarInputStream(new FileInputStream(file));
2334 public String getFilename()
2342 * Recover jalview session from a jalview project archive. Caller may
2343 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2344 * themselves. Any null fields will be initialised with default values,
2345 * non-null fields are left alone.
2350 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2352 errorMessage = null;
2353 if (uniqueSetSuffix == null)
2355 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2357 if (seqRefIds == null)
2361 AlignFrame af = null, _af = null;
2362 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2363 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2364 final String file = jprovider.getFilename();
2367 JarInputStream jin = null;
2368 JarEntry jarentry = null;
2373 jin = jprovider.getJarInputStream();
2374 for (int i = 0; i < entryCount; i++)
2376 jarentry = jin.getNextJarEntry();
2379 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2381 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2382 JalviewModel object = new JalviewModel();
2384 Unmarshaller unmar = new Unmarshaller(object);
2385 unmar.setValidation(false);
2386 object = (JalviewModel) unmar.unmarshal(in);
2387 if (true) // !skipViewport(object))
2389 _af = loadFromObject(object, file, true, jprovider);
2391 && object.getJalviewModelSequence().getViewportCount() > 0)
2395 // store a reference to the first view
2398 if (_af.viewport.isGatherViewsHere())
2400 // if this is a gathered view, keep its reference since
2401 // after gathering views, only this frame will remain
2403 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2405 // Save dataset to register mappings once all resolved
2406 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2407 af.viewport.getAlignment().getDataset());
2412 else if (jarentry != null)
2414 // Some other file here.
2417 } while (jarentry != null);
2418 resolveFrefedSequences();
2419 } catch (IOException ex)
2421 ex.printStackTrace();
2422 errorMessage = "Couldn't locate Jalview XML file : " + file;
2423 System.err.println("Exception whilst loading jalview XML file : "
2425 } catch (Exception ex)
2427 System.err.println("Parsing as Jalview Version 2 file failed.");
2428 ex.printStackTrace(System.err);
2429 if (attemptversion1parse)
2431 // Is Version 1 Jar file?
2434 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2435 } catch (Exception ex2)
2437 System.err.println("Exception whilst loading as jalviewXMLV1:");
2438 ex2.printStackTrace();
2442 if (Desktop.instance != null)
2444 Desktop.instance.stopLoading();
2448 System.out.println("Successfully loaded archive file");
2451 ex.printStackTrace();
2453 System.err.println("Exception whilst loading jalview XML file : "
2455 } catch (OutOfMemoryError e)
2457 // Don't use the OOM Window here
2458 errorMessage = "Out of memory loading jalview XML file";
2459 System.err.println("Out of memory whilst loading jalview XML file");
2460 e.printStackTrace();
2464 * Regather multiple views (with the same sequence set id) to the frame (if
2465 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2466 * views instead of separate frames. Note this doesn't restore a state where
2467 * some expanded views in turn have tabbed views - the last "first tab" read
2468 * in will play the role of gatherer for all.
2470 for (AlignFrame fr : gatherToThisFrame.values())
2472 Desktop.instance.gatherViews(fr);
2475 restoreSplitFrames();
2476 for (AlignmentI ds : importedDatasets.keySet())
2478 if (ds.getCodonFrames() != null)
2480 StructureSelectionManager.getStructureSelectionManager(
2481 Desktop.instance).registerMappings(ds.getCodonFrames());
2484 if (errorMessage != null)
2489 if (Desktop.instance != null)
2491 Desktop.instance.stopLoading();
2498 * Try to reconstruct and display SplitFrame windows, where each contains
2499 * complementary dna and protein alignments. Done by pairing up AlignFrame
2500 * objects (created earlier) which have complementary viewport ids associated.
2502 protected void restoreSplitFrames()
2504 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2505 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2506 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2509 * Identify the DNA alignments
2511 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2514 AlignFrame af = candidate.getValue();
2515 if (af.getViewport().getAlignment().isNucleotide())
2517 dna.put(candidate.getKey().getId(), af);
2522 * Try to match up the protein complements
2524 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2527 AlignFrame af = candidate.getValue();
2528 if (!af.getViewport().getAlignment().isNucleotide())
2530 String complementId = candidate.getKey().getComplementId();
2531 // only non-null complements should be in the Map
2532 if (complementId != null && dna.containsKey(complementId))
2534 final AlignFrame dnaFrame = dna.get(complementId);
2535 SplitFrame sf = createSplitFrame(dnaFrame, af);
2536 addedToSplitFrames.add(dnaFrame);
2537 addedToSplitFrames.add(af);
2538 if (af.viewport.isGatherViewsHere())
2547 * Open any that we failed to pair up (which shouldn't happen!) as
2548 * standalone AlignFrame's.
2550 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2553 AlignFrame af = candidate.getValue();
2554 if (!addedToSplitFrames.contains(af))
2556 Viewport view = candidate.getKey();
2557 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2559 System.err.println("Failed to restore view " + view.getTitle()
2560 + " to split frame");
2565 * Gather back into tabbed views as flagged.
2567 for (SplitFrame sf : gatherTo)
2569 Desktop.instance.gatherViews(sf);
2572 splitFrameCandidates.clear();
2576 * Construct and display one SplitFrame holding DNA and protein alignments.
2579 * @param proteinFrame
2582 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2583 AlignFrame proteinFrame)
2585 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2586 String title = MessageManager.getString("label.linked_view_title");
2587 int width = (int) dnaFrame.getBounds().getWidth();
2588 int height = (int) (dnaFrame.getBounds().getHeight()
2589 + proteinFrame.getBounds().getHeight() + 50);
2592 * SplitFrame location is saved to both enclosed frames
2594 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2595 Desktop.addInternalFrame(splitFrame, title, width, height);
2598 * And compute cDNA consensus (couldn't do earlier with consensus as
2599 * mappings were not yet present)
2601 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2607 * check errorMessage for a valid error message and raise an error box in the
2608 * GUI or write the current errorMessage to stderr and then clear the error
2611 protected void reportErrors()
2613 reportErrors(false);
2616 protected void reportErrors(final boolean saving)
2618 if (errorMessage != null)
2620 final String finalErrorMessage = errorMessage;
2623 javax.swing.SwingUtilities.invokeLater(new Runnable()
2628 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2629 finalErrorMessage, "Error "
2630 + (saving ? "saving" : "loading")
2631 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2637 System.err.println("Problem loading Jalview file: " + errorMessage);
2640 errorMessage = null;
2643 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2646 * when set, local views will be updated from view stored in JalviewXML
2647 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2648 * sync if this is set to true.
2650 private final boolean updateLocalViews = false;
2653 * Returns the path to a temporary file holding the PDB file for the given PDB
2654 * id. The first time of asking, searches for a file of that name in the
2655 * Jalview project jar, and copies it to a new temporary file. Any repeat
2656 * requests just return the path to the file previously created.
2662 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2665 if (alreadyLoadedPDB.containsKey(pdbId))
2667 return alreadyLoadedPDB.get(pdbId).toString();
2670 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2672 if (tempFile != null)
2674 alreadyLoadedPDB.put(pdbId, tempFile);
2680 * Copies the jar entry of given name to a new temporary file and returns the
2681 * path to the file, or null if the entry is not found.
2684 * @param jarEntryName
2686 * a prefix for the temporary file name, must be at least three
2689 * null or original file - so new file can be given the same suffix
2693 protected String copyJarEntry(jarInputStreamProvider jprovider,
2694 String jarEntryName, String prefix, String origFile)
2696 BufferedReader in = null;
2697 PrintWriter out = null;
2698 String suffix = ".tmp";
2699 if (origFile == null)
2701 origFile = jarEntryName;
2703 int sfpos = origFile.lastIndexOf(".");
2704 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2706 suffix = "." + origFile.substring(sfpos + 1);
2710 JarInputStream jin = jprovider.getJarInputStream();
2712 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2713 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2714 * FileInputStream(jprovider)); }
2717 JarEntry entry = null;
2720 entry = jin.getNextJarEntry();
2721 } while (entry != null && !entry.getName().equals(jarEntryName));
2724 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2725 File outFile = File.createTempFile(prefix, suffix);
2726 outFile.deleteOnExit();
2727 out = new PrintWriter(new FileOutputStream(outFile));
2730 while ((data = in.readLine()) != null)
2735 String t = outFile.getAbsolutePath();
2740 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2742 } catch (Exception ex)
2744 ex.printStackTrace();
2752 } catch (IOException e)
2766 private class JvAnnotRow
2768 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2775 * persisted version of annotation row from which to take vis properties
2777 public jalview.datamodel.AlignmentAnnotation template;
2780 * original position of the annotation row in the alignment
2786 * Load alignment frame from jalview XML DOM object
2791 * filename source string
2792 * @param loadTreesAndStructures
2793 * when false only create Viewport
2795 * data source provider
2796 * @return alignment frame created from view stored in DOM
2798 AlignFrame loadFromObject(JalviewModel object, String file,
2799 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2801 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2802 Sequence[] vamsasSeq = vamsasSet.getSequence();
2804 JalviewModelSequence jms = object.getJalviewModelSequence();
2806 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2809 // ////////////////////////////////
2812 List<SequenceI> hiddenSeqs = null;
2815 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2817 boolean multipleView = false;
2818 SequenceI referenceseqForView = null;
2819 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2820 int vi = 0; // counter in vamsasSeq array
2821 for (int i = 0; i < jseqs.length; i++)
2823 String seqId = jseqs[i].getId();
2825 SequenceI tmpSeq = seqRefIds.get(seqId);
2828 if (!incompleteSeqs.containsKey(seqId))
2830 // may not need this check, but keep it for at least 2.9,1 release
2831 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2834 .println("Warning JAL-2154 regression: updating start/end for sequence "
2835 + tmpSeq.toString() + " to " + jseqs[i]);
2838 incompleteSeqs.remove(seqId);
2840 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2842 // most likely we are reading a dataset XML document so
2843 // update from vamsasSeq section of XML for this sequence
2844 tmpSeq.setName(vamsasSeq[vi].getName());
2845 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2846 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2851 // reading multiple views, so vamsasSeq set is a subset of JSeq
2852 multipleView = true;
2854 tmpSeq.setStart(jseqs[i].getStart());
2855 tmpSeq.setEnd(jseqs[i].getEnd());
2856 tmpseqs.add(tmpSeq);
2860 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2861 vamsasSeq[vi].getSequence());
2862 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2863 tmpSeq.setStart(jseqs[i].getStart());
2864 tmpSeq.setEnd(jseqs[i].getEnd());
2865 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2866 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2867 tmpseqs.add(tmpSeq);
2871 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2873 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2876 if (jseqs[i].getHidden())
2878 if (hiddenSeqs == null)
2880 hiddenSeqs = new ArrayList<SequenceI>();
2883 hiddenSeqs.add(tmpSeq);
2888 // Create the alignment object from the sequence set
2889 // ///////////////////////////////
2890 SequenceI[] orderedSeqs = tmpseqs
2891 .toArray(new SequenceI[tmpseqs.size()]);
2893 AlignmentI al = null;
2894 // so we must create or recover the dataset alignment before going further
2895 // ///////////////////////////////
2896 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2898 // older jalview projects do not have a dataset - so creat alignment and
2900 al = new Alignment(orderedSeqs);
2901 al.setDataset(null);
2905 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2908 // we are importing a dataset record, so
2909 // recover reference to an alignment already materialsed as dataset
2910 al = getDatasetFor(vamsasSet.getDatasetId());
2914 // materialse the alignment
2915 al = new Alignment(orderedSeqs);
2919 addDatasetRef(vamsasSet.getDatasetId(), al);
2922 // finally, verify all data in vamsasSet is actually present in al
2923 // passing on flag indicating if it is actually a stored dataset
2924 recoverDatasetFor(vamsasSet, al, isdsal);
2927 if (referenceseqForView != null)
2929 al.setSeqrep(referenceseqForView);
2931 // / Add the alignment properties
2932 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2934 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2935 al.setProperty(ssp.getKey(), ssp.getValue());
2938 // ///////////////////////////////
2940 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2943 // load sequence features, database references and any associated PDB
2944 // structures for the alignment
2946 // prior to 2.10, this part would only be executed the first time a
2947 // sequence was encountered, but not afterwards.
2948 // now, for 2.10 projects, this is also done if the xml doc includes
2949 // dataset sequences not actually present in any particular view.
2951 for (int i = 0; i < vamsasSeq.length; i++)
2953 if (jseqs[i].getFeaturesCount() > 0)
2955 Features[] features = jseqs[i].getFeatures();
2956 for (int f = 0; f < features.length; f++)
2958 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2959 features[f].getType(), features[f].getDescription(),
2960 features[f].getStatus(), features[f].getBegin(),
2961 features[f].getEnd(), features[f].getFeatureGroup());
2963 sf.setScore(features[f].getScore());
2964 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2966 OtherData keyValue = features[f].getOtherData(od);
2967 if (keyValue.getKey().startsWith("LINK"))
2969 sf.addLink(keyValue.getValue());
2973 sf.setValue(keyValue.getKey(), keyValue.getValue());
2977 // adds feature to datasequence's feature set (since Jalview 2.10)
2978 al.getSequenceAt(i).addSequenceFeature(sf);
2981 if (vamsasSeq[i].getDBRefCount() > 0)
2983 // adds dbrefs to datasequence's set (since Jalview 2.10)
2985 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
2986 : al.getSequenceAt(i).getDatasetSequence(),
2989 if (jseqs[i].getPdbidsCount() > 0)
2991 Pdbids[] ids = jseqs[i].getPdbids();
2992 for (int p = 0; p < ids.length; p++)
2994 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2995 entry.setId(ids[p].getId());
2996 if (ids[p].getType() != null)
2998 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3000 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3004 entry.setType(PDBEntry.Type.FILE);
3007 if (ids[p].getFile() != null)
3009 if (!pdbloaded.containsKey(ids[p].getFile()))
3011 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3016 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3019 if (ids[p].getPdbentryItem() != null)
3021 for (PdbentryItem item : ids[p].getPdbentryItem())
3023 for (Property pr : item.getProperty())
3025 entry.setProperty(pr.getName(), pr.getValue());
3029 StructureSelectionManager.getStructureSelectionManager(
3030 Desktop.instance).registerPDBEntry(entry);
3031 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3032 if (al.getSequenceAt(i).getDatasetSequence() != null)
3034 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3038 al.getSequenceAt(i).addPDBId(entry);
3043 } // end !multipleview
3045 // ///////////////////////////////
3046 // LOAD SEQUENCE MAPPINGS
3048 if (vamsasSet.getAlcodonFrameCount() > 0)
3050 // TODO Potentially this should only be done once for all views of an
3052 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3053 for (int i = 0; i < alc.length; i++)
3055 AlignedCodonFrame cf = new AlignedCodonFrame();
3056 if (alc[i].getAlcodMapCount() > 0)
3058 AlcodMap[] maps = alc[i].getAlcodMap();
3059 for (int m = 0; m < maps.length; m++)
3061 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3063 jalview.datamodel.Mapping mapping = null;
3064 // attach to dna sequence reference.
3065 if (maps[m].getMapping() != null)
3067 mapping = addMapping(maps[m].getMapping());
3068 if (dnaseq != null && mapping.getTo() != null)
3070 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3075 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3080 al.addCodonFrame(cf);
3085 // ////////////////////////////////
3087 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3090 * store any annotations which forward reference a group's ID
3092 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3094 if (vamsasSet.getAnnotationCount() > 0)
3096 Annotation[] an = vamsasSet.getAnnotation();
3098 for (int i = 0; i < an.length; i++)
3100 Annotation annotation = an[i];
3103 * test if annotation is automatically calculated for this view only
3105 boolean autoForView = false;
3106 if (annotation.getLabel().equals("Quality")
3107 || annotation.getLabel().equals("Conservation")
3108 || annotation.getLabel().equals("Consensus"))
3110 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3112 if (!annotation.hasAutoCalculated())
3114 annotation.setAutoCalculated(true);
3118 || (annotation.hasAutoCalculated() && annotation
3119 .isAutoCalculated()))
3121 // remove ID - we don't recover annotation from other views for
3122 // view-specific annotation
3123 annotation.setId(null);
3126 // set visiblity for other annotation in this view
3127 String annotationId = annotation.getId();
3128 if (annotationId != null && annotationIds.containsKey(annotationId))
3130 AlignmentAnnotation jda = annotationIds.get(annotationId);
3131 // in principle Visible should always be true for annotation displayed
3132 // in multiple views
3133 if (annotation.hasVisible())
3135 jda.visible = annotation.getVisible();
3138 al.addAnnotation(jda);
3142 // Construct new annotation from model.
3143 AnnotationElement[] ae = annotation.getAnnotationElement();
3144 jalview.datamodel.Annotation[] anot = null;
3145 java.awt.Color firstColour = null;
3147 if (!annotation.getScoreOnly())
3149 anot = new jalview.datamodel.Annotation[al.getWidth()];
3150 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3152 anpos = ae[aa].getPosition();
3154 if (anpos >= anot.length)
3159 anot[anpos] = new jalview.datamodel.Annotation(
3161 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3162 (ae[aa].getSecondaryStructure() == null || ae[aa]
3163 .getSecondaryStructure().length() == 0) ? ' '
3164 : ae[aa].getSecondaryStructure().charAt(0),
3168 // JBPNote: Consider verifying dataflow for IO of secondary
3169 // structure annotation read from Stockholm files
3170 // this was added to try to ensure that
3171 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3173 // anot[ae[aa].getPosition()].displayCharacter = "";
3175 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3176 if (firstColour == null)
3178 firstColour = anot[anpos].colour;
3182 jalview.datamodel.AlignmentAnnotation jaa = null;
3184 if (annotation.getGraph())
3186 float llim = 0, hlim = 0;
3187 // if (autoForView || an[i].isAutoCalculated()) {
3190 jaa = new jalview.datamodel.AlignmentAnnotation(
3191 annotation.getLabel(), annotation.getDescription(), anot,
3192 llim, hlim, annotation.getGraphType());
3194 jaa.graphGroup = annotation.getGraphGroup();
3195 jaa._linecolour = firstColour;
3196 if (annotation.getThresholdLine() != null)
3198 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3199 .getThresholdLine().getValue(), annotation
3200 .getThresholdLine().getLabel(), new java.awt.Color(
3201 annotation.getThresholdLine().getColour())));
3204 if (autoForView || annotation.isAutoCalculated())
3206 // Hardwire the symbol display line to ensure that labels for
3207 // histograms are displayed
3213 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3214 an[i].getDescription(), anot);
3215 jaa._linecolour = firstColour;
3217 // register new annotation
3218 if (an[i].getId() != null)
3220 annotationIds.put(an[i].getId(), jaa);
3221 jaa.annotationId = an[i].getId();
3223 // recover sequence association
3224 String sequenceRef = an[i].getSequenceRef();
3225 if (sequenceRef != null)
3227 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3228 SequenceI sequence = seqRefIds.get(sequenceRef);
3229 if (sequence == null)
3231 // in pre-2.9 projects sequence ref is to sequence name
3232 sequence = al.findName(sequenceRef);
3234 if (sequence != null)
3236 jaa.createSequenceMapping(sequence, 1, true);
3237 sequence.addAlignmentAnnotation(jaa);
3240 // and make a note of any group association
3241 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3243 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3244 .get(an[i].getGroupRef());
3247 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3248 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3253 if (an[i].hasScore())
3255 jaa.setScore(an[i].getScore());
3257 if (an[i].hasVisible())
3259 jaa.visible = an[i].getVisible();
3262 if (an[i].hasCentreColLabels())
3264 jaa.centreColLabels = an[i].getCentreColLabels();
3267 if (an[i].hasScaleColLabels())
3269 jaa.scaleColLabel = an[i].getScaleColLabels();
3271 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3273 // newer files have an 'autoCalculated' flag and store calculation
3274 // state in viewport properties
3275 jaa.autoCalculated = true; // means annotation will be marked for
3276 // update at end of load.
3278 if (an[i].hasGraphHeight())
3280 jaa.graphHeight = an[i].getGraphHeight();
3282 if (an[i].hasBelowAlignment())
3284 jaa.belowAlignment = an[i].isBelowAlignment();
3286 jaa.setCalcId(an[i].getCalcId());
3287 if (an[i].getPropertyCount() > 0)
3289 for (jalview.schemabinding.version2.Property prop : an[i]
3292 jaa.setProperty(prop.getName(), prop.getValue());
3295 if (jaa.autoCalculated)
3297 autoAlan.add(new JvAnnotRow(i, jaa));
3300 // if (!autoForView)
3302 // add autocalculated group annotation and any user created annotation
3304 al.addAnnotation(jaa);
3308 // ///////////////////////
3310 // Create alignment markup and styles for this view
3311 if (jms.getJGroupCount() > 0)
3313 JGroup[] groups = jms.getJGroup();
3314 boolean addAnnotSchemeGroup = false;
3315 for (int i = 0; i < groups.length; i++)
3317 JGroup jGroup = groups[i];
3318 ColourSchemeI cs = null;
3319 if (jGroup.getColour() != null)
3321 if (jGroup.getColour().startsWith("ucs"))
3323 cs = getUserColourScheme(jms, jGroup.getColour());
3325 else if (jGroup.getColour().equals("AnnotationColourGradient")
3326 && jGroup.getAnnotationColours() != null)
3328 addAnnotSchemeGroup = true;
3333 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3338 cs.setThreshold(jGroup.getPidThreshold(), true);
3342 Vector<SequenceI> seqs = new Vector<SequenceI>();
3344 for (int s = 0; s < jGroup.getSeqCount(); s++)
3346 String seqId = jGroup.getSeq(s) + "";
3347 SequenceI ts = seqRefIds.get(seqId);
3351 seqs.addElement(ts);
3355 if (seqs.size() < 1)
3360 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3361 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3362 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3364 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3366 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3367 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3368 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3369 .isShowUnconserved() : false);
3370 sg.thresholdTextColour = jGroup.getTextColThreshold();
3371 if (jGroup.hasShowConsensusHistogram())
3373 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3376 if (jGroup.hasShowSequenceLogo())
3378 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3380 if (jGroup.hasNormaliseSequenceLogo())
3382 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3384 if (jGroup.hasIgnoreGapsinConsensus())
3386 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3388 if (jGroup.getConsThreshold() != 0)
3390 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3391 "All", ResidueProperties.propHash, 3,
3392 sg.getSequences(null), 0, sg.getWidth() - 1);
3394 c.verdict(false, 25);
3395 sg.cs.setConservation(c);
3398 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3400 // re-instate unique group/annotation row reference
3401 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3405 for (AlignmentAnnotation jaa : jaal)
3408 if (jaa.autoCalculated)
3410 // match up and try to set group autocalc alignment row for this
3412 if (jaa.label.startsWith("Consensus for "))
3414 sg.setConsensus(jaa);
3416 // match up and try to set group autocalc alignment row for this
3418 if (jaa.label.startsWith("Conservation for "))
3420 sg.setConservationRow(jaa);
3427 if (addAnnotSchemeGroup)
3429 // reconstruct the annotation colourscheme
3430 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3431 null, al, jms, false);
3437 // only dataset in this model, so just return.
3440 // ///////////////////////////////
3443 // If we just load in the same jar file again, the sequenceSetId
3444 // will be the same, and we end up with multiple references
3445 // to the same sequenceSet. We must modify this id on load
3446 // so that each load of the file gives a unique id
3447 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3448 String viewId = (view.getId() == null ? null : view.getId()
3450 AlignFrame af = null;
3451 AlignViewport av = null;
3452 // now check to see if we really need to create a new viewport.
3453 if (multipleView && viewportsAdded.size() == 0)
3455 // We recovered an alignment for which a viewport already exists.
3456 // TODO: fix up any settings necessary for overlaying stored state onto
3457 // state recovered from another document. (may not be necessary).
3458 // we may need a binding from a viewport in memory to one recovered from
3460 // and then recover its containing af to allow the settings to be applied.
3461 // TODO: fix for vamsas demo
3463 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3465 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3466 if (seqsetobj != null)
3468 if (seqsetobj instanceof String)
3470 uniqueSeqSetId = (String) seqsetobj;
3472 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3478 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3484 * indicate that annotation colours are applied across all groups (pre
3485 * Jalview 2.8.1 behaviour)
3487 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3488 "2.8.1", object.getVersion());
3490 AlignmentPanel ap = null;
3491 boolean isnewview = true;
3494 // Check to see if this alignment already has a view id == viewId
3495 jalview.gui.AlignmentPanel views[] = Desktop
3496 .getAlignmentPanels(uniqueSeqSetId);
3497 if (views != null && views.length > 0)
3499 for (int v = 0; v < views.length; v++)
3501 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3503 // recover the existing alignpanel, alignframe, viewport
3504 af = views[v].alignFrame;
3507 // TODO: could even skip resetting view settings if we don't want to
3508 // change the local settings from other jalview processes
3517 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3518 uniqueSeqSetId, viewId, autoAlan);
3524 * Load any trees, PDB structures and viewers
3526 * Not done if flag is false (when this method is used for New View)
3528 if (loadTreesAndStructures)
3530 loadTrees(jms, view, af, av, ap);
3531 loadPDBStructures(jprovider, jseqs, af, ap);
3532 loadRnaViewers(jprovider, jseqs, ap);
3534 // and finally return.
3539 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3540 * panel is restored from separate jar entries, two (gapped and trimmed) per
3541 * sequence and secondary structure.
3543 * Currently each viewer shows just one sequence and structure (gapped and
3544 * trimmed), however this method is designed to support multiple sequences or
3545 * structures in viewers if wanted in future.
3551 private void loadRnaViewers(jarInputStreamProvider jprovider,
3552 JSeq[] jseqs, AlignmentPanel ap)
3555 * scan the sequences for references to viewers; create each one the first
3556 * time it is referenced, add Rna models to existing viewers
3558 for (JSeq jseq : jseqs)
3560 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3562 RnaViewer viewer = jseq.getRnaViewer(i);
3563 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3564 uniqueSetSuffix, ap);
3566 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3568 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3569 SequenceI seq = seqRefIds.get(jseq.getId());
3570 AlignmentAnnotation ann = this.annotationIds.get(ss
3571 .getAnnotationId());
3574 * add the structure to the Varna display (with session state copied
3575 * from the jar to a temporary file)
3577 boolean gapped = ss.isGapped();
3578 String rnaTitle = ss.getTitle();
3579 String sessionState = ss.getViewerState();
3580 String tempStateFile = copyJarEntry(jprovider, sessionState,
3582 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3583 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3585 appVarna.setInitialSelection(viewer.getSelectedRna());
3591 * Locate and return an already instantiated matching AppVarna, or create one
3595 * @param viewIdSuffix
3599 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3600 String viewIdSuffix, AlignmentPanel ap)
3603 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3604 * if load is repeated
3606 String postLoadId = viewer.getViewId() + viewIdSuffix;
3607 for (JInternalFrame frame : getAllFrames())
3609 if (frame instanceof AppVarna)
3611 AppVarna varna = (AppVarna) frame;
3612 if (postLoadId.equals(varna.getViewId()))
3614 // this viewer is already instantiated
3615 // could in future here add ap as another 'parent' of the
3616 // AppVarna window; currently just 1-to-many
3623 * viewer not found - make it
3625 RnaViewerModel model = new RnaViewerModel(postLoadId,
3626 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3627 viewer.getWidth(), viewer.getHeight(),
3628 viewer.getDividerLocation());
3629 AppVarna varna = new AppVarna(model, ap);
3635 * Load any saved trees
3643 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3644 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3646 // TODO result of automated refactoring - are all these parameters needed?
3649 for (int t = 0; t < jms.getTreeCount(); t++)
3652 Tree tree = jms.getTree(t);
3654 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3657 tp = af.ShowNewickTree(
3658 new jalview.io.NewickFile(tree.getNewick()),
3659 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3660 tree.getXpos(), tree.getYpos());
3661 if (tree.getId() != null)
3663 // perhaps bind the tree id to something ?
3668 // update local tree attributes ?
3669 // TODO: should check if tp has been manipulated by user - if so its
3670 // settings shouldn't be modified
3671 tp.setTitle(tree.getTitle());
3672 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3673 .getWidth(), tree.getHeight()));
3674 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3677 tp.treeCanvas.av = av; // af.viewport;
3678 tp.treeCanvas.ap = ap; // af.alignPanel;
3683 warn("There was a problem recovering stored Newick tree: \n"
3684 + tree.getNewick());
3688 tp.fitToWindow.setState(tree.getFitToWindow());
3689 tp.fitToWindow_actionPerformed(null);
3691 if (tree.getFontName() != null)
3693 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3694 .getFontStyle(), tree.getFontSize()));
3698 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3699 .getFontStyle(), tree.getFontSize()));
3702 tp.showPlaceholders(tree.getMarkUnlinked());
3703 tp.showBootstrap(tree.getShowBootstrap());
3704 tp.showDistances(tree.getShowDistances());
3706 tp.treeCanvas.threshold = tree.getThreshold();
3708 if (tree.getCurrentTree())
3710 af.viewport.setCurrentTree(tp.getTree());
3714 } catch (Exception ex)
3716 ex.printStackTrace();
3721 * Load and link any saved structure viewers.
3728 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3729 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3732 * Run through all PDB ids on the alignment, and collect mappings between
3733 * distinct view ids and all sequences referring to that view.
3735 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3737 for (int i = 0; i < jseqs.length; i++)
3739 if (jseqs[i].getPdbidsCount() > 0)
3741 Pdbids[] ids = jseqs[i].getPdbids();
3742 for (int p = 0; p < ids.length; p++)
3744 final int structureStateCount = ids[p].getStructureStateCount();
3745 for (int s = 0; s < structureStateCount; s++)
3747 // check to see if we haven't already created this structure view
3748 final StructureState structureState = ids[p]
3749 .getStructureState(s);
3750 String sviewid = (structureState.getViewId() == null) ? null
3751 : structureState.getViewId() + uniqueSetSuffix;
3752 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3753 // Originally : ids[p].getFile()
3754 // : TODO: verify external PDB file recovery still works in normal
3755 // jalview project load
3756 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3758 jpdb.setId(ids[p].getId());
3760 int x = structureState.getXpos();
3761 int y = structureState.getYpos();
3762 int width = structureState.getWidth();
3763 int height = structureState.getHeight();
3765 // Probably don't need to do this anymore...
3766 // Desktop.desktop.getComponentAt(x, y);
3767 // TODO: NOW: check that this recovers the PDB file correctly.
3768 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3770 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3772 if (sviewid == null)
3774 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3777 if (!structureViewers.containsKey(sviewid))
3779 structureViewers.put(sviewid,
3780 new StructureViewerModel(x, y, width, height, false,
3781 false, true, structureState.getViewId(),
3782 structureState.getType()));
3783 // Legacy pre-2.7 conversion JAL-823 :
3784 // do not assume any view has to be linked for colour by
3788 // assemble String[] { pdb files }, String[] { id for each
3789 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3790 // seqs_file 2}, boolean[] {
3791 // linkAlignPanel,superposeWithAlignpanel}} from hash
3792 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3793 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3794 | (structureState.hasAlignwithAlignPanel() ? structureState
3795 .getAlignwithAlignPanel() : false));
3798 * Default colour by linked panel to false if not specified (e.g.
3799 * for pre-2.7 projects)
3801 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3802 colourWithAlignPanel |= (structureState
3803 .hasColourwithAlignPanel() ? structureState
3804 .getColourwithAlignPanel() : false);
3805 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3808 * Default colour by viewer to true if not specified (e.g. for
3811 boolean colourByViewer = jmoldat.isColourByViewer();
3812 colourByViewer &= structureState.hasColourByJmol() ? structureState
3813 .getColourByJmol() : true;
3814 jmoldat.setColourByViewer(colourByViewer);
3816 if (jmoldat.getStateData().length() < structureState
3817 .getContent().length())
3820 jmoldat.setStateData(structureState.getContent());
3823 if (ids[p].getFile() != null)
3825 File mapkey = new File(ids[p].getFile());
3826 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3827 if (seqstrmaps == null)
3829 jmoldat.getFileData().put(
3831 seqstrmaps = jmoldat.new StructureData(pdbFile,
3834 if (!seqstrmaps.getSeqList().contains(seq))
3836 seqstrmaps.getSeqList().add(seq);
3842 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");
3849 // Instantiate the associated structure views
3850 for (Entry<String, StructureViewerModel> entry : structureViewers
3855 createOrLinkStructureViewer(entry, af, ap, jprovider);
3856 } catch (Exception e)
3858 System.err.println("Error loading structure viewer: "
3860 // failed - try the next one
3872 protected void createOrLinkStructureViewer(
3873 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3874 AlignmentPanel ap, jarInputStreamProvider jprovider)
3876 final StructureViewerModel stateData = viewerData.getValue();
3879 * Search for any viewer windows already open from other alignment views
3880 * that exactly match the stored structure state
3882 StructureViewerBase comp = findMatchingViewer(viewerData);
3886 linkStructureViewer(ap, comp, stateData);
3891 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3892 * "viewer_"+stateData.viewId
3894 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3896 createChimeraViewer(viewerData, af, jprovider);
3901 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3903 createJmolViewer(viewerData, af, jprovider);
3908 * Create a new Chimera viewer.
3914 protected void createChimeraViewer(
3915 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3916 jarInputStreamProvider jprovider)
3918 StructureViewerModel data = viewerData.getValue();
3919 String chimeraSessionFile = data.getStateData();
3922 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3924 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3925 * 'uniquified' sviewid used to reconstruct the viewer here
3927 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3928 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3931 Set<Entry<File, StructureData>> fileData = data.getFileData()
3933 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3934 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3935 for (Entry<File, StructureData> pdb : fileData)
3937 String filePath = pdb.getValue().getFilePath();
3938 String pdbId = pdb.getValue().getPdbId();
3939 // pdbs.add(new PDBEntry(filePath, pdbId));
3940 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3941 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3942 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3946 boolean colourByChimera = data.isColourByViewer();
3947 boolean colourBySequence = data.isColourWithAlignPanel();
3949 // TODO use StructureViewer as a factory here, see JAL-1761
3950 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3951 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3953 String newViewId = viewerData.getKey();
3955 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3956 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3957 colourBySequence, newViewId);
3958 cvf.setSize(data.getWidth(), data.getHeight());
3959 cvf.setLocation(data.getX(), data.getY());
3963 * Create a new Jmol window. First parse the Jmol state to translate filenames
3964 * loaded into the view, and record the order in which files are shown in the
3965 * Jmol view, so we can add the sequence mappings in same order.
3971 protected void createJmolViewer(
3972 final Entry<String, StructureViewerModel> viewerData,
3973 AlignFrame af, jarInputStreamProvider jprovider)
3975 final StructureViewerModel svattrib = viewerData.getValue();
3976 String state = svattrib.getStateData();
3979 * Pre-2.9: state element value is the Jmol state string
3981 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3984 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3986 state = readJarEntry(jprovider,
3987 getViewerJarEntryName(svattrib.getViewId()));
3990 List<String> pdbfilenames = new ArrayList<String>();
3991 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3992 List<String> pdbids = new ArrayList<String>();
3993 StringBuilder newFileLoc = new StringBuilder(64);
3994 int cp = 0, ncp, ecp;
3995 Map<File, StructureData> oldFiles = svattrib.getFileData();
3996 while ((ncp = state.indexOf("load ", cp)) > -1)
4000 // look for next filename in load statement
4001 newFileLoc.append(state.substring(cp,
4002 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4003 String oldfilenam = state.substring(ncp,
4004 ecp = state.indexOf("\"", ncp));
4005 // recover the new mapping data for this old filename
4006 // have to normalize filename - since Jmol and jalview do
4008 // translation differently.
4009 StructureData filedat = oldFiles.get(new File(oldfilenam));
4010 if (filedat == null)
4012 String reformatedOldFilename = oldfilenam.replaceAll("/",
4014 filedat = oldFiles.get(new File(reformatedOldFilename));
4016 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4017 pdbfilenames.add(filedat.getFilePath());
4018 pdbids.add(filedat.getPdbId());
4019 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4020 newFileLoc.append("\"");
4021 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4022 // look for next file statement.
4023 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4027 // just append rest of state
4028 newFileLoc.append(state.substring(cp));
4032 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4033 newFileLoc = new StringBuilder(state);
4034 newFileLoc.append("; load append ");
4035 for (File id : oldFiles.keySet())
4037 // add this and any other pdb files that should be present in
4039 StructureData filedat = oldFiles.get(id);
4040 newFileLoc.append(filedat.getFilePath());
4041 pdbfilenames.add(filedat.getFilePath());
4042 pdbids.add(filedat.getPdbId());
4043 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4044 newFileLoc.append(" \"");
4045 newFileLoc.append(filedat.getFilePath());
4046 newFileLoc.append("\"");
4049 newFileLoc.append(";");
4052 if (newFileLoc.length() == 0)
4056 int histbug = newFileLoc.indexOf("history = ");
4060 * change "history = [true|false];" to "history = [1|0];"
4063 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4064 String val = (diff == -1) ? null : newFileLoc
4065 .substring(histbug, diff);
4066 if (val != null && val.length() >= 4)
4068 if (val.contains("e")) // eh? what can it be?
4070 if (val.trim().equals("true"))
4078 newFileLoc.replace(histbug, diff, val);
4083 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4085 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4086 final SequenceI[][] sq = seqmaps
4087 .toArray(new SequenceI[seqmaps.size()][]);
4088 final String fileloc = newFileLoc.toString();
4089 final String sviewid = viewerData.getKey();
4090 final AlignFrame alf = af;
4091 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4092 svattrib.getWidth(), svattrib.getHeight());
4095 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4100 JalviewStructureDisplayI sview = null;
4103 sview = new StructureViewer(alf.alignPanel
4104 .getStructureSelectionManager()).createView(
4105 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4106 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4107 addNewStructureViewer(sview);
4108 } catch (OutOfMemoryError ex)
4110 new OOMWarning("restoring structure view for PDB id " + id,
4111 (OutOfMemoryError) ex.getCause());
4112 if (sview != null && sview.isVisible())
4114 sview.closeViewer(false);
4115 sview.setVisible(false);
4121 } catch (InvocationTargetException ex)
4123 warn("Unexpected error when opening Jmol view.", ex);
4125 } catch (InterruptedException e)
4127 // e.printStackTrace();
4133 * Generates a name for the entry in the project jar file to hold state
4134 * information for a structure viewer
4139 protected String getViewerJarEntryName(String viewId)
4141 return VIEWER_PREFIX + viewId;
4145 * Returns any open frame that matches given structure viewer data. The match
4146 * is based on the unique viewId, or (for older project versions) the frame's
4152 protected StructureViewerBase findMatchingViewer(
4153 Entry<String, StructureViewerModel> viewerData)
4155 final String sviewid = viewerData.getKey();
4156 final StructureViewerModel svattrib = viewerData.getValue();
4157 StructureViewerBase comp = null;
4158 JInternalFrame[] frames = getAllFrames();
4159 for (JInternalFrame frame : frames)
4161 if (frame instanceof StructureViewerBase)
4164 * Post jalview 2.4 schema includes structure view id
4167 && ((StructureViewerBase) frame).getViewId()
4170 comp = (StructureViewerBase) frame;
4171 break; // break added in 2.9
4174 * Otherwise test for matching position and size of viewer frame
4176 else if (frame.getX() == svattrib.getX()
4177 && frame.getY() == svattrib.getY()
4178 && frame.getHeight() == svattrib.getHeight()
4179 && frame.getWidth() == svattrib.getWidth())
4181 comp = (StructureViewerBase) frame;
4182 // no break in faint hope of an exact match on viewId
4190 * Link an AlignmentPanel to an existing structure viewer.
4195 * @param useinViewerSuperpos
4196 * @param usetoColourbyseq
4197 * @param viewerColouring
4199 protected void linkStructureViewer(AlignmentPanel ap,
4200 StructureViewerBase viewer, StructureViewerModel stateData)
4202 // NOTE: if the jalview project is part of a shared session then
4203 // view synchronization should/could be done here.
4205 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4206 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4207 final boolean viewerColouring = stateData.isColourByViewer();
4208 Map<File, StructureData> oldFiles = stateData.getFileData();
4211 * Add mapping for sequences in this view to an already open viewer
4213 final AAStructureBindingModel binding = viewer.getBinding();
4214 for (File id : oldFiles.keySet())
4216 // add this and any other pdb files that should be present in the
4218 StructureData filedat = oldFiles.get(id);
4219 String pdbFile = filedat.getFilePath();
4220 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4221 binding.getSsm().setMapping(seq, null, pdbFile,
4222 jalview.io.AppletFormatAdapter.FILE);
4223 binding.addSequenceForStructFile(pdbFile, seq);
4225 // and add the AlignmentPanel's reference to the view panel
4226 viewer.addAlignmentPanel(ap);
4227 if (useinViewerSuperpos)
4229 viewer.useAlignmentPanelForSuperposition(ap);
4233 viewer.excludeAlignmentPanelForSuperposition(ap);
4235 if (usetoColourbyseq)
4237 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4241 viewer.excludeAlignmentPanelForColourbyseq(ap);
4246 * Get all frames within the Desktop.
4250 protected JInternalFrame[] getAllFrames()
4252 JInternalFrame[] frames = null;
4253 // TODO is this necessary - is it safe - risk of hanging?
4258 frames = Desktop.desktop.getAllFrames();
4259 } catch (ArrayIndexOutOfBoundsException e)
4261 // occasional No such child exceptions are thrown here...
4265 } catch (InterruptedException f)
4269 } while (frames == null);
4274 * Answers true if 'version' is equal to or later than 'supported', where each
4275 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4276 * changes. Development and test values for 'version' are leniently treated
4280 * - minimum version we are comparing against
4282 * - version of data being processsed
4285 public static boolean isVersionStringLaterThan(String supported,
4288 if (supported == null || version == null
4289 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4290 || version.equalsIgnoreCase("Test")
4291 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4293 System.err.println("Assuming project file with "
4294 + (version == null ? "null" : version)
4295 + " is compatible with Jalview version " + supported);
4300 return StringUtils.compareVersions(version, supported, "b") >= 0;
4304 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4306 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4308 if (newStructureViewers != null)
4310 sview.getBinding().setFinishedLoadingFromArchive(false);
4311 newStructureViewers.add(sview);
4315 protected void setLoadingFinishedForNewStructureViewers()
4317 if (newStructureViewers != null)
4319 for (JalviewStructureDisplayI sview : newStructureViewers)
4321 sview.getBinding().setFinishedLoadingFromArchive(true);
4323 newStructureViewers.clear();
4324 newStructureViewers = null;
4328 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4329 List<SequenceI> hiddenSeqs, AlignmentI al,
4330 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4331 String viewId, List<JvAnnotRow> autoAlan)
4333 AlignFrame af = null;
4334 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4335 uniqueSeqSetId, viewId);
4337 af.setFileName(file, "Jalview");
4339 for (int i = 0; i < JSEQ.length; i++)
4341 af.viewport.setSequenceColour(af.viewport.getAlignment()
4342 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4347 af.getViewport().setColourByReferenceSeq(true);
4348 af.getViewport().setDisplayReferenceSeq(true);
4351 af.viewport.setGatherViewsHere(view.getGatheredViews());
4353 if (view.getSequenceSetId() != null)
4355 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4357 af.viewport.setSequenceSetId(uniqueSeqSetId);
4360 // propagate shared settings to this new view
4361 af.viewport.setHistoryList(av.getHistoryList());
4362 af.viewport.setRedoList(av.getRedoList());
4366 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4368 // TODO: check if this method can be called repeatedly without
4369 // side-effects if alignpanel already registered.
4370 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4372 // apply Hidden regions to view.
4373 if (hiddenSeqs != null)
4375 for (int s = 0; s < JSEQ.length; s++)
4377 SequenceGroup hidden = new SequenceGroup();
4378 boolean isRepresentative = false;
4379 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4381 isRepresentative = true;
4382 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4383 .getHiddenSequences(r));
4384 hidden.addSequence(sequenceToHide, false);
4385 // remove from hiddenSeqs list so we don't try to hide it twice
4386 hiddenSeqs.remove(sequenceToHide);
4388 if (isRepresentative)
4390 SequenceI representativeSequence = al.getSequenceAt(s);
4391 hidden.addSequence(representativeSequence, false);
4392 af.viewport.hideRepSequences(representativeSequence, hidden);
4396 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4398 af.viewport.hideSequence(hseqs);
4401 // recover view properties and display parameters
4402 if (view.getViewName() != null)
4404 af.viewport.viewName = view.getViewName();
4405 af.setInitialTabVisible();
4407 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4410 af.viewport.setShowAnnotation(view.getShowAnnotation());
4411 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4413 af.viewport.setColourText(view.getShowColourText());
4415 af.viewport.setConservationSelected(view.getConservationSelected());
4416 af.viewport.setShowJVSuffix(view.getShowFullId());
4417 af.viewport.setRightAlignIds(view.getRightAlignIds());
4418 af.viewport.setFont(
4419 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4420 .getFontSize()), true);
4421 ViewStyleI vs = af.viewport.getViewStyle();
4422 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4423 af.viewport.setViewStyle(vs);
4424 // TODO: allow custom charWidth/Heights to be restored by updating them
4425 // after setting font - which means set above to false
4426 af.viewport.setRenderGaps(view.getRenderGaps());
4427 af.viewport.setWrapAlignment(view.getWrapAlignment());
4428 af.viewport.setShowAnnotation(view.getShowAnnotation());
4430 af.viewport.setShowBoxes(view.getShowBoxes());
4432 af.viewport.setShowText(view.getShowText());
4434 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4435 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4436 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4437 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4438 .isShowUnconserved() : false);
4439 af.viewport.setStartRes(view.getStartRes());
4440 af.viewport.setStartSeq(view.getStartSeq());
4441 af.alignPanel.updateLayout();
4442 ColourSchemeI cs = null;
4443 // apply colourschemes
4444 if (view.getBgColour() != null)
4446 if (view.getBgColour().startsWith("ucs"))
4448 cs = getUserColourScheme(jms, view.getBgColour());
4450 else if (view.getBgColour().startsWith("Annotation"))
4452 AnnotationColours viewAnnColour = view.getAnnotationColours();
4453 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4460 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4465 cs.setThreshold(view.getPidThreshold(), true);
4466 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4470 af.viewport.setGlobalColourScheme(cs);
4471 af.viewport.setColourAppliesToAllGroups(false);
4473 if (view.getConservationSelected() && cs != null)
4475 cs.setConservationInc(view.getConsThreshold());
4478 af.changeColour(cs);
4480 af.viewport.setColourAppliesToAllGroups(true);
4482 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4484 if (view.hasCentreColumnLabels())
4486 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4488 if (view.hasIgnoreGapsinConsensus())
4490 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4493 if (view.hasFollowHighlight())
4495 af.viewport.setFollowHighlight(view.getFollowHighlight());
4497 if (view.hasFollowSelection())
4499 af.viewport.followSelection = view.getFollowSelection();
4501 if (view.hasShowConsensusHistogram())
4503 af.viewport.setShowConsensusHistogram(view
4504 .getShowConsensusHistogram());
4508 af.viewport.setShowConsensusHistogram(true);
4510 if (view.hasShowSequenceLogo())
4512 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4516 af.viewport.setShowSequenceLogo(false);
4518 if (view.hasNormaliseSequenceLogo())
4520 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4522 if (view.hasShowDbRefTooltip())
4524 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4526 if (view.hasShowNPfeatureTooltip())
4528 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4530 if (view.hasShowGroupConsensus())
4532 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4536 af.viewport.setShowGroupConsensus(false);
4538 if (view.hasShowGroupConservation())
4540 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4544 af.viewport.setShowGroupConservation(false);
4547 // recover featre settings
4548 if (jms.getFeatureSettings() != null)
4550 FeaturesDisplayed fdi;
4551 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4552 String[] renderOrder = new String[jms.getFeatureSettings()
4553 .getSettingCount()];
4554 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4555 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4557 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4559 Setting setting = jms.getFeatureSettings().getSetting(fs);
4560 if (setting.hasMincolour())
4562 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4563 new Color(setting.getMincolour()), new Color(
4564 setting.getColour()), setting.getMin(),
4565 setting.getMax()) : new FeatureColour(new Color(
4566 setting.getMincolour()), new Color(setting.getColour()),
4568 if (setting.hasThreshold())
4570 gc.setThreshold(setting.getThreshold());
4571 int threshstate = setting.getThreshstate();
4572 // -1 = None, 0 = Below, 1 = Above threshold
4573 if (threshstate == 0)
4575 gc.setBelowThreshold(true);
4577 else if (threshstate == 1)
4579 gc.setAboveThreshold(true);
4582 gc.setAutoScaled(true); // default
4583 if (setting.hasAutoScale())
4585 gc.setAutoScaled(setting.getAutoScale());
4587 if (setting.hasColourByLabel())
4589 gc.setColourByLabel(setting.getColourByLabel());
4591 // and put in the feature colour table.
4592 featureColours.put(setting.getType(), gc);
4596 featureColours.put(setting.getType(), new FeatureColour(
4597 new Color(setting.getColour())));
4599 renderOrder[fs] = setting.getType();
4600 if (setting.hasOrder())
4602 featureOrder.put(setting.getType(), setting.getOrder());
4606 featureOrder.put(setting.getType(), new Float(fs
4607 / jms.getFeatureSettings().getSettingCount()));
4609 if (setting.getDisplay())
4611 fdi.setVisible(setting.getType());
4614 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4615 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4617 Group grp = jms.getFeatureSettings().getGroup(gs);
4618 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4620 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4621 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4622 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4623 FeatureRendererSettings frs = new FeatureRendererSettings(
4624 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4625 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4626 .transferSettings(frs);
4630 if (view.getHiddenColumnsCount() > 0)
4632 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4634 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4635 .getHiddenColumns(c).getEnd() // +1
4639 if (view.getCalcIdParam() != null)
4641 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4643 if (calcIdParam != null)
4645 if (recoverCalcIdParam(calcIdParam, af.viewport))
4650 warn("Couldn't recover parameters for "
4651 + calcIdParam.getCalcId());
4656 af.setMenusFromViewport(af.viewport);
4657 af.setTitle(view.getTitle());
4658 // TODO: we don't need to do this if the viewport is aready visible.
4660 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4661 * has a 'cdna/protein complement' view, in which case save it in order to
4662 * populate a SplitFrame once all views have been read in.
4664 String complementaryViewId = view.getComplementId();
4665 if (complementaryViewId == null)
4667 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4669 // recompute any autoannotation
4670 af.alignPanel.updateAnnotation(false, true);
4671 reorderAutoannotation(af, al, autoAlan);
4672 af.alignPanel.alignmentChanged();
4676 splitFrameCandidates.put(view, af);
4681 private ColourSchemeI constructAnnotationColour(
4682 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4683 JalviewModelSequence jms, boolean checkGroupAnnColour)
4685 boolean propagateAnnColour = false;
4686 ColourSchemeI cs = null;
4687 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4688 if (checkGroupAnnColour && al.getGroups() != null
4689 && al.getGroups().size() > 0)
4691 // pre 2.8.1 behaviour
4692 // check to see if we should transfer annotation colours
4693 propagateAnnColour = true;
4694 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4696 if (sg.cs instanceof AnnotationColourGradient)
4698 propagateAnnColour = false;
4702 // int find annotation
4703 if (annAlignment.getAlignmentAnnotation() != null)
4705 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4707 if (annAlignment.getAlignmentAnnotation()[i].label
4708 .equals(viewAnnColour.getAnnotation()))
4710 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4712 annAlignment.getAlignmentAnnotation()[i]
4713 .setThreshold(new jalview.datamodel.GraphLine(
4714 viewAnnColour.getThreshold(), "Threshold",
4715 java.awt.Color.black)
4720 if (viewAnnColour.getColourScheme().equals("None"))
4722 cs = new AnnotationColourGradient(
4723 annAlignment.getAlignmentAnnotation()[i],
4724 new java.awt.Color(viewAnnColour.getMinColour()),
4725 new java.awt.Color(viewAnnColour.getMaxColour()),
4726 viewAnnColour.getAboveThreshold());
4728 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4730 cs = new AnnotationColourGradient(
4731 annAlignment.getAlignmentAnnotation()[i],
4732 getUserColourScheme(jms,
4733 viewAnnColour.getColourScheme()),
4734 viewAnnColour.getAboveThreshold());
4738 cs = new AnnotationColourGradient(
4739 annAlignment.getAlignmentAnnotation()[i],
4740 ColourSchemeProperty.getColour(al,
4741 viewAnnColour.getColourScheme()),
4742 viewAnnColour.getAboveThreshold());
4744 if (viewAnnColour.hasPerSequence())
4746 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4749 if (viewAnnColour.hasPredefinedColours())
4751 ((AnnotationColourGradient) cs)
4752 .setPredefinedColours(viewAnnColour
4753 .isPredefinedColours());
4755 if (propagateAnnColour && al.getGroups() != null)
4757 // Also use these settings for all the groups
4758 for (int g = 0; g < al.getGroups().size(); g++)
4760 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4768 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4769 * new AnnotationColourGradient(
4770 * annAlignment.getAlignmentAnnotation()[i], new
4771 * java.awt.Color(viewAnnColour. getMinColour()), new
4772 * java.awt.Color(viewAnnColour. getMaxColour()),
4773 * viewAnnColour.getAboveThreshold()); } else
4776 sg.cs = new AnnotationColourGradient(
4777 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4778 viewAnnColour.getAboveThreshold());
4779 if (cs instanceof AnnotationColourGradient)
4781 if (viewAnnColour.hasPerSequence())
4783 ((AnnotationColourGradient) cs)
4784 .setSeqAssociated(viewAnnColour.isPerSequence());
4786 if (viewAnnColour.hasPredefinedColours())
4788 ((AnnotationColourGradient) cs)
4789 .setPredefinedColours(viewAnnColour
4790 .isPredefinedColours());
4806 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4807 List<JvAnnotRow> autoAlan)
4809 // copy over visualization settings for autocalculated annotation in the
4811 if (al.getAlignmentAnnotation() != null)
4814 * Kludge for magic autoannotation names (see JAL-811)
4816 String[] magicNames = new String[] { "Consensus", "Quality",
4818 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4819 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4820 for (String nm : magicNames)
4822 visan.put(nm, nullAnnot);
4824 for (JvAnnotRow auan : autoAlan)
4826 visan.put(auan.template.label
4827 + (auan.template.getCalcId() == null ? "" : "\t"
4828 + auan.template.getCalcId()), auan);
4830 int hSize = al.getAlignmentAnnotation().length;
4831 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4832 // work through any autoCalculated annotation already on the view
4833 // removing it if it should be placed in a different location on the
4834 // annotation panel.
4835 List<String> remains = new ArrayList<String>(visan.keySet());
4836 for (int h = 0; h < hSize; h++)
4838 jalview.datamodel.AlignmentAnnotation jalan = al
4839 .getAlignmentAnnotation()[h];
4840 if (jalan.autoCalculated)
4843 JvAnnotRow valan = visan.get(k = jalan.label);
4844 if (jalan.getCalcId() != null)
4846 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4851 // delete the auto calculated row from the alignment
4852 al.deleteAnnotation(jalan, false);
4856 if (valan != nullAnnot)
4858 if (jalan != valan.template)
4860 // newly created autoannotation row instance
4861 // so keep a reference to the visible annotation row
4862 // and copy over all relevant attributes
4863 if (valan.template.graphHeight >= 0)
4866 jalan.graphHeight = valan.template.graphHeight;
4868 jalan.visible = valan.template.visible;
4870 reorder.add(new JvAnnotRow(valan.order, jalan));
4875 // Add any (possibly stale) autocalculated rows that were not appended to
4876 // the view during construction
4877 for (String other : remains)
4879 JvAnnotRow othera = visan.get(other);
4880 if (othera != nullAnnot && othera.template.getCalcId() != null
4881 && othera.template.getCalcId().length() > 0)
4883 reorder.add(othera);
4886 // now put the automatic annotation in its correct place
4887 int s = 0, srt[] = new int[reorder.size()];
4888 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4889 for (JvAnnotRow jvar : reorder)
4892 srt[s++] = jvar.order;
4895 jalview.util.QuickSort.sort(srt, rws);
4896 // and re-insert the annotation at its correct position
4897 for (JvAnnotRow jvar : rws)
4899 al.addAnnotation(jvar.template, jvar.order);
4901 af.alignPanel.adjustAnnotationHeight();
4905 Hashtable skipList = null;
4908 * TODO remove this method
4911 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4912 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4913 * throw new Error("Implementation Error. No skipList defined for this
4914 * Jalview2XML instance."); } return (AlignFrame)
4915 * skipList.get(view.getSequenceSetId()); }
4919 * Check if the Jalview view contained in object should be skipped or not.
4922 * @return true if view's sequenceSetId is a key in skipList
4924 private boolean skipViewport(JalviewModel object)
4926 if (skipList == null)
4931 if (skipList.containsKey(id = object.getJalviewModelSequence()
4932 .getViewport()[0].getSequenceSetId()))
4934 if (Cache.log != null && Cache.log.isDebugEnabled())
4936 Cache.log.debug("Skipping seuqence set id " + id);
4943 public void addToSkipList(AlignFrame af)
4945 if (skipList == null)
4947 skipList = new Hashtable();
4949 skipList.put(af.getViewport().getSequenceSetId(), af);
4952 public void clearSkipList()
4954 if (skipList != null)
4961 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4962 boolean ignoreUnrefed)
4964 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4966 Vector dseqs = null;
4969 // create a list of new dataset sequences
4970 dseqs = new Vector();
4972 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4974 Sequence vamsasSeq = vamsasSet.getSequence(i);
4975 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4977 // create a new dataset
4980 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4981 dseqs.copyInto(dsseqs);
4982 ds = new jalview.datamodel.Alignment(dsseqs);
4983 debug("Created new dataset " + vamsasSet.getDatasetId()
4984 + " for alignment " + System.identityHashCode(al));
4985 addDatasetRef(vamsasSet.getDatasetId(), ds);
4987 // set the dataset for the newly imported alignment.
4988 if (al.getDataset() == null && !ignoreUnrefed)
4997 * sequence definition to create/merge dataset sequence for
5001 * vector to add new dataset sequence to
5002 * @param ignoreUnrefed
5003 * - when true, don't create new sequences from vamsasSeq if it's id
5004 * doesn't already have an asssociated Jalview sequence.
5006 * - used to reorder the sequence in the alignment according to the
5007 * vamsasSeq array ordering, to preserve ordering of dataset
5009 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5010 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5012 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5014 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5015 boolean reorder = false;
5016 SequenceI dsq = null;
5017 if (sq != null && sq.getDatasetSequence() != null)
5019 dsq = sq.getDatasetSequence();
5025 if (sq == null && ignoreUnrefed)
5029 String sqid = vamsasSeq.getDsseqid();
5032 // need to create or add a new dataset sequence reference to this sequence
5035 dsq = seqRefIds.get(sqid);
5040 // make a new dataset sequence
5041 dsq = sq.createDatasetSequence();
5044 // make up a new dataset reference for this sequence
5045 sqid = seqHash(dsq);
5047 dsq.setVamsasId(uniqueSetSuffix + sqid);
5048 seqRefIds.put(sqid, dsq);
5053 dseqs.addElement(dsq);
5058 ds.addSequence(dsq);
5064 { // make this dataset sequence sq's dataset sequence
5065 sq.setDatasetSequence(dsq);
5066 // and update the current dataset alignment
5071 if (!dseqs.contains(dsq))
5078 if (ds.findIndex(dsq) < 0)
5080 ds.addSequence(dsq);
5087 // TODO: refactor this as a merge dataset sequence function
5088 // now check that sq (the dataset sequence) sequence really is the union of
5089 // all references to it
5090 // boolean pre = sq.getStart() < dsq.getStart();
5091 // boolean post = sq.getEnd() > dsq.getEnd();
5095 // StringBuffer sb = new StringBuffer();
5096 String newres = jalview.analysis.AlignSeq.extractGaps(
5097 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5098 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5099 && newres.length() > dsq.getLength())
5101 // Update with the longer sequence.
5105 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5106 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5107 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5108 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5110 dsq.setSequence(newres);
5112 // TODO: merges will never happen if we 'know' we have the real dataset
5113 // sequence - this should be detected when id==dssid
5115 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5116 // + (pre ? "prepended" : "") + " "
5117 // + (post ? "appended" : ""));
5122 // sequence refs are identical. We may need to update the existing dataset
5123 // alignment with this one, though.
5124 if (ds != null && dseqs == null)
5126 int opos = ds.findIndex(dsq);
5127 SequenceI tseq = null;
5128 if (opos != -1 && vseqpos != opos)
5130 // remove from old position
5131 ds.deleteSequence(dsq);
5133 if (vseqpos < ds.getHeight())
5135 if (vseqpos != opos)
5137 // save sequence at destination position
5138 tseq = ds.getSequenceAt(vseqpos);
5139 ds.replaceSequenceAt(vseqpos, dsq);
5140 ds.addSequence(tseq);
5145 ds.addSequence(dsq);
5152 * TODO use AlignmentI here and in related methods - needs
5153 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5155 Hashtable<String, AlignmentI> datasetIds = null;
5157 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5159 private AlignmentI getDatasetFor(String datasetId)
5161 if (datasetIds == null)
5163 datasetIds = new Hashtable<String, AlignmentI>();
5166 if (datasetIds.containsKey(datasetId))
5168 return datasetIds.get(datasetId);
5173 private void addDatasetRef(String datasetId, AlignmentI dataset)
5175 if (datasetIds == null)
5177 datasetIds = new Hashtable<String, AlignmentI>();
5179 datasetIds.put(datasetId, dataset);
5183 * make a new dataset ID for this jalview dataset alignment
5188 private String getDatasetIdRef(AlignmentI dataset)
5190 if (dataset.getDataset() != null)
5192 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5194 String datasetId = makeHashCode(dataset, null);
5195 if (datasetId == null)
5197 // make a new datasetId and record it
5198 if (dataset2Ids == null)
5200 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5204 datasetId = dataset2Ids.get(dataset);
5206 if (datasetId == null)
5208 datasetId = "ds" + dataset2Ids.size() + 1;
5209 dataset2Ids.put(dataset, datasetId);
5215 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5217 for (int d = 0; d < sequence.getDBRefCount(); d++)
5219 DBRef dr = sequence.getDBRef(d);
5220 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5221 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5222 .getVersion(), sequence.getDBRef(d).getAccessionId());
5223 if (dr.getMapping() != null)
5225 entry.setMap(addMapping(dr.getMapping()));
5227 datasetSequence.addDBRef(entry);
5231 private jalview.datamodel.Mapping addMapping(Mapping m)
5233 SequenceI dsto = null;
5234 // Mapping m = dr.getMapping();
5235 int fr[] = new int[m.getMapListFromCount() * 2];
5236 Enumeration f = m.enumerateMapListFrom();
5237 for (int _i = 0; f.hasMoreElements(); _i += 2)
5239 MapListFrom mf = (MapListFrom) f.nextElement();
5240 fr[_i] = mf.getStart();
5241 fr[_i + 1] = mf.getEnd();
5243 int fto[] = new int[m.getMapListToCount() * 2];
5244 f = m.enumerateMapListTo();
5245 for (int _i = 0; f.hasMoreElements(); _i += 2)
5247 MapListTo mf = (MapListTo) f.nextElement();
5248 fto[_i] = mf.getStart();
5249 fto[_i + 1] = mf.getEnd();
5251 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5252 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5253 if (m.getMappingChoice() != null)
5255 MappingChoice mc = m.getMappingChoice();
5256 if (mc.getDseqFor() != null)
5258 String dsfor = "" + mc.getDseqFor();
5259 if (seqRefIds.containsKey(dsfor))
5264 jmap.setTo(seqRefIds.get(dsfor));
5268 frefedSequence.add(newMappingRef(dsfor, jmap));
5274 * local sequence definition
5276 Sequence ms = mc.getSequence();
5277 SequenceI djs = null;
5278 String sqid = ms.getDsseqid();
5279 if (sqid != null && sqid.length() > 0)
5282 * recover dataset sequence
5284 djs = seqRefIds.get(sqid);
5289 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5290 sqid = ((Object) ms).toString(); // make up a new hascode for
5291 // undefined dataset sequence hash
5292 // (unlikely to happen)
5298 * make a new dataset sequence and add it to refIds hash
5300 djs = new jalview.datamodel.Sequence(ms.getName(),
5302 djs.setStart(jmap.getMap().getToLowest());
5303 djs.setEnd(jmap.getMap().getToHighest());
5304 djs.setVamsasId(uniqueSetSuffix + sqid);
5306 incompleteSeqs.put(sqid, djs);
5307 seqRefIds.put(sqid, djs);
5310 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5319 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5320 boolean keepSeqRefs)
5323 JalviewModel jm = saveState(ap, null, null, null);
5328 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5332 uniqueSetSuffix = "";
5333 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5338 if (this.frefedSequence == null)
5340 frefedSequence = new Vector();
5343 viewportsAdded.clear();
5345 AlignFrame af = loadFromObject(jm, null, false, null);
5346 af.alignPanels.clear();
5347 af.closeMenuItem_actionPerformed(true);
5350 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5351 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5352 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5353 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5354 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5357 return af.alignPanel;
5361 * flag indicating if hashtables should be cleared on finalization TODO this
5362 * flag may not be necessary
5364 private final boolean _cleartables = true;
5366 private Hashtable jvids2vobj;
5371 * @see java.lang.Object#finalize()
5374 protected void finalize() throws Throwable
5376 // really make sure we have no buried refs left.
5381 this.seqRefIds = null;
5382 this.seqsToIds = null;
5386 private void warn(String msg)
5391 private void warn(String msg, Exception e)
5393 if (Cache.log != null)
5397 Cache.log.warn(msg, e);
5401 Cache.log.warn(msg);
5406 System.err.println("Warning: " + msg);
5409 e.printStackTrace();
5414 private void debug(String string)
5416 debug(string, null);
5419 private void debug(String msg, Exception e)
5421 if (Cache.log != null)
5425 Cache.log.debug(msg, e);
5429 Cache.log.debug(msg);
5434 System.err.println("Warning: " + msg);
5437 e.printStackTrace();
5443 * set the object to ID mapping tables used to write/recover objects and XML
5444 * ID strings for the jalview project. If external tables are provided then
5445 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5446 * object goes out of scope. - also populates the datasetIds hashtable with
5447 * alignment objects containing dataset sequences
5450 * Map from ID strings to jalview datamodel
5452 * Map from jalview datamodel to ID strings
5456 public void setObjectMappingTables(Hashtable vobj2jv,
5457 IdentityHashMap jv2vobj)
5459 this.jv2vobj = jv2vobj;
5460 this.vobj2jv = vobj2jv;
5461 Iterator ds = jv2vobj.keySet().iterator();
5463 while (ds.hasNext())
5465 Object jvobj = ds.next();
5466 id = jv2vobj.get(jvobj).toString();
5467 if (jvobj instanceof jalview.datamodel.Alignment)
5469 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5471 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5474 else if (jvobj instanceof jalview.datamodel.Sequence)
5476 // register sequence object so the XML parser can recover it.
5477 if (seqRefIds == null)
5479 seqRefIds = new HashMap<String, SequenceI>();
5481 if (seqsToIds == null)
5483 seqsToIds = new IdentityHashMap<SequenceI, String>();
5485 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5486 seqsToIds.put((SequenceI) jvobj, id);
5488 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5491 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5492 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5493 if (jvann.annotationId == null)
5495 jvann.annotationId = anid;
5497 if (!jvann.annotationId.equals(anid))
5499 // TODO verify that this is the correct behaviour
5500 this.warn("Overriding Annotation ID for " + anid
5501 + " from different id : " + jvann.annotationId);
5502 jvann.annotationId = anid;
5505 else if (jvobj instanceof String)
5507 if (jvids2vobj == null)
5509 jvids2vobj = new Hashtable();
5510 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5515 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5521 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5522 * objects created from the project archive. If string is null (default for
5523 * construction) then suffix will be set automatically.
5527 public void setUniqueSetSuffix(String string)
5529 uniqueSetSuffix = string;
5534 * uses skipList2 as the skipList for skipping views on sequence sets
5535 * associated with keys in the skipList
5539 public void setSkipList(Hashtable skipList2)
5541 skipList = skipList2;
5545 * Reads the jar entry of given name and returns its contents, or null if the
5546 * entry is not found.
5549 * @param jarEntryName
5552 protected String readJarEntry(jarInputStreamProvider jprovider,
5553 String jarEntryName)
5555 String result = null;
5556 BufferedReader in = null;
5561 * Reopen the jar input stream and traverse its entries to find a matching
5564 JarInputStream jin = jprovider.getJarInputStream();
5565 JarEntry entry = null;
5568 entry = jin.getNextJarEntry();
5569 } while (entry != null && !entry.getName().equals(jarEntryName));
5573 StringBuilder out = new StringBuilder(256);
5574 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5577 while ((data = in.readLine()) != null)
5581 result = out.toString();
5585 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5587 } catch (Exception ex)
5589 ex.printStackTrace();
5597 } catch (IOException e)
5608 * Returns an incrementing counter (0, 1, 2...)
5612 private synchronized int nextCounter()