2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.analysis.Conservation;
24 import jalview.api.FeatureColourI;
25 import jalview.api.ViewStyleI;
26 import jalview.api.structures.JalviewStructureDisplayI;
27 import jalview.bin.Cache;
28 import jalview.datamodel.AlignedCodonFrame;
29 import jalview.datamodel.Alignment;
30 import jalview.datamodel.AlignmentAnnotation;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.RnaViewerModel;
34 import jalview.datamodel.SequenceGroup;
35 import jalview.datamodel.SequenceI;
36 import jalview.datamodel.StructureViewerModel;
37 import jalview.datamodel.StructureViewerModel.StructureData;
38 import jalview.ext.varna.RnaModel;
39 import jalview.gui.StructureViewer.ViewerType;
40 import jalview.io.DataSourceType;
41 import jalview.io.FileFormat;
42 import jalview.schemabinding.version2.AlcodMap;
43 import jalview.schemabinding.version2.AlcodonFrame;
44 import jalview.schemabinding.version2.Annotation;
45 import jalview.schemabinding.version2.AnnotationColours;
46 import jalview.schemabinding.version2.AnnotationElement;
47 import jalview.schemabinding.version2.CalcIdParam;
48 import jalview.schemabinding.version2.DBRef;
49 import jalview.schemabinding.version2.Features;
50 import jalview.schemabinding.version2.Group;
51 import jalview.schemabinding.version2.HiddenColumns;
52 import jalview.schemabinding.version2.JGroup;
53 import jalview.schemabinding.version2.JSeq;
54 import jalview.schemabinding.version2.JalviewModel;
55 import jalview.schemabinding.version2.JalviewModelSequence;
56 import jalview.schemabinding.version2.MapListFrom;
57 import jalview.schemabinding.version2.MapListTo;
58 import jalview.schemabinding.version2.Mapping;
59 import jalview.schemabinding.version2.MappingChoice;
60 import jalview.schemabinding.version2.OtherData;
61 import jalview.schemabinding.version2.PdbentryItem;
62 import jalview.schemabinding.version2.Pdbids;
63 import jalview.schemabinding.version2.Property;
64 import jalview.schemabinding.version2.RnaViewer;
65 import jalview.schemabinding.version2.SecondaryStructure;
66 import jalview.schemabinding.version2.Sequence;
67 import jalview.schemabinding.version2.SequenceSet;
68 import jalview.schemabinding.version2.SequenceSetProperties;
69 import jalview.schemabinding.version2.Setting;
70 import jalview.schemabinding.version2.StructureState;
71 import jalview.schemabinding.version2.ThresholdLine;
72 import jalview.schemabinding.version2.Tree;
73 import jalview.schemabinding.version2.UserColours;
74 import jalview.schemabinding.version2.Viewport;
75 import jalview.schemes.AnnotationColourGradient;
76 import jalview.schemes.ColourSchemeI;
77 import jalview.schemes.ColourSchemeProperty;
78 import jalview.schemes.FeatureColour;
79 import jalview.schemes.ResidueColourScheme;
80 import jalview.schemes.ResidueProperties;
81 import jalview.schemes.UserColourScheme;
82 import jalview.structure.StructureSelectionManager;
83 import jalview.structures.models.AAStructureBindingModel;
84 import jalview.util.MessageManager;
85 import jalview.util.Platform;
86 import jalview.util.StringUtils;
87 import jalview.util.jarInputStreamProvider;
88 import jalview.viewmodel.AlignmentViewport;
89 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
90 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
91 import jalview.ws.jws2.Jws2Discoverer;
92 import jalview.ws.jws2.dm.AAConSettings;
93 import jalview.ws.jws2.jabaws2.Jws2Instance;
94 import jalview.ws.params.ArgumentI;
95 import jalview.ws.params.AutoCalcSetting;
96 import jalview.ws.params.WsParamSetI;
98 import java.awt.Color;
99 import java.awt.Rectangle;
100 import java.io.BufferedReader;
101 import java.io.DataInputStream;
102 import java.io.DataOutputStream;
104 import java.io.FileInputStream;
105 import java.io.FileOutputStream;
106 import java.io.IOException;
107 import java.io.InputStreamReader;
108 import java.io.OutputStreamWriter;
109 import java.io.PrintWriter;
110 import java.lang.reflect.InvocationTargetException;
111 import java.net.MalformedURLException;
113 import java.util.ArrayList;
114 import java.util.Arrays;
115 import java.util.Enumeration;
116 import java.util.HashMap;
117 import java.util.HashSet;
118 import java.util.Hashtable;
119 import java.util.IdentityHashMap;
120 import java.util.Iterator;
121 import java.util.LinkedHashMap;
122 import java.util.List;
123 import java.util.Map;
124 import java.util.Map.Entry;
125 import java.util.Set;
126 import java.util.Vector;
127 import java.util.jar.JarEntry;
128 import java.util.jar.JarInputStream;
129 import java.util.jar.JarOutputStream;
131 import javax.swing.JInternalFrame;
132 import javax.swing.SwingUtilities;
134 import org.exolab.castor.xml.Marshaller;
135 import org.exolab.castor.xml.Unmarshaller;
138 * Write out the current jalview desktop state as a Jalview XML stream.
140 * Note: the vamsas objects referred to here are primitive versions of the
141 * VAMSAS project schema elements - they are not the same and most likely never
145 * @version $Revision: 1.134 $
147 public class Jalview2XML
149 private static final String VIEWER_PREFIX = "viewer_";
151 private static final String RNA_PREFIX = "rna_";
153 private static final String UTF_8 = "UTF-8";
155 // use this with nextCounter() to make unique names for entities
156 private int counter = 0;
159 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
160 * of sequence objects are created.
162 IdentityHashMap<SequenceI, String> seqsToIds = null;
165 * jalview XML Sequence ID to jalview sequence object reference (both dataset
166 * and alignment sequences. Populated as XML reps of sequence objects are
169 Map<String, SequenceI> seqRefIds = null;
171 Map<String, SequenceI> incompleteSeqs = null;
173 List<SeqFref> frefedSequence = null;
175 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
178 * Map of reconstructed AlignFrame objects that appear to have come from
179 * SplitFrame objects (have a dna/protein complement view).
181 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
184 * Map from displayed rna structure models to their saved session state jar
187 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
190 * create/return unique hash string for sq
193 * @return new or existing unique string for sq
195 String seqHash(SequenceI sq)
197 if (seqsToIds == null)
201 if (seqsToIds.containsKey(sq))
203 return seqsToIds.get(sq);
207 // create sequential key
208 String key = "sq" + (seqsToIds.size() + 1);
209 key = makeHashCode(sq, key); // check we don't have an external reference
211 seqsToIds.put(sq, key);
220 if (seqRefIds != null)
224 if (seqsToIds != null)
228 if (incompleteSeqs != null)
230 incompleteSeqs.clear();
238 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
239 // seqRefIds = new Hashtable();
240 // seqsToIds = new IdentityHashMap();
246 if (seqsToIds == null)
248 seqsToIds = new IdentityHashMap<SequenceI, String>();
250 if (seqRefIds == null)
252 seqRefIds = new HashMap<String, SequenceI>();
254 if (incompleteSeqs == null)
256 incompleteSeqs = new HashMap<String, SequenceI>();
258 if (frefedSequence == null)
260 frefedSequence = new ArrayList<SeqFref>();
268 public Jalview2XML(boolean raiseGUI)
270 this.raiseGUI = raiseGUI;
274 * base class for resolving forward references to sequences by their ID
279 abstract class SeqFref
285 public SeqFref(String _sref, String type)
291 public String getSref()
296 public SequenceI getSrefSeq()
298 return seqRefIds.get(sref);
301 public boolean isResolvable()
303 return seqRefIds.get(sref) != null;
306 public SequenceI getSrefDatasetSeq()
308 SequenceI sq = seqRefIds.get(sref);
311 while (sq.getDatasetSequence() != null)
313 sq = sq.getDatasetSequence();
320 * @return true if the forward reference was fully resolved
322 abstract boolean resolve();
325 public String toString()
327 return type + " reference to " + sref;
332 * create forward reference for a mapping
338 public SeqFref newMappingRef(final String sref,
339 final jalview.datamodel.Mapping _jmap)
341 SeqFref fref = new SeqFref(sref, "Mapping")
343 public jalview.datamodel.Mapping jmap = _jmap;
348 SequenceI seq = getSrefDatasetSeq();
360 public SeqFref newAlcodMapRef(final String sref,
361 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
364 SeqFref fref = new SeqFref(sref, "Codon Frame")
366 AlignedCodonFrame cf = _cf;
368 public jalview.datamodel.Mapping mp = _jmap;
371 public boolean isResolvable()
373 return super.isResolvable() && mp.getTo() != null;
379 SequenceI seq = getSrefDatasetSeq();
384 cf.addMap(seq, mp.getTo(), mp.getMap());
391 public void resolveFrefedSequences()
393 Iterator<SeqFref> nextFref = frefedSequence.iterator();
394 int toresolve = frefedSequence.size();
395 int unresolved = 0, failedtoresolve = 0;
396 while (nextFref.hasNext())
398 SeqFref ref = nextFref.next();
399 if (ref.isResolvable())
411 } catch (Exception x)
414 .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
427 System.err.println("Jalview Project Import: There were " + unresolved
428 + " forward references left unresolved on the stack.");
430 if (failedtoresolve > 0)
432 System.err.println("SERIOUS! " + failedtoresolve
433 + " resolvable forward references failed to resolve.");
435 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
437 System.err.println("Jalview Project Import: There are "
438 + incompleteSeqs.size()
439 + " sequences which may have incomplete metadata.");
440 if (incompleteSeqs.size() < 10)
442 for (SequenceI s : incompleteSeqs.values())
444 System.err.println(s.toString());
450 .println("Too many to report. Skipping output of incomplete sequences.");
456 * This maintains a map of viewports, the key being the seqSetId. Important to
457 * set historyItem and redoList for multiple views
459 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
461 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
463 String uniqueSetSuffix = "";
466 * List of pdbfiles added to Jar
468 List<String> pdbfiles = null;
470 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
471 public void saveState(File statefile)
473 FileOutputStream fos = null;
476 fos = new FileOutputStream(statefile);
477 JarOutputStream jout = new JarOutputStream(fos);
480 } catch (Exception e)
482 // TODO: inform user of the problem - they need to know if their data was
484 if (errorMessage == null)
486 errorMessage = "Couldn't write Jalview Archive to output file '"
487 + statefile + "' - See console error log for details";
491 errorMessage += "(output file was '" + statefile + "')";
501 } catch (IOException e)
511 * Writes a jalview project archive to the given Jar output stream.
515 public void saveState(JarOutputStream jout)
517 AlignFrame[] frames = Desktop.getAlignFrames();
523 saveAllFrames(Arrays.asList(frames), jout);
527 * core method for storing state for a set of AlignFrames.
530 * - frames involving all data to be exported (including containing
533 * - project output stream
535 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
537 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
540 * ensure cached data is clear before starting
542 // todo tidy up seqRefIds, seqsToIds initialisation / reset
544 splitFrameCandidates.clear();
549 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
550 // //////////////////////////////////////////////////
552 List<String> shortNames = new ArrayList<String>();
553 List<String> viewIds = new ArrayList<String>();
556 for (int i = frames.size() - 1; i > -1; i--)
558 AlignFrame af = frames.get(i);
562 .containsKey(af.getViewport().getSequenceSetId()))
567 String shortName = makeFilename(af, shortNames);
569 int ap, apSize = af.alignPanels.size();
571 for (ap = 0; ap < apSize; ap++)
573 AlignmentPanel apanel = af.alignPanels.get(ap);
574 String fileName = apSize == 1 ? shortName : ap + shortName;
575 if (!fileName.endsWith(".xml"))
577 fileName = fileName + ".xml";
580 saveState(apanel, fileName, jout, viewIds);
582 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
584 if (!dsses.containsKey(dssid))
586 dsses.put(dssid, af);
591 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
597 } catch (Exception foo)
602 } catch (Exception ex)
604 // TODO: inform user of the problem - they need to know if their data was
606 if (errorMessage == null)
608 errorMessage = "Couldn't write Jalview Archive - see error output for details";
610 ex.printStackTrace();
615 * Generates a distinct file name, based on the title of the AlignFrame, by
616 * appending _n for increasing n until an unused name is generated. The new
617 * name (without its extension) is added to the list.
621 * @return the generated name, with .xml extension
623 protected String makeFilename(AlignFrame af, List<String> namesUsed)
625 String shortName = af.getTitle();
627 if (shortName.indexOf(File.separatorChar) > -1)
629 shortName = shortName.substring(shortName
630 .lastIndexOf(File.separatorChar) + 1);
635 while (namesUsed.contains(shortName))
637 if (shortName.endsWith("_" + (count - 1)))
639 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
642 shortName = shortName.concat("_" + count);
646 namesUsed.add(shortName);
648 if (!shortName.endsWith(".xml"))
650 shortName = shortName + ".xml";
655 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
656 public boolean saveAlignment(AlignFrame af, String jarFile,
661 FileOutputStream fos = new FileOutputStream(jarFile);
662 JarOutputStream jout = new JarOutputStream(fos);
663 List<AlignFrame> frames = new ArrayList<AlignFrame>();
665 // resolve splitframes
666 if (af.getViewport().getCodingComplement() != null)
668 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
674 saveAllFrames(frames, jout);
678 } catch (Exception foo)
684 } catch (Exception ex)
686 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
687 ex.printStackTrace();
692 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
693 String fileName, JarOutputStream jout)
696 for (String dssids : dsses.keySet())
698 AlignFrame _af = dsses.get(dssids);
699 String jfileName = fileName + " Dataset for " + _af.getTitle();
700 if (!jfileName.endsWith(".xml"))
702 jfileName = jfileName + ".xml";
704 saveState(_af.alignPanel, jfileName, true, jout, null);
709 * create a JalviewModel from an alignment view and marshall it to a
713 * panel to create jalview model for
715 * name of alignment panel written to output stream
722 public JalviewModel saveState(AlignmentPanel ap, String fileName,
723 JarOutputStream jout, List<String> viewIds)
725 return saveState(ap, fileName, false, jout, viewIds);
729 * create a JalviewModel from an alignment view and marshall it to a
733 * panel to create jalview model for
735 * name of alignment panel written to output stream
737 * when true, only write the dataset for the alignment, not the data
738 * associated with the view.
744 public JalviewModel saveState(AlignmentPanel ap, String fileName,
745 boolean storeDS, JarOutputStream jout, List<String> viewIds)
749 viewIds = new ArrayList<String>();
754 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
756 AlignViewport av = ap.av;
758 JalviewModel object = new JalviewModel();
759 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
761 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
762 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
763 "Development Build"));
766 * rjal is full height alignment, jal is actual alignment with full metadata
767 * but excludes hidden sequences.
769 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
771 if (av.hasHiddenRows())
773 rjal = jal.getHiddenSequences().getFullAlignment();
776 SequenceSet vamsasSet = new SequenceSet();
778 JalviewModelSequence jms = new JalviewModelSequence();
780 vamsasSet.setGapChar(jal.getGapCharacter() + "");
782 if (jal.getDataset() != null)
784 // dataset id is the dataset's hashcode
785 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
788 // switch jal and the dataset
789 jal = jal.getDataset();
793 if (jal.getProperties() != null)
795 Enumeration en = jal.getProperties().keys();
796 while (en.hasMoreElements())
798 String key = en.nextElement().toString();
799 SequenceSetProperties ssp = new SequenceSetProperties();
801 ssp.setValue(jal.getProperties().get(key).toString());
802 vamsasSet.addSequenceSetProperties(ssp);
807 Set<String> calcIdSet = new HashSet<String>();
808 // record the set of vamsas sequence XML POJO we create.
809 HashMap<String, Sequence> vamsasSetIds = new HashMap<String, Sequence>();
811 for (final SequenceI jds : rjal.getSequences())
813 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
814 : jds.getDatasetSequence();
815 String id = seqHash(jds);
816 if (vamsasSetIds.get(id) == null)
818 if (seqRefIds.get(id) != null && !storeDS)
820 // This happens for two reasons: 1. multiple views are being
822 // 2. the hashCode has collided with another sequence's code. This
824 // HAPPEN! (PF00072.15.stk does this)
825 // JBPNote: Uncomment to debug writing out of files that do not read
826 // back in due to ArrayOutOfBoundExceptions.
827 // System.err.println("vamsasSeq backref: "+id+"");
828 // System.err.println(jds.getName()+"
829 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
830 // System.err.println("Hashcode: "+seqHash(jds));
831 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
832 // System.err.println(rsq.getName()+"
833 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
834 // System.err.println("Hashcode: "+seqHash(rsq));
838 vamsasSeq = createVamsasSequence(id, jds);
839 vamsasSet.addSequence(vamsasSeq);
840 vamsasSetIds.put(id, vamsasSeq);
841 seqRefIds.put(id, jds);
845 jseq.setStart(jds.getStart());
846 jseq.setEnd(jds.getEnd());
847 jseq.setColour(av.getSequenceColour(jds).getRGB());
849 jseq.setId(id); // jseq id should be a string not a number
852 // Store any sequences this sequence represents
853 if (av.hasHiddenRows())
855 // use rjal, contains the full height alignment
856 jseq.setHidden(av.getAlignment().getHiddenSequences()
859 if (av.isHiddenRepSequence(jds))
861 jalview.datamodel.SequenceI[] reps = av
862 .getRepresentedSequences(jds).getSequencesInOrder(rjal);
864 for (int h = 0; h < reps.length; h++)
868 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
873 // mark sequence as reference - if it is the reference for this view
876 jseq.setViewreference(jds == jal.getSeqrep());
880 // TODO: omit sequence features from each alignment view's XML dump if we
881 // are storing dataset
882 if (jds.getSequenceFeatures() != null)
884 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
886 while (index < sf.length)
888 Features features = new Features();
890 features.setBegin(sf[index].getBegin());
891 features.setEnd(sf[index].getEnd());
892 features.setDescription(sf[index].getDescription());
893 features.setType(sf[index].getType());
894 features.setFeatureGroup(sf[index].getFeatureGroup());
895 features.setScore(sf[index].getScore());
896 if (sf[index].links != null)
898 for (int l = 0; l < sf[index].links.size(); l++)
900 OtherData keyValue = new OtherData();
901 keyValue.setKey("LINK_" + l);
902 keyValue.setValue(sf[index].links.elementAt(l).toString());
903 features.addOtherData(keyValue);
906 if (sf[index].otherDetails != null)
909 Iterator<String> keys = sf[index].otherDetails.keySet()
911 while (keys.hasNext())
914 OtherData keyValue = new OtherData();
915 keyValue.setKey(key);
916 keyValue.setValue(sf[index].otherDetails.get(key).toString());
917 features.addOtherData(keyValue);
921 jseq.addFeatures(features);
926 if (jdatasq.getAllPDBEntries() != null)
928 Enumeration en = jdatasq.getAllPDBEntries().elements();
929 while (en.hasMoreElements())
931 Pdbids pdb = new Pdbids();
932 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
935 String pdbId = entry.getId();
937 pdb.setType(entry.getType());
940 * Store any structure views associated with this sequence. This
941 * section copes with duplicate entries in the project, so a dataset
942 * only view *should* be coped with sensibly.
944 // This must have been loaded, is it still visible?
945 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
946 String matchedFile = null;
947 for (int f = frames.length - 1; f > -1; f--)
949 if (frames[f] instanceof StructureViewerBase)
951 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
952 matchedFile = saveStructureState(ap, jds, pdb, entry,
953 viewIds, matchedFile, viewFrame);
955 * Only store each structure viewer's state once in the project
956 * jar. First time through only (storeDS==false)
958 String viewId = viewFrame.getViewId();
959 if (!storeDS && !viewIds.contains(viewId))
964 String viewerState = viewFrame.getStateInfo();
965 writeJarEntry(jout, getViewerJarEntryName(viewId),
966 viewerState.getBytes());
967 } catch (IOException e)
969 System.err.println("Error saving viewer state: "
976 if (matchedFile != null || entry.getFile() != null)
978 if (entry.getFile() != null)
981 matchedFile = entry.getFile();
983 pdb.setFile(matchedFile); // entry.getFile());
984 if (pdbfiles == null)
986 pdbfiles = new ArrayList<String>();
989 if (!pdbfiles.contains(pdbId))
992 copyFileToJar(jout, matchedFile, pdbId);
996 Enumeration<String> props = entry.getProperties();
997 if (props.hasMoreElements())
999 PdbentryItem item = new PdbentryItem();
1000 while (props.hasMoreElements())
1002 Property prop = new Property();
1003 String key = props.nextElement();
1005 prop.setValue(entry.getProperty(key).toString());
1006 item.addProperty(prop);
1008 pdb.addPdbentryItem(item);
1011 jseq.addPdbids(pdb);
1015 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1020 if (!storeDS && av.hasHiddenRows())
1022 jal = av.getAlignment();
1026 if (storeDS && jal.getCodonFrames() != null)
1028 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1029 for (AlignedCodonFrame acf : jac)
1031 AlcodonFrame alc = new AlcodonFrame();
1032 if (acf.getProtMappings() != null
1033 && acf.getProtMappings().length > 0)
1035 boolean hasMap = false;
1036 SequenceI[] dnas = acf.getdnaSeqs();
1037 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1038 for (int m = 0; m < pmaps.length; m++)
1040 AlcodMap alcmap = new AlcodMap();
1041 alcmap.setDnasq(seqHash(dnas[m]));
1042 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1044 alc.addAlcodMap(alcmap);
1049 vamsasSet.addAlcodonFrame(alc);
1052 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1054 // AlcodonFrame alc = new AlcodonFrame();
1055 // vamsasSet.addAlcodonFrame(alc);
1056 // for (int p = 0; p < acf.aaWidth; p++)
1058 // Alcodon cmap = new Alcodon();
1059 // if (acf.codons[p] != null)
1061 // // Null codons indicate a gapped column in the translated peptide
1063 // cmap.setPos1(acf.codons[p][0]);
1064 // cmap.setPos2(acf.codons[p][1]);
1065 // cmap.setPos3(acf.codons[p][2]);
1067 // alc.addAlcodon(cmap);
1069 // if (acf.getProtMappings() != null
1070 // && acf.getProtMappings().length > 0)
1072 // SequenceI[] dnas = acf.getdnaSeqs();
1073 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1074 // for (int m = 0; m < pmaps.length; m++)
1076 // AlcodMap alcmap = new AlcodMap();
1077 // alcmap.setDnasq(seqHash(dnas[m]));
1078 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1080 // alc.addAlcodMap(alcmap);
1087 // /////////////////////////////////
1088 if (!storeDS && av.currentTree != null)
1090 // FIND ANY ASSOCIATED TREES
1091 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1092 if (Desktop.desktop != null)
1094 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1096 for (int t = 0; t < frames.length; t++)
1098 if (frames[t] instanceof TreePanel)
1100 TreePanel tp = (TreePanel) frames[t];
1102 if (tp.treeCanvas.av.getAlignment() == jal)
1104 Tree tree = new Tree();
1105 tree.setTitle(tp.getTitle());
1106 tree.setCurrentTree((av.currentTree == tp.getTree()));
1107 tree.setNewick(tp.getTree().toString());
1108 tree.setThreshold(tp.treeCanvas.threshold);
1110 tree.setFitToWindow(tp.fitToWindow.getState());
1111 tree.setFontName(tp.getTreeFont().getName());
1112 tree.setFontSize(tp.getTreeFont().getSize());
1113 tree.setFontStyle(tp.getTreeFont().getStyle());
1114 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1116 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1117 tree.setShowDistances(tp.distanceMenu.getState());
1119 tree.setHeight(tp.getHeight());
1120 tree.setWidth(tp.getWidth());
1121 tree.setXpos(tp.getX());
1122 tree.setYpos(tp.getY());
1123 tree.setId(makeHashCode(tp, null));
1133 * store forward refs from an annotationRow to any groups
1135 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1138 for (SequenceI sq : jal.getSequences())
1140 // Store annotation on dataset sequences only
1141 AlignmentAnnotation[] aa = sq.getAnnotation();
1142 if (aa != null && aa.length > 0)
1144 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1151 if (jal.getAlignmentAnnotation() != null)
1153 // Store the annotation shown on the alignment.
1154 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1155 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1160 if (jal.getGroups() != null)
1162 JGroup[] groups = new JGroup[jal.getGroups().size()];
1164 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1166 JGroup jGroup = new JGroup();
1167 groups[++i] = jGroup;
1169 jGroup.setStart(sg.getStartRes());
1170 jGroup.setEnd(sg.getEndRes());
1171 jGroup.setName(sg.getName());
1172 if (groupRefs.containsKey(sg))
1174 // group has references so set its ID field
1175 jGroup.setId(groupRefs.get(sg));
1179 if (sg.cs.conservationApplied())
1181 jGroup.setConsThreshold(sg.cs.getConservationInc());
1183 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1185 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1189 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1192 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1194 jGroup.setColour("AnnotationColourGradient");
1195 jGroup.setAnnotationColours(constructAnnotationColours(
1196 (jalview.schemes.AnnotationColourGradient) sg.cs,
1199 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1201 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1205 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1208 jGroup.setPidThreshold(sg.cs.getThreshold());
1211 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1212 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1213 jGroup.setDisplayText(sg.getDisplayText());
1214 jGroup.setColourText(sg.getColourText());
1215 jGroup.setTextCol1(sg.textColour.getRGB());
1216 jGroup.setTextCol2(sg.textColour2.getRGB());
1217 jGroup.setTextColThreshold(sg.thresholdTextColour);
1218 jGroup.setShowUnconserved(sg.getShowNonconserved());
1219 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1220 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1221 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1222 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1223 for (SequenceI seq : sg.getSequences())
1225 jGroup.addSeq(seqHash(seq));
1229 jms.setJGroup(groups);
1233 // /////////SAVE VIEWPORT
1234 Viewport view = new Viewport();
1235 view.setTitle(ap.alignFrame.getTitle());
1236 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1237 av.getSequenceSetId()));
1238 view.setId(av.getViewId());
1239 if (av.getCodingComplement() != null)
1241 view.setComplementId(av.getCodingComplement().getViewId());
1243 view.setViewName(av.viewName);
1244 view.setGatheredViews(av.isGatherViewsHere());
1246 Rectangle size = ap.av.getExplodedGeometry();
1247 Rectangle position = size;
1250 size = ap.alignFrame.getBounds();
1251 if (av.getCodingComplement() != null)
1253 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1261 view.setXpos(position.x);
1262 view.setYpos(position.y);
1264 view.setWidth(size.width);
1265 view.setHeight(size.height);
1267 view.setStartRes(av.startRes);
1268 view.setStartSeq(av.startSeq);
1270 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1272 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1275 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1277 AnnotationColours ac = constructAnnotationColours(
1278 (jalview.schemes.AnnotationColourGradient) av
1279 .getGlobalColourScheme(),
1282 view.setAnnotationColours(ac);
1283 view.setBgColour("AnnotationColourGradient");
1287 view.setBgColour(ColourSchemeProperty.getColourName(av
1288 .getGlobalColourScheme()));
1291 ColourSchemeI cs = av.getGlobalColourScheme();
1295 if (cs.conservationApplied())
1297 view.setConsThreshold(cs.getConservationInc());
1298 if (cs instanceof jalview.schemes.UserColourScheme)
1300 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1304 if (cs instanceof ResidueColourScheme)
1306 view.setPidThreshold(cs.getThreshold());
1310 view.setConservationSelected(av.getConservationSelected());
1311 view.setPidSelected(av.getAbovePIDThreshold());
1312 view.setFontName(av.font.getName());
1313 view.setFontSize(av.font.getSize());
1314 view.setFontStyle(av.font.getStyle());
1315 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1316 view.setRenderGaps(av.isRenderGaps());
1317 view.setShowAnnotation(av.isShowAnnotation());
1318 view.setShowBoxes(av.getShowBoxes());
1319 view.setShowColourText(av.getColourText());
1320 view.setShowFullId(av.getShowJVSuffix());
1321 view.setRightAlignIds(av.isRightAlignIds());
1322 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1323 view.setShowText(av.getShowText());
1324 view.setShowUnconserved(av.getShowUnconserved());
1325 view.setWrapAlignment(av.getWrapAlignment());
1326 view.setTextCol1(av.getTextColour().getRGB());
1327 view.setTextCol2(av.getTextColour2().getRGB());
1328 view.setTextColThreshold(av.getThresholdTextColour());
1329 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1330 view.setShowSequenceLogo(av.isShowSequenceLogo());
1331 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1332 view.setShowGroupConsensus(av.isShowGroupConsensus());
1333 view.setShowGroupConservation(av.isShowGroupConservation());
1334 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1335 view.setShowDbRefTooltip(av.isShowDBRefs());
1336 view.setFollowHighlight(av.isFollowHighlight());
1337 view.setFollowSelection(av.followSelection);
1338 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1339 if (av.getFeaturesDisplayed() != null)
1341 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1343 String[] renderOrder = ap.getSeqPanel().seqCanvas
1344 .getFeatureRenderer().getRenderOrder()
1345 .toArray(new String[0]);
1347 Vector<String> settingsAdded = new Vector<String>();
1348 if (renderOrder != null)
1350 for (String featureType : renderOrder)
1352 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1353 .getFeatureRenderer().getFeatureStyle(featureType);
1354 Setting setting = new Setting();
1355 setting.setType(featureType);
1356 if (!fcol.isSimpleColour())
1358 setting.setColour(fcol.getMaxColour().getRGB());
1359 setting.setMincolour(fcol.getMinColour().getRGB());
1360 setting.setMin(fcol.getMin());
1361 setting.setMax(fcol.getMax());
1362 setting.setColourByLabel(fcol.isColourByLabel());
1363 setting.setAutoScale(fcol.isAutoScaled());
1364 setting.setThreshold(fcol.getThreshold());
1365 // -1 = No threshold, 0 = Below, 1 = Above
1366 setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
1367 .isBelowThreshold() ? 0 : -1));
1371 setting.setColour(fcol.getColour().getRGB());
1374 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1376 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1377 .getOrder(featureType);
1380 setting.setOrder(rorder);
1382 fs.addSetting(setting);
1383 settingsAdded.addElement(featureType);
1387 // is groups actually supposed to be a map here ?
1388 Iterator<String> en = ap.getSeqPanel().seqCanvas
1389 .getFeatureRenderer().getFeatureGroups().iterator();
1390 Vector<String> groupsAdded = new Vector<String>();
1391 while (en.hasNext())
1393 String grp = en.next();
1394 if (groupsAdded.contains(grp))
1398 Group g = new Group();
1400 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1401 .getFeatureRenderer().checkGroupVisibility(grp, false))
1404 groupsAdded.addElement(grp);
1406 jms.setFeatureSettings(fs);
1409 if (av.hasHiddenColumns())
1411 if (av.getColumnSelection() == null
1412 || av.getColumnSelection().getHiddenColumns() == null)
1414 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1418 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1421 int[] region = av.getColumnSelection().getHiddenColumns()
1423 HiddenColumns hc = new HiddenColumns();
1424 hc.setStart(region[0]);
1425 hc.setEnd(region[1]);
1426 view.addHiddenColumns(hc);
1430 if (calcIdSet.size() > 0)
1432 for (String calcId : calcIdSet)
1434 if (calcId.trim().length() > 0)
1436 CalcIdParam cidp = createCalcIdParam(calcId, av);
1437 // Some calcIds have no parameters.
1440 view.addCalcIdParam(cidp);
1446 jms.addViewport(view);
1448 object.setJalviewModelSequence(jms);
1449 object.getVamsasModel().addSequenceSet(vamsasSet);
1451 if (jout != null && fileName != null)
1453 // We may not want to write the object to disk,
1454 // eg we can copy the alignViewport to a new view object
1455 // using save and then load
1458 System.out.println("Writing jar entry " + fileName);
1459 JarEntry entry = new JarEntry(fileName);
1460 jout.putNextEntry(entry);
1461 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1463 Marshaller marshaller = new Marshaller(pout);
1464 marshaller.marshal(object);
1467 } catch (Exception ex)
1469 // TODO: raise error in GUI if marshalling failed.
1470 ex.printStackTrace();
1477 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1478 * for each viewer, with
1480 * <li>viewer geometry (position, size, split pane divider location)</li>
1481 * <li>index of the selected structure in the viewer (currently shows gapped
1483 * <li>the id of the annotation holding RNA secondary structure</li>
1484 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1486 * Varna viewer state is also written out (in native Varna XML) to separate
1487 * project jar entries. A separate entry is written for each RNA structure
1488 * displayed, with the naming convention
1490 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1498 * @param storeDataset
1500 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1501 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1502 boolean storeDataset)
1504 if (Desktop.desktop == null)
1508 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1509 for (int f = frames.length - 1; f > -1; f--)
1511 if (frames[f] instanceof AppVarna)
1513 AppVarna varna = (AppVarna) frames[f];
1515 * link the sequence to every viewer that is showing it and is linked to
1516 * its alignment panel
1518 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1520 String viewId = varna.getViewId();
1521 RnaViewer rna = new RnaViewer();
1522 rna.setViewId(viewId);
1523 rna.setTitle(varna.getTitle());
1524 rna.setXpos(varna.getX());
1525 rna.setYpos(varna.getY());
1526 rna.setWidth(varna.getWidth());
1527 rna.setHeight(varna.getHeight());
1528 rna.setDividerLocation(varna.getDividerLocation());
1529 rna.setSelectedRna(varna.getSelectedIndex());
1530 jseq.addRnaViewer(rna);
1533 * Store each Varna panel's state once in the project per sequence.
1534 * First time through only (storeDataset==false)
1536 // boolean storeSessions = false;
1537 // String sequenceViewId = viewId + seqsToIds.get(jds);
1538 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1540 // viewIds.add(sequenceViewId);
1541 // storeSessions = true;
1543 for (RnaModel model : varna.getModels())
1545 if (model.seq == jds)
1548 * VARNA saves each view (sequence or alignment secondary
1549 * structure, gapped or trimmed) as a separate XML file
1551 String jarEntryName = rnaSessions.get(model);
1552 if (jarEntryName == null)
1555 String varnaStateFile = varna.getStateInfo(model.rna);
1556 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1557 copyFileToJar(jout, varnaStateFile, jarEntryName);
1558 rnaSessions.put(model, jarEntryName);
1560 SecondaryStructure ss = new SecondaryStructure();
1561 String annotationId = varna.getAnnotation(jds).annotationId;
1562 ss.setAnnotationId(annotationId);
1563 ss.setViewerState(jarEntryName);
1564 ss.setGapped(model.gapped);
1565 ss.setTitle(model.title);
1566 rna.addSecondaryStructure(ss);
1575 * Copy the contents of a file to a new entry added to the output jar
1579 * @param jarEntryName
1581 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1582 String jarEntryName)
1584 DataInputStream dis = null;
1587 File file = new File(infilePath);
1588 if (file.exists() && jout != null)
1590 dis = new DataInputStream(new FileInputStream(file));
1591 byte[] data = new byte[(int) file.length()];
1592 dis.readFully(data);
1593 writeJarEntry(jout, jarEntryName, data);
1595 } catch (Exception ex)
1597 ex.printStackTrace();
1605 } catch (IOException e)
1614 * Write the data to a new entry of given name in the output jar file
1617 * @param jarEntryName
1619 * @throws IOException
1621 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1622 byte[] data) throws IOException
1626 System.out.println("Writing jar entry " + jarEntryName);
1627 jout.putNextEntry(new JarEntry(jarEntryName));
1628 DataOutputStream dout = new DataOutputStream(jout);
1629 dout.write(data, 0, data.length);
1636 * Save the state of a structure viewer
1641 * the archive XML element under which to save the state
1644 * @param matchedFile
1648 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1649 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1650 String matchedFile, StructureViewerBase viewFrame)
1652 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1655 * Look for any bindings for this viewer to the PDB file of interest
1656 * (including part matches excluding chain id)
1658 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1660 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1661 final String pdbId = pdbentry.getId();
1662 if (!pdbId.equals(entry.getId())
1663 && !(entry.getId().length() > 4 && entry.getId()
1664 .toLowerCase().startsWith(pdbId.toLowerCase())))
1667 * not interested in a binding to a different PDB entry here
1671 if (matchedFile == null)
1673 matchedFile = pdbentry.getFile();
1675 else if (!matchedFile.equals(pdbentry.getFile()))
1678 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1679 + pdbentry.getFile());
1683 // can get at it if the ID
1684 // match is ambiguous (e.g.
1687 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1689 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1690 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1692 StructureState state = new StructureState();
1693 state.setVisible(true);
1694 state.setXpos(viewFrame.getX());
1695 state.setYpos(viewFrame.getY());
1696 state.setWidth(viewFrame.getWidth());
1697 state.setHeight(viewFrame.getHeight());
1698 final String viewId = viewFrame.getViewId();
1699 state.setViewId(viewId);
1700 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1701 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1702 state.setColourByJmol(viewFrame.isColouredByViewer());
1703 state.setType(viewFrame.getViewerType().toString());
1704 pdb.addStructureState(state);
1711 private AnnotationColours constructAnnotationColours(
1712 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1713 JalviewModelSequence jms)
1715 AnnotationColours ac = new AnnotationColours();
1716 ac.setAboveThreshold(acg.getAboveThreshold());
1717 ac.setThreshold(acg.getAnnotationThreshold());
1718 ac.setAnnotation(acg.getAnnotation());
1719 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1721 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1726 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1730 ac.setMaxColour(acg.getMaxColour().getRGB());
1731 ac.setMinColour(acg.getMinColour().getRGB());
1732 ac.setPerSequence(acg.isSeqAssociated());
1733 ac.setPredefinedColours(acg.isPredefinedColours());
1737 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1738 IdentityHashMap<SequenceGroup, String> groupRefs,
1739 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1740 SequenceSet vamsasSet)
1743 for (int i = 0; i < aa.length; i++)
1745 Annotation an = new Annotation();
1747 AlignmentAnnotation annotation = aa[i];
1748 if (annotation.annotationId != null)
1750 annotationIds.put(annotation.annotationId, annotation);
1753 an.setId(annotation.annotationId);
1755 an.setVisible(annotation.visible);
1757 an.setDescription(annotation.description);
1759 if (annotation.sequenceRef != null)
1761 // 2.9 JAL-1781 xref on sequence id rather than name
1762 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1764 if (annotation.groupRef != null)
1766 String groupIdr = groupRefs.get(annotation.groupRef);
1767 if (groupIdr == null)
1769 // make a locally unique String
1771 annotation.groupRef,
1772 groupIdr = ("" + System.currentTimeMillis()
1773 + annotation.groupRef.getName() + groupRefs
1776 an.setGroupRef(groupIdr.toString());
1779 // store all visualization attributes for annotation
1780 an.setGraphHeight(annotation.graphHeight);
1781 an.setCentreColLabels(annotation.centreColLabels);
1782 an.setScaleColLabels(annotation.scaleColLabel);
1783 an.setShowAllColLabels(annotation.showAllColLabels);
1784 an.setBelowAlignment(annotation.belowAlignment);
1786 if (annotation.graph > 0)
1789 an.setGraphType(annotation.graph);
1790 an.setGraphGroup(annotation.graphGroup);
1791 if (annotation.getThreshold() != null)
1793 ThresholdLine line = new ThresholdLine();
1794 line.setLabel(annotation.getThreshold().label);
1795 line.setValue(annotation.getThreshold().value);
1796 line.setColour(annotation.getThreshold().colour.getRGB());
1797 an.setThresholdLine(line);
1805 an.setLabel(annotation.label);
1807 if (annotation == av.getAlignmentQualityAnnot()
1808 || annotation == av.getAlignmentConservationAnnotation()
1809 || annotation == av.getAlignmentConsensusAnnotation()
1810 || annotation.autoCalculated)
1812 // new way of indicating autocalculated annotation -
1813 an.setAutoCalculated(annotation.autoCalculated);
1815 if (annotation.hasScore())
1817 an.setScore(annotation.getScore());
1820 if (annotation.getCalcId() != null)
1822 calcIdSet.add(annotation.getCalcId());
1823 an.setCalcId(annotation.getCalcId());
1825 if (annotation.hasProperties())
1827 for (String pr : annotation.getProperties())
1829 Property prop = new Property();
1831 prop.setValue(annotation.getProperty(pr));
1832 an.addProperty(prop);
1836 AnnotationElement ae;
1837 if (annotation.annotations != null)
1839 an.setScoreOnly(false);
1840 for (int a = 0; a < annotation.annotations.length; a++)
1842 if ((annotation == null) || (annotation.annotations[a] == null))
1847 ae = new AnnotationElement();
1848 if (annotation.annotations[a].description != null)
1850 ae.setDescription(annotation.annotations[a].description);
1852 if (annotation.annotations[a].displayCharacter != null)
1854 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1857 if (!Float.isNaN(annotation.annotations[a].value))
1859 ae.setValue(annotation.annotations[a].value);
1863 if (annotation.annotations[a].secondaryStructure > ' ')
1865 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1869 if (annotation.annotations[a].colour != null
1870 && annotation.annotations[a].colour != java.awt.Color.black)
1872 ae.setColour(annotation.annotations[a].colour.getRGB());
1875 an.addAnnotationElement(ae);
1876 if (annotation.autoCalculated)
1878 // only write one non-null entry into the annotation row -
1879 // sufficient to get the visualization attributes necessary to
1887 an.setScoreOnly(true);
1889 if (!storeDS || (storeDS && !annotation.autoCalculated))
1891 // skip autocalculated annotation - these are only provided for
1893 vamsasSet.addAnnotation(an);
1899 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1901 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1902 if (settings != null)
1904 CalcIdParam vCalcIdParam = new CalcIdParam();
1905 vCalcIdParam.setCalcId(calcId);
1906 vCalcIdParam.addServiceURL(settings.getServiceURI());
1907 // generic URI allowing a third party to resolve another instance of the
1908 // service used for this calculation
1909 for (String urls : settings.getServiceURLs())
1911 vCalcIdParam.addServiceURL(urls);
1913 vCalcIdParam.setVersion("1.0");
1914 if (settings.getPreset() != null)
1916 WsParamSetI setting = settings.getPreset();
1917 vCalcIdParam.setName(setting.getName());
1918 vCalcIdParam.setDescription(setting.getDescription());
1922 vCalcIdParam.setName("");
1923 vCalcIdParam.setDescription("Last used parameters");
1925 // need to be able to recover 1) settings 2) user-defined presets or
1926 // recreate settings from preset 3) predefined settings provided by
1927 // service - or settings that can be transferred (or discarded)
1928 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1930 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1931 // todo - decide if updateImmediately is needed for any projects.
1933 return vCalcIdParam;
1938 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1941 if (calcIdParam.getVersion().equals("1.0"))
1943 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1944 .getPreferredServiceFor(calcIdParam.getServiceURL());
1945 if (service != null)
1947 WsParamSetI parmSet = null;
1950 parmSet = service.getParamStore().parseServiceParameterFile(
1951 calcIdParam.getName(), calcIdParam.getDescription(),
1952 calcIdParam.getServiceURL(),
1953 calcIdParam.getParameters().replace("|\\n|", "\n"));
1954 } catch (IOException x)
1956 warn("Couldn't parse parameter data for "
1957 + calcIdParam.getCalcId(), x);
1960 List<ArgumentI> argList = null;
1961 if (calcIdParam.getName().length() > 0)
1963 parmSet = service.getParamStore()
1964 .getPreset(calcIdParam.getName());
1965 if (parmSet != null)
1967 // TODO : check we have a good match with settings in AACon -
1968 // otherwise we'll need to create a new preset
1973 argList = parmSet.getArguments();
1976 AAConSettings settings = new AAConSettings(
1977 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1978 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1979 calcIdParam.isNeedsUpdate());
1984 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1988 throw new Error(MessageManager.formatMessage(
1989 "error.unsupported_version_calcIdparam",
1990 new Object[] { calcIdParam.toString() }));
1994 * External mapping between jalview objects and objects yielding a valid and
1995 * unique object ID string. This is null for normal Jalview project IO, but
1996 * non-null when a jalview project is being read or written as part of a
1999 IdentityHashMap jv2vobj = null;
2002 * Construct a unique ID for jvobj using either existing bindings or if none
2003 * exist, the result of the hashcode call for the object.
2006 * jalview data object
2007 * @return unique ID for referring to jvobj
2009 private String makeHashCode(Object jvobj, String altCode)
2011 if (jv2vobj != null)
2013 Object id = jv2vobj.get(jvobj);
2016 return id.toString();
2018 // check string ID mappings
2019 if (jvids2vobj != null && jvobj instanceof String)
2021 id = jvids2vobj.get(jvobj);
2025 return id.toString();
2027 // give up and warn that something has gone wrong
2028 warn("Cannot find ID for object in external mapping : " + jvobj);
2034 * return local jalview object mapped to ID, if it exists
2038 * @return null or object bound to idcode
2040 private Object retrieveExistingObj(String idcode)
2042 if (idcode != null && vobj2jv != null)
2044 return vobj2jv.get(idcode);
2050 * binding from ID strings from external mapping table to jalview data model
2053 private Hashtable vobj2jv;
2055 private Sequence createVamsasSequence(String id, SequenceI jds)
2057 return createVamsasSequence(true, id, jds, null);
2060 private Sequence createVamsasSequence(boolean recurse, String id,
2061 SequenceI jds, SequenceI parentseq)
2063 Sequence vamsasSeq = new Sequence();
2064 vamsasSeq.setId(id);
2065 vamsasSeq.setName(jds.getName());
2066 vamsasSeq.setSequence(jds.getSequenceAsString());
2067 vamsasSeq.setDescription(jds.getDescription());
2068 jalview.datamodel.DBRefEntry[] dbrefs = null;
2069 if (jds.getDatasetSequence() != null)
2071 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2075 // seqId==dsseqid so we can tell which sequences really are
2076 // dataset sequences only
2077 vamsasSeq.setDsseqid(id);
2078 dbrefs = jds.getDBRefs();
2079 if (parentseq == null)
2086 for (int d = 0; d < dbrefs.length; d++)
2088 DBRef dbref = new DBRef();
2089 dbref.setSource(dbrefs[d].getSource());
2090 dbref.setVersion(dbrefs[d].getVersion());
2091 dbref.setAccessionId(dbrefs[d].getAccessionId());
2092 if (dbrefs[d].hasMap())
2094 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2096 dbref.setMapping(mp);
2098 vamsasSeq.addDBRef(dbref);
2104 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2105 SequenceI parentseq, SequenceI jds, boolean recurse)
2108 if (jmp.getMap() != null)
2112 jalview.util.MapList mlst = jmp.getMap();
2113 List<int[]> r = mlst.getFromRanges();
2114 for (int[] range : r)
2116 MapListFrom mfrom = new MapListFrom();
2117 mfrom.setStart(range[0]);
2118 mfrom.setEnd(range[1]);
2119 mp.addMapListFrom(mfrom);
2121 r = mlst.getToRanges();
2122 for (int[] range : r)
2124 MapListTo mto = new MapListTo();
2125 mto.setStart(range[0]);
2126 mto.setEnd(range[1]);
2127 mp.addMapListTo(mto);
2129 mp.setMapFromUnit(mlst.getFromRatio());
2130 mp.setMapToUnit(mlst.getToRatio());
2131 if (jmp.getTo() != null)
2133 MappingChoice mpc = new MappingChoice();
2135 // check/create ID for the sequence referenced by getTo()
2138 SequenceI ps = null;
2139 if (parentseq != jmp.getTo()
2140 && parentseq.getDatasetSequence() != jmp.getTo())
2142 // chaining dbref rather than a handshaking one
2143 jmpid = seqHash(ps = jmp.getTo());
2147 jmpid = seqHash(ps = parentseq);
2149 mpc.setDseqFor(jmpid);
2150 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2152 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2153 seqRefIds.put(mpc.getDseqFor(), ps);
2157 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2160 mp.setMappingChoice(mpc);
2166 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2167 List<UserColourScheme> userColours, JalviewModelSequence jms)
2170 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2171 boolean newucs = false;
2172 if (!userColours.contains(ucs))
2174 userColours.add(ucs);
2177 id = "ucs" + userColours.indexOf(ucs);
2180 // actually create the scheme's entry in the XML model
2181 java.awt.Color[] colours = ucs.getColours();
2182 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2183 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2185 for (int i = 0; i < colours.length; i++)
2187 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2188 col.setName(ResidueProperties.aa[i]);
2189 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2190 jbucs.addColour(col);
2192 if (ucs.getLowerCaseColours() != null)
2194 colours = ucs.getLowerCaseColours();
2195 for (int i = 0; i < colours.length; i++)
2197 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2198 col.setName(ResidueProperties.aa[i].toLowerCase());
2199 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2200 jbucs.addColour(col);
2205 uc.setUserColourScheme(jbucs);
2206 jms.addUserColours(uc);
2212 jalview.schemes.UserColourScheme getUserColourScheme(
2213 JalviewModelSequence jms, String id)
2215 UserColours[] uc = jms.getUserColours();
2216 UserColours colours = null;
2218 for (int i = 0; i < uc.length; i++)
2220 if (uc[i].getId().equals(id))
2228 java.awt.Color[] newColours = new java.awt.Color[24];
2230 for (int i = 0; i < 24; i++)
2232 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2233 .getUserColourScheme().getColour(i).getRGB(), 16));
2236 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2239 if (colours.getUserColourScheme().getColourCount() > 24)
2241 newColours = new java.awt.Color[23];
2242 for (int i = 0; i < 23; i++)
2244 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2245 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2247 ucs.setLowerCaseColours(newColours);
2254 * contains last error message (if any) encountered by XML loader.
2256 String errorMessage = null;
2259 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2260 * exceptions are raised during project XML parsing
2262 public boolean attemptversion1parse = true;
2265 * Load a jalview project archive from a jar file
2268 * - HTTP URL or filename
2270 public AlignFrame loadJalviewAlign(final String file)
2273 jalview.gui.AlignFrame af = null;
2277 // create list to store references for any new Jmol viewers created
2278 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2279 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2280 // Workaround is to make sure caller implements the JarInputStreamProvider
2282 // so we can re-open the jar input stream for each entry.
2284 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2285 af = loadJalviewAlign(jprovider);
2287 } catch (MalformedURLException e)
2289 errorMessage = "Invalid URL format for '" + file + "'";
2295 SwingUtilities.invokeAndWait(new Runnable()
2300 setLoadingFinishedForNewStructureViewers();
2303 } catch (Exception x)
2305 System.err.println("Error loading alignment: " + x.getMessage());
2311 private jarInputStreamProvider createjarInputStreamProvider(
2312 final String file) throws MalformedURLException
2315 errorMessage = null;
2316 uniqueSetSuffix = null;
2318 viewportsAdded.clear();
2319 frefedSequence = null;
2321 if (file.startsWith("http://"))
2323 url = new URL(file);
2325 final URL _url = url;
2326 return new jarInputStreamProvider()
2330 public JarInputStream getJarInputStream() throws IOException
2334 return new JarInputStream(_url.openStream());
2338 return new JarInputStream(new FileInputStream(file));
2343 public String getFilename()
2351 * Recover jalview session from a jalview project archive. Caller may
2352 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2353 * themselves. Any null fields will be initialised with default values,
2354 * non-null fields are left alone.
2359 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2361 errorMessage = null;
2362 if (uniqueSetSuffix == null)
2364 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2366 if (seqRefIds == null)
2370 AlignFrame af = null, _af = null;
2371 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2372 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2373 final String file = jprovider.getFilename();
2376 JarInputStream jin = null;
2377 JarEntry jarentry = null;
2382 jin = jprovider.getJarInputStream();
2383 for (int i = 0; i < entryCount; i++)
2385 jarentry = jin.getNextJarEntry();
2388 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2390 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2391 JalviewModel object = new JalviewModel();
2393 Unmarshaller unmar = new Unmarshaller(object);
2394 unmar.setValidation(false);
2395 object = (JalviewModel) unmar.unmarshal(in);
2396 if (true) // !skipViewport(object))
2398 _af = loadFromObject(object, file, true, jprovider);
2400 && object.getJalviewModelSequence().getViewportCount() > 0)
2404 // store a reference to the first view
2407 if (_af.viewport.isGatherViewsHere())
2409 // if this is a gathered view, keep its reference since
2410 // after gathering views, only this frame will remain
2412 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2414 // Save dataset to register mappings once all resolved
2415 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2416 af.viewport.getAlignment().getDataset());
2421 else if (jarentry != null)
2423 // Some other file here.
2426 } while (jarentry != null);
2427 resolveFrefedSequences();
2428 } catch (IOException ex)
2430 ex.printStackTrace();
2431 errorMessage = "Couldn't locate Jalview XML file : " + file;
2432 System.err.println("Exception whilst loading jalview XML file : "
2434 } catch (Exception ex)
2436 System.err.println("Parsing as Jalview Version 2 file failed.");
2437 ex.printStackTrace(System.err);
2438 if (attemptversion1parse)
2440 // Is Version 1 Jar file?
2443 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2444 } catch (Exception ex2)
2446 System.err.println("Exception whilst loading as jalviewXMLV1:");
2447 ex2.printStackTrace();
2451 if (Desktop.instance != null)
2453 Desktop.instance.stopLoading();
2457 System.out.println("Successfully loaded archive file");
2460 ex.printStackTrace();
2462 System.err.println("Exception whilst loading jalview XML file : "
2464 } catch (OutOfMemoryError e)
2466 // Don't use the OOM Window here
2467 errorMessage = "Out of memory loading jalview XML file";
2468 System.err.println("Out of memory whilst loading jalview XML file");
2469 e.printStackTrace();
2473 * Regather multiple views (with the same sequence set id) to the frame (if
2474 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2475 * views instead of separate frames. Note this doesn't restore a state where
2476 * some expanded views in turn have tabbed views - the last "first tab" read
2477 * in will play the role of gatherer for all.
2479 for (AlignFrame fr : gatherToThisFrame.values())
2481 Desktop.instance.gatherViews(fr);
2484 restoreSplitFrames();
2485 for (AlignmentI ds : importedDatasets.keySet())
2487 if (ds.getCodonFrames() != null)
2489 StructureSelectionManager.getStructureSelectionManager(
2490 Desktop.instance).registerMappings(ds.getCodonFrames());
2493 if (errorMessage != null)
2498 if (Desktop.instance != null)
2500 Desktop.instance.stopLoading();
2507 * Try to reconstruct and display SplitFrame windows, where each contains
2508 * complementary dna and protein alignments. Done by pairing up AlignFrame
2509 * objects (created earlier) which have complementary viewport ids associated.
2511 protected void restoreSplitFrames()
2513 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2514 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2515 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2518 * Identify the DNA alignments
2520 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2523 AlignFrame af = candidate.getValue();
2524 if (af.getViewport().getAlignment().isNucleotide())
2526 dna.put(candidate.getKey().getId(), af);
2531 * Try to match up the protein complements
2533 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2536 AlignFrame af = candidate.getValue();
2537 if (!af.getViewport().getAlignment().isNucleotide())
2539 String complementId = candidate.getKey().getComplementId();
2540 // only non-null complements should be in the Map
2541 if (complementId != null && dna.containsKey(complementId))
2543 final AlignFrame dnaFrame = dna.get(complementId);
2544 SplitFrame sf = createSplitFrame(dnaFrame, af);
2545 addedToSplitFrames.add(dnaFrame);
2546 addedToSplitFrames.add(af);
2547 dnaFrame.setMenusForViewport();
2548 af.setMenusForViewport();
2549 if (af.viewport.isGatherViewsHere())
2558 * Open any that we failed to pair up (which shouldn't happen!) as
2559 * standalone AlignFrame's.
2561 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2564 AlignFrame af = candidate.getValue();
2565 if (!addedToSplitFrames.contains(af))
2567 Viewport view = candidate.getKey();
2568 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2570 af.setMenusForViewport();
2571 System.err.println("Failed to restore view " + view.getTitle()
2572 + " to split frame");
2577 * Gather back into tabbed views as flagged.
2579 for (SplitFrame sf : gatherTo)
2581 Desktop.instance.gatherViews(sf);
2584 splitFrameCandidates.clear();
2588 * Construct and display one SplitFrame holding DNA and protein alignments.
2591 * @param proteinFrame
2594 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2595 AlignFrame proteinFrame)
2597 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2598 String title = MessageManager.getString("label.linked_view_title");
2599 int width = (int) dnaFrame.getBounds().getWidth();
2600 int height = (int) (dnaFrame.getBounds().getHeight()
2601 + proteinFrame.getBounds().getHeight() + 50);
2604 * SplitFrame location is saved to both enclosed frames
2606 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2607 Desktop.addInternalFrame(splitFrame, title, width, height);
2610 * And compute cDNA consensus (couldn't do earlier with consensus as
2611 * mappings were not yet present)
2613 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2619 * check errorMessage for a valid error message and raise an error box in the
2620 * GUI or write the current errorMessage to stderr and then clear the error
2623 protected void reportErrors()
2625 reportErrors(false);
2628 protected void reportErrors(final boolean saving)
2630 if (errorMessage != null)
2632 final String finalErrorMessage = errorMessage;
2635 javax.swing.SwingUtilities.invokeLater(new Runnable()
2640 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2641 finalErrorMessage, "Error "
2642 + (saving ? "saving" : "loading")
2643 + " Jalview file", JvOptionPane.WARNING_MESSAGE);
2649 System.err.println("Problem loading Jalview file: " + errorMessage);
2652 errorMessage = null;
2655 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2658 * when set, local views will be updated from view stored in JalviewXML
2659 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2660 * sync if this is set to true.
2662 private final boolean updateLocalViews = false;
2665 * Returns the path to a temporary file holding the PDB file for the given PDB
2666 * id. The first time of asking, searches for a file of that name in the
2667 * Jalview project jar, and copies it to a new temporary file. Any repeat
2668 * requests just return the path to the file previously created.
2674 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2677 if (alreadyLoadedPDB.containsKey(pdbId))
2679 return alreadyLoadedPDB.get(pdbId).toString();
2682 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2684 if (tempFile != null)
2686 alreadyLoadedPDB.put(pdbId, tempFile);
2692 * Copies the jar entry of given name to a new temporary file and returns the
2693 * path to the file, or null if the entry is not found.
2696 * @param jarEntryName
2698 * a prefix for the temporary file name, must be at least three
2701 * null or original file - so new file can be given the same suffix
2705 protected String copyJarEntry(jarInputStreamProvider jprovider,
2706 String jarEntryName, String prefix, String origFile)
2708 BufferedReader in = null;
2709 PrintWriter out = null;
2710 String suffix = ".tmp";
2711 if (origFile == null)
2713 origFile = jarEntryName;
2715 int sfpos = origFile.lastIndexOf(".");
2716 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2718 suffix = "." + origFile.substring(sfpos + 1);
2722 JarInputStream jin = jprovider.getJarInputStream();
2724 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2725 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2726 * FileInputStream(jprovider)); }
2729 JarEntry entry = null;
2732 entry = jin.getNextJarEntry();
2733 } while (entry != null && !entry.getName().equals(jarEntryName));
2736 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2737 File outFile = File.createTempFile(prefix, suffix);
2738 outFile.deleteOnExit();
2739 out = new PrintWriter(new FileOutputStream(outFile));
2742 while ((data = in.readLine()) != null)
2747 String t = outFile.getAbsolutePath();
2752 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2754 } catch (Exception ex)
2756 ex.printStackTrace();
2764 } catch (IOException e)
2778 private class JvAnnotRow
2780 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2787 * persisted version of annotation row from which to take vis properties
2789 public jalview.datamodel.AlignmentAnnotation template;
2792 * original position of the annotation row in the alignment
2798 * Load alignment frame from jalview XML DOM object
2803 * filename source string
2804 * @param loadTreesAndStructures
2805 * when false only create Viewport
2807 * data source provider
2808 * @return alignment frame created from view stored in DOM
2810 AlignFrame loadFromObject(JalviewModel object, String file,
2811 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2813 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2814 Sequence[] vamsasSeq = vamsasSet.getSequence();
2816 JalviewModelSequence jms = object.getJalviewModelSequence();
2818 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2821 // ////////////////////////////////
2824 List<SequenceI> hiddenSeqs = null;
2826 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2828 boolean multipleView = false;
2829 SequenceI referenceseqForView = null;
2830 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2831 int vi = 0; // counter in vamsasSeq array
2832 for (int i = 0; i < jseqs.length; i++)
2834 String seqId = jseqs[i].getId();
2836 SequenceI tmpSeq = seqRefIds.get(seqId);
2839 if (!incompleteSeqs.containsKey(seqId))
2841 // may not need this check, but keep it for at least 2.9,1 release
2842 if (tmpSeq.getStart() != jseqs[i].getStart()
2843 || tmpSeq.getEnd() != jseqs[i].getEnd())
2846 .println("Warning JAL-2154 regression: updating start/end for sequence "
2847 + tmpSeq.toString() + " to " + jseqs[i]);
2852 incompleteSeqs.remove(seqId);
2854 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2856 // most likely we are reading a dataset XML document so
2857 // update from vamsasSeq section of XML for this sequence
2858 tmpSeq.setName(vamsasSeq[vi].getName());
2859 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2860 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2865 // reading multiple views, so vamsasSeq set is a subset of JSeq
2866 multipleView = true;
2868 tmpSeq.setStart(jseqs[i].getStart());
2869 tmpSeq.setEnd(jseqs[i].getEnd());
2870 tmpseqs.add(tmpSeq);
2874 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2875 vamsasSeq[vi].getSequence());
2876 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2877 tmpSeq.setStart(jseqs[i].getStart());
2878 tmpSeq.setEnd(jseqs[i].getEnd());
2879 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2880 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2881 tmpseqs.add(tmpSeq);
2885 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2887 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2890 if (jseqs[i].getHidden())
2892 if (hiddenSeqs == null)
2894 hiddenSeqs = new ArrayList<SequenceI>();
2897 hiddenSeqs.add(tmpSeq);
2902 // Create the alignment object from the sequence set
2903 // ///////////////////////////////
2904 SequenceI[] orderedSeqs = tmpseqs
2905 .toArray(new SequenceI[tmpseqs.size()]);
2907 AlignmentI al = null;
2908 // so we must create or recover the dataset alignment before going further
2909 // ///////////////////////////////
2910 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2912 // older jalview projects do not have a dataset - so creat alignment and
2914 al = new Alignment(orderedSeqs);
2915 al.setDataset(null);
2919 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2922 // we are importing a dataset record, so
2923 // recover reference to an alignment already materialsed as dataset
2924 al = getDatasetFor(vamsasSet.getDatasetId());
2928 // materialse the alignment
2929 al = new Alignment(orderedSeqs);
2933 addDatasetRef(vamsasSet.getDatasetId(), al);
2936 // finally, verify all data in vamsasSet is actually present in al
2937 // passing on flag indicating if it is actually a stored dataset
2938 recoverDatasetFor(vamsasSet, al, isdsal);
2941 if (referenceseqForView != null)
2943 al.setSeqrep(referenceseqForView);
2945 // / Add the alignment properties
2946 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2948 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2949 al.setProperty(ssp.getKey(), ssp.getValue());
2952 // ///////////////////////////////
2954 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2957 // load sequence features, database references and any associated PDB
2958 // structures for the alignment
2960 // prior to 2.10, this part would only be executed the first time a
2961 // sequence was encountered, but not afterwards.
2962 // now, for 2.10 projects, this is also done if the xml doc includes
2963 // dataset sequences not actually present in any particular view.
2965 for (int i = 0; i < vamsasSeq.length; i++)
2967 if (jseqs[i].getFeaturesCount() > 0)
2969 Features[] features = jseqs[i].getFeatures();
2970 for (int f = 0; f < features.length; f++)
2972 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2973 features[f].getType(), features[f].getDescription(),
2974 features[f].getStatus(), features[f].getBegin(),
2975 features[f].getEnd(), features[f].getFeatureGroup());
2977 sf.setScore(features[f].getScore());
2978 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2980 OtherData keyValue = features[f].getOtherData(od);
2981 if (keyValue.getKey().startsWith("LINK"))
2983 sf.addLink(keyValue.getValue());
2987 sf.setValue(keyValue.getKey(), keyValue.getValue());
2991 // adds feature to datasequence's feature set (since Jalview 2.10)
2992 al.getSequenceAt(i).addSequenceFeature(sf);
2995 if (vamsasSeq[i].getDBRefCount() > 0)
2997 // adds dbrefs to datasequence's set (since Jalview 2.10)
2999 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
3000 : al.getSequenceAt(i).getDatasetSequence(),
3003 if (jseqs[i].getPdbidsCount() > 0)
3005 Pdbids[] ids = jseqs[i].getPdbids();
3006 for (int p = 0; p < ids.length; p++)
3008 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
3009 entry.setId(ids[p].getId());
3010 if (ids[p].getType() != null)
3012 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3014 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3018 entry.setType(PDBEntry.Type.FILE);
3021 // jprovider is null when executing 'New View'
3022 if (ids[p].getFile() != null && jprovider != null)
3024 if (!pdbloaded.containsKey(ids[p].getFile()))
3026 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3031 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3034 if (ids[p].getPdbentryItem() != null)
3036 for (PdbentryItem item : ids[p].getPdbentryItem())
3038 for (Property pr : item.getProperty())
3040 entry.setProperty(pr.getName(), pr.getValue());
3044 StructureSelectionManager.getStructureSelectionManager(
3045 Desktop.instance).registerPDBEntry(entry);
3046 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3047 if (al.getSequenceAt(i).getDatasetSequence() != null)
3049 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3053 al.getSequenceAt(i).addPDBId(entry);
3058 } // end !multipleview
3060 // ///////////////////////////////
3061 // LOAD SEQUENCE MAPPINGS
3063 if (vamsasSet.getAlcodonFrameCount() > 0)
3065 // TODO Potentially this should only be done once for all views of an
3067 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3068 for (int i = 0; i < alc.length; i++)
3070 AlignedCodonFrame cf = new AlignedCodonFrame();
3071 if (alc[i].getAlcodMapCount() > 0)
3073 AlcodMap[] maps = alc[i].getAlcodMap();
3074 for (int m = 0; m < maps.length; m++)
3076 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3078 jalview.datamodel.Mapping mapping = null;
3079 // attach to dna sequence reference.
3080 if (maps[m].getMapping() != null)
3082 mapping = addMapping(maps[m].getMapping());
3083 if (dnaseq != null && mapping.getTo() != null)
3085 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3090 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3095 al.addCodonFrame(cf);
3100 // ////////////////////////////////
3102 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3105 * store any annotations which forward reference a group's ID
3107 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3109 if (vamsasSet.getAnnotationCount() > 0)
3111 Annotation[] an = vamsasSet.getAnnotation();
3113 for (int i = 0; i < an.length; i++)
3115 Annotation annotation = an[i];
3118 * test if annotation is automatically calculated for this view only
3120 boolean autoForView = false;
3121 if (annotation.getLabel().equals("Quality")
3122 || annotation.getLabel().equals("Conservation")
3123 || annotation.getLabel().equals("Consensus"))
3125 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3127 if (!annotation.hasAutoCalculated())
3129 annotation.setAutoCalculated(true);
3133 || (annotation.hasAutoCalculated() && annotation
3134 .isAutoCalculated()))
3136 // remove ID - we don't recover annotation from other views for
3137 // view-specific annotation
3138 annotation.setId(null);
3141 // set visiblity for other annotation in this view
3142 String annotationId = annotation.getId();
3143 if (annotationId != null && annotationIds.containsKey(annotationId))
3145 AlignmentAnnotation jda = annotationIds.get(annotationId);
3146 // in principle Visible should always be true for annotation displayed
3147 // in multiple views
3148 if (annotation.hasVisible())
3150 jda.visible = annotation.getVisible();
3153 al.addAnnotation(jda);
3157 // Construct new annotation from model.
3158 AnnotationElement[] ae = annotation.getAnnotationElement();
3159 jalview.datamodel.Annotation[] anot = null;
3160 java.awt.Color firstColour = null;
3162 if (!annotation.getScoreOnly())
3164 anot = new jalview.datamodel.Annotation[al.getWidth()];
3165 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3167 anpos = ae[aa].getPosition();
3169 if (anpos >= anot.length)
3174 anot[anpos] = new jalview.datamodel.Annotation(
3176 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3177 (ae[aa].getSecondaryStructure() == null || ae[aa]
3178 .getSecondaryStructure().length() == 0) ? ' '
3179 : ae[aa].getSecondaryStructure().charAt(0),
3183 // JBPNote: Consider verifying dataflow for IO of secondary
3184 // structure annotation read from Stockholm files
3185 // this was added to try to ensure that
3186 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3188 // anot[ae[aa].getPosition()].displayCharacter = "";
3190 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3191 if (firstColour == null)
3193 firstColour = anot[anpos].colour;
3197 jalview.datamodel.AlignmentAnnotation jaa = null;
3199 if (annotation.getGraph())
3201 float llim = 0, hlim = 0;
3202 // if (autoForView || an[i].isAutoCalculated()) {
3205 jaa = new jalview.datamodel.AlignmentAnnotation(
3206 annotation.getLabel(), annotation.getDescription(), anot,
3207 llim, hlim, annotation.getGraphType());
3209 jaa.graphGroup = annotation.getGraphGroup();
3210 jaa._linecolour = firstColour;
3211 if (annotation.getThresholdLine() != null)
3213 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3214 .getThresholdLine().getValue(), annotation
3215 .getThresholdLine().getLabel(), new java.awt.Color(
3216 annotation.getThresholdLine().getColour())));
3219 if (autoForView || annotation.isAutoCalculated())
3221 // Hardwire the symbol display line to ensure that labels for
3222 // histograms are displayed
3228 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3229 an[i].getDescription(), anot);
3230 jaa._linecolour = firstColour;
3232 // register new annotation
3233 if (an[i].getId() != null)
3235 annotationIds.put(an[i].getId(), jaa);
3236 jaa.annotationId = an[i].getId();
3238 // recover sequence association
3239 String sequenceRef = an[i].getSequenceRef();
3240 if (sequenceRef != null)
3242 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3243 SequenceI sequence = seqRefIds.get(sequenceRef);
3244 if (sequence == null)
3246 // in pre-2.9 projects sequence ref is to sequence name
3247 sequence = al.findName(sequenceRef);
3249 if (sequence != null)
3251 jaa.createSequenceMapping(sequence, 1, true);
3252 sequence.addAlignmentAnnotation(jaa);
3255 // and make a note of any group association
3256 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3258 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3259 .get(an[i].getGroupRef());
3262 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3263 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3268 if (an[i].hasScore())
3270 jaa.setScore(an[i].getScore());
3272 if (an[i].hasVisible())
3274 jaa.visible = an[i].getVisible();
3277 if (an[i].hasCentreColLabels())
3279 jaa.centreColLabels = an[i].getCentreColLabels();
3282 if (an[i].hasScaleColLabels())
3284 jaa.scaleColLabel = an[i].getScaleColLabels();
3286 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3288 // newer files have an 'autoCalculated' flag and store calculation
3289 // state in viewport properties
3290 jaa.autoCalculated = true; // means annotation will be marked for
3291 // update at end of load.
3293 if (an[i].hasGraphHeight())
3295 jaa.graphHeight = an[i].getGraphHeight();
3297 if (an[i].hasBelowAlignment())
3299 jaa.belowAlignment = an[i].isBelowAlignment();
3301 jaa.setCalcId(an[i].getCalcId());
3302 if (an[i].getPropertyCount() > 0)
3304 for (jalview.schemabinding.version2.Property prop : an[i]
3307 jaa.setProperty(prop.getName(), prop.getValue());
3310 if (jaa.autoCalculated)
3312 autoAlan.add(new JvAnnotRow(i, jaa));
3315 // if (!autoForView)
3317 // add autocalculated group annotation and any user created annotation
3319 al.addAnnotation(jaa);
3323 // ///////////////////////
3325 // Create alignment markup and styles for this view
3326 if (jms.getJGroupCount() > 0)
3328 JGroup[] groups = jms.getJGroup();
3329 boolean addAnnotSchemeGroup = false;
3330 for (int i = 0; i < groups.length; i++)
3332 JGroup jGroup = groups[i];
3333 ColourSchemeI cs = null;
3334 if (jGroup.getColour() != null)
3336 if (jGroup.getColour().startsWith("ucs"))
3338 cs = getUserColourScheme(jms, jGroup.getColour());
3340 else if (jGroup.getColour().equals("AnnotationColourGradient")
3341 && jGroup.getAnnotationColours() != null)
3343 addAnnotSchemeGroup = true;
3348 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3353 cs.setThreshold(jGroup.getPidThreshold(), true);
3354 cs.setConservationInc(jGroup.getConsThreshold());
3358 Vector<SequenceI> seqs = new Vector<SequenceI>();
3360 for (int s = 0; s < jGroup.getSeqCount(); s++)
3362 String seqId = jGroup.getSeq(s) + "";
3363 SequenceI ts = seqRefIds.get(seqId);
3367 seqs.addElement(ts);
3371 if (seqs.size() < 1)
3376 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3377 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3378 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3380 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3382 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3383 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3384 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3385 .isShowUnconserved() : false);
3386 sg.thresholdTextColour = jGroup.getTextColThreshold();
3387 if (jGroup.hasShowConsensusHistogram())
3389 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3392 if (jGroup.hasShowSequenceLogo())
3394 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3396 if (jGroup.hasNormaliseSequenceLogo())
3398 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3400 if (jGroup.hasIgnoreGapsinConsensus())
3402 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3404 if (jGroup.getConsThreshold() != 0)
3406 Conservation c = new Conservation("All", sg.getSequences(null),
3407 0, sg.getWidth() - 1);
3409 c.verdict(false, 25);
3410 sg.cs.setConservation(c);
3413 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3415 // re-instate unique group/annotation row reference
3416 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3420 for (AlignmentAnnotation jaa : jaal)
3423 if (jaa.autoCalculated)
3425 // match up and try to set group autocalc alignment row for this
3427 if (jaa.label.startsWith("Consensus for "))
3429 sg.setConsensus(jaa);
3431 // match up and try to set group autocalc alignment row for this
3433 if (jaa.label.startsWith("Conservation for "))
3435 sg.setConservationRow(jaa);
3442 if (addAnnotSchemeGroup)
3444 // reconstruct the annotation colourscheme
3445 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3446 null, al, jms, false);
3452 // only dataset in this model, so just return.
3455 // ///////////////////////////////
3458 // If we just load in the same jar file again, the sequenceSetId
3459 // will be the same, and we end up with multiple references
3460 // to the same sequenceSet. We must modify this id on load
3461 // so that each load of the file gives a unique id
3462 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3463 String viewId = (view.getId() == null ? null : view.getId()
3465 AlignFrame af = null;
3466 AlignViewport av = null;
3467 // now check to see if we really need to create a new viewport.
3468 if (multipleView && viewportsAdded.size() == 0)
3470 // We recovered an alignment for which a viewport already exists.
3471 // TODO: fix up any settings necessary for overlaying stored state onto
3472 // state recovered from another document. (may not be necessary).
3473 // we may need a binding from a viewport in memory to one recovered from
3475 // and then recover its containing af to allow the settings to be applied.
3476 // TODO: fix for vamsas demo
3478 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3480 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3481 if (seqsetobj != null)
3483 if (seqsetobj instanceof String)
3485 uniqueSeqSetId = (String) seqsetobj;
3487 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3493 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3499 * indicate that annotation colours are applied across all groups (pre
3500 * Jalview 2.8.1 behaviour)
3502 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3503 "2.8.1", object.getVersion());
3505 AlignmentPanel ap = null;
3506 boolean isnewview = true;
3509 // Check to see if this alignment already has a view id == viewId
3510 jalview.gui.AlignmentPanel views[] = Desktop
3511 .getAlignmentPanels(uniqueSeqSetId);
3512 if (views != null && views.length > 0)
3514 for (int v = 0; v < views.length; v++)
3516 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3518 // recover the existing alignpanel, alignframe, viewport
3519 af = views[v].alignFrame;
3522 // TODO: could even skip resetting view settings if we don't want to
3523 // change the local settings from other jalview processes
3532 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3533 uniqueSeqSetId, viewId, autoAlan);
3539 * Load any trees, PDB structures and viewers
3541 * Not done if flag is false (when this method is used for New View)
3543 if (loadTreesAndStructures)
3545 loadTrees(jms, view, af, av, ap);
3546 loadPDBStructures(jprovider, jseqs, af, ap);
3547 loadRnaViewers(jprovider, jseqs, ap);
3549 // and finally return.
3554 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3555 * panel is restored from separate jar entries, two (gapped and trimmed) per
3556 * sequence and secondary structure.
3558 * Currently each viewer shows just one sequence and structure (gapped and
3559 * trimmed), however this method is designed to support multiple sequences or
3560 * structures in viewers if wanted in future.
3566 private void loadRnaViewers(jarInputStreamProvider jprovider,
3567 JSeq[] jseqs, AlignmentPanel ap)
3570 * scan the sequences for references to viewers; create each one the first
3571 * time it is referenced, add Rna models to existing viewers
3573 for (JSeq jseq : jseqs)
3575 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3577 RnaViewer viewer = jseq.getRnaViewer(i);
3578 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3579 uniqueSetSuffix, ap);
3581 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3583 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3584 SequenceI seq = seqRefIds.get(jseq.getId());
3585 AlignmentAnnotation ann = this.annotationIds.get(ss
3586 .getAnnotationId());
3589 * add the structure to the Varna display (with session state copied
3590 * from the jar to a temporary file)
3592 boolean gapped = ss.isGapped();
3593 String rnaTitle = ss.getTitle();
3594 String sessionState = ss.getViewerState();
3595 String tempStateFile = copyJarEntry(jprovider, sessionState,
3597 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3598 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3600 appVarna.setInitialSelection(viewer.getSelectedRna());
3606 * Locate and return an already instantiated matching AppVarna, or create one
3610 * @param viewIdSuffix
3614 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3615 String viewIdSuffix, AlignmentPanel ap)
3618 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3619 * if load is repeated
3621 String postLoadId = viewer.getViewId() + viewIdSuffix;
3622 for (JInternalFrame frame : getAllFrames())
3624 if (frame instanceof AppVarna)
3626 AppVarna varna = (AppVarna) frame;
3627 if (postLoadId.equals(varna.getViewId()))
3629 // this viewer is already instantiated
3630 // could in future here add ap as another 'parent' of the
3631 // AppVarna window; currently just 1-to-many
3638 * viewer not found - make it
3640 RnaViewerModel model = new RnaViewerModel(postLoadId,
3641 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3642 viewer.getWidth(), viewer.getHeight(),
3643 viewer.getDividerLocation());
3644 AppVarna varna = new AppVarna(model, ap);
3650 * Load any saved trees
3658 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3659 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3661 // TODO result of automated refactoring - are all these parameters needed?
3664 for (int t = 0; t < jms.getTreeCount(); t++)
3667 Tree tree = jms.getTree(t);
3669 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3672 tp = af.ShowNewickTree(
3673 new jalview.io.NewickFile(tree.getNewick()),
3674 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3675 tree.getXpos(), tree.getYpos());
3676 if (tree.getId() != null)
3678 // perhaps bind the tree id to something ?
3683 // update local tree attributes ?
3684 // TODO: should check if tp has been manipulated by user - if so its
3685 // settings shouldn't be modified
3686 tp.setTitle(tree.getTitle());
3687 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3688 .getWidth(), tree.getHeight()));
3689 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3692 tp.treeCanvas.av = av; // af.viewport;
3693 tp.treeCanvas.ap = ap; // af.alignPanel;
3698 warn("There was a problem recovering stored Newick tree: \n"
3699 + tree.getNewick());
3703 tp.fitToWindow.setState(tree.getFitToWindow());
3704 tp.fitToWindow_actionPerformed(null);
3706 if (tree.getFontName() != null)
3708 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3709 .getFontStyle(), tree.getFontSize()));
3713 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3714 .getFontStyle(), tree.getFontSize()));
3717 tp.showPlaceholders(tree.getMarkUnlinked());
3718 tp.showBootstrap(tree.getShowBootstrap());
3719 tp.showDistances(tree.getShowDistances());
3721 tp.treeCanvas.threshold = tree.getThreshold();
3723 if (tree.getCurrentTree())
3725 af.viewport.setCurrentTree(tp.getTree());
3729 } catch (Exception ex)
3731 ex.printStackTrace();
3736 * Load and link any saved structure viewers.
3743 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3744 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3747 * Run through all PDB ids on the alignment, and collect mappings between
3748 * distinct view ids and all sequences referring to that view.
3750 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3752 for (int i = 0; i < jseqs.length; i++)
3754 if (jseqs[i].getPdbidsCount() > 0)
3756 Pdbids[] ids = jseqs[i].getPdbids();
3757 for (int p = 0; p < ids.length; p++)
3759 final int structureStateCount = ids[p].getStructureStateCount();
3760 for (int s = 0; s < structureStateCount; s++)
3762 // check to see if we haven't already created this structure view
3763 final StructureState structureState = ids[p]
3764 .getStructureState(s);
3765 String sviewid = (structureState.getViewId() == null) ? null
3766 : structureState.getViewId() + uniqueSetSuffix;
3767 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3768 // Originally : ids[p].getFile()
3769 // : TODO: verify external PDB file recovery still works in normal
3770 // jalview project load
3771 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3773 jpdb.setId(ids[p].getId());
3775 int x = structureState.getXpos();
3776 int y = structureState.getYpos();
3777 int width = structureState.getWidth();
3778 int height = structureState.getHeight();
3780 // Probably don't need to do this anymore...
3781 // Desktop.desktop.getComponentAt(x, y);
3782 // TODO: NOW: check that this recovers the PDB file correctly.
3783 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3785 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3787 if (sviewid == null)
3789 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3792 if (!structureViewers.containsKey(sviewid))
3794 structureViewers.put(sviewid,
3795 new StructureViewerModel(x, y, width, height, false,
3796 false, true, structureState.getViewId(),
3797 structureState.getType()));
3798 // Legacy pre-2.7 conversion JAL-823 :
3799 // do not assume any view has to be linked for colour by
3803 // assemble String[] { pdb files }, String[] { id for each
3804 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3805 // seqs_file 2}, boolean[] {
3806 // linkAlignPanel,superposeWithAlignpanel}} from hash
3807 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3808 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3809 | (structureState.hasAlignwithAlignPanel() ? structureState
3810 .getAlignwithAlignPanel() : false));
3813 * Default colour by linked panel to false if not specified (e.g.
3814 * for pre-2.7 projects)
3816 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3817 colourWithAlignPanel |= (structureState
3818 .hasColourwithAlignPanel() ? structureState
3819 .getColourwithAlignPanel() : false);
3820 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3823 * Default colour by viewer to true if not specified (e.g. for
3826 boolean colourByViewer = jmoldat.isColourByViewer();
3827 colourByViewer &= structureState.hasColourByJmol() ? structureState
3828 .getColourByJmol() : true;
3829 jmoldat.setColourByViewer(colourByViewer);
3831 if (jmoldat.getStateData().length() < structureState
3832 .getContent().length())
3835 jmoldat.setStateData(structureState.getContent());
3838 if (ids[p].getFile() != null)
3840 File mapkey = new File(ids[p].getFile());
3841 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3842 if (seqstrmaps == null)
3844 jmoldat.getFileData().put(
3846 seqstrmaps = jmoldat.new StructureData(pdbFile,
3849 if (!seqstrmaps.getSeqList().contains(seq))
3851 seqstrmaps.getSeqList().add(seq);
3857 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");
3864 // Instantiate the associated structure views
3865 for (Entry<String, StructureViewerModel> entry : structureViewers
3870 createOrLinkStructureViewer(entry, af, ap, jprovider);
3871 } catch (Exception e)
3873 System.err.println("Error loading structure viewer: "
3875 // failed - try the next one
3887 protected void createOrLinkStructureViewer(
3888 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3889 AlignmentPanel ap, jarInputStreamProvider jprovider)
3891 final StructureViewerModel stateData = viewerData.getValue();
3894 * Search for any viewer windows already open from other alignment views
3895 * that exactly match the stored structure state
3897 StructureViewerBase comp = findMatchingViewer(viewerData);
3901 linkStructureViewer(ap, comp, stateData);
3906 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3907 * "viewer_"+stateData.viewId
3909 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3911 createChimeraViewer(viewerData, af, jprovider);
3916 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3918 createJmolViewer(viewerData, af, jprovider);
3923 * Create a new Chimera viewer.
3929 protected void createChimeraViewer(
3930 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3931 jarInputStreamProvider jprovider)
3933 StructureViewerModel data = viewerData.getValue();
3934 String chimeraSessionFile = data.getStateData();
3937 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3939 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3940 * 'uniquified' sviewid used to reconstruct the viewer here
3942 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3943 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3946 Set<Entry<File, StructureData>> fileData = data.getFileData()
3948 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3949 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3950 for (Entry<File, StructureData> pdb : fileData)
3952 String filePath = pdb.getValue().getFilePath();
3953 String pdbId = pdb.getValue().getPdbId();
3954 // pdbs.add(new PDBEntry(filePath, pdbId));
3955 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3956 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3957 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3961 boolean colourByChimera = data.isColourByViewer();
3962 boolean colourBySequence = data.isColourWithAlignPanel();
3964 // TODO use StructureViewer as a factory here, see JAL-1761
3965 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3966 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3968 String newViewId = viewerData.getKey();
3970 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3971 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3972 colourBySequence, newViewId);
3973 cvf.setSize(data.getWidth(), data.getHeight());
3974 cvf.setLocation(data.getX(), data.getY());
3978 * Create a new Jmol window. First parse the Jmol state to translate filenames
3979 * loaded into the view, and record the order in which files are shown in the
3980 * Jmol view, so we can add the sequence mappings in same order.
3986 protected void createJmolViewer(
3987 final Entry<String, StructureViewerModel> viewerData,
3988 AlignFrame af, jarInputStreamProvider jprovider)
3990 final StructureViewerModel svattrib = viewerData.getValue();
3991 String state = svattrib.getStateData();
3994 * Pre-2.9: state element value is the Jmol state string
3996 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3999 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
4001 state = readJarEntry(jprovider,
4002 getViewerJarEntryName(svattrib.getViewId()));
4005 List<String> pdbfilenames = new ArrayList<String>();
4006 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
4007 List<String> pdbids = new ArrayList<String>();
4008 StringBuilder newFileLoc = new StringBuilder(64);
4009 int cp = 0, ncp, ecp;
4010 Map<File, StructureData> oldFiles = svattrib.getFileData();
4011 while ((ncp = state.indexOf("load ", cp)) > -1)
4015 // look for next filename in load statement
4016 newFileLoc.append(state.substring(cp,
4017 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4018 String oldfilenam = state.substring(ncp,
4019 ecp = state.indexOf("\"", ncp));
4020 // recover the new mapping data for this old filename
4021 // have to normalize filename - since Jmol and jalview do
4023 // translation differently.
4024 StructureData filedat = oldFiles.get(new File(oldfilenam));
4025 if (filedat == null)
4027 String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
4028 filedat = oldFiles.get(new File(reformatedOldFilename));
4030 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4031 pdbfilenames.add(filedat.getFilePath());
4032 pdbids.add(filedat.getPdbId());
4033 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4034 newFileLoc.append("\"");
4035 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4036 // look for next file statement.
4037 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4041 // just append rest of state
4042 newFileLoc.append(state.substring(cp));
4046 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4047 newFileLoc = new StringBuilder(state);
4048 newFileLoc.append("; load append ");
4049 for (File id : oldFiles.keySet())
4051 // add this and any other pdb files that should be present in
4053 StructureData filedat = oldFiles.get(id);
4054 newFileLoc.append(filedat.getFilePath());
4055 pdbfilenames.add(filedat.getFilePath());
4056 pdbids.add(filedat.getPdbId());
4057 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4058 newFileLoc.append(" \"");
4059 newFileLoc.append(filedat.getFilePath());
4060 newFileLoc.append("\"");
4063 newFileLoc.append(";");
4066 if (newFileLoc.length() == 0)
4070 int histbug = newFileLoc.indexOf("history = ");
4074 * change "history = [true|false];" to "history = [1|0];"
4077 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4078 String val = (diff == -1) ? null : newFileLoc
4079 .substring(histbug, diff);
4080 if (val != null && val.length() >= 4)
4082 if (val.contains("e")) // eh? what can it be?
4084 if (val.trim().equals("true"))
4092 newFileLoc.replace(histbug, diff, val);
4097 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4099 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4100 final SequenceI[][] sq = seqmaps
4101 .toArray(new SequenceI[seqmaps.size()][]);
4102 final String fileloc = newFileLoc.toString();
4103 final String sviewid = viewerData.getKey();
4104 final AlignFrame alf = af;
4105 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4106 svattrib.getWidth(), svattrib.getHeight());
4109 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4114 JalviewStructureDisplayI sview = null;
4117 sview = new StructureViewer(alf.alignPanel
4118 .getStructureSelectionManager()).createView(
4119 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4120 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4121 addNewStructureViewer(sview);
4122 } catch (OutOfMemoryError ex)
4124 new OOMWarning("restoring structure view for PDB id " + id,
4125 (OutOfMemoryError) ex.getCause());
4126 if (sview != null && sview.isVisible())
4128 sview.closeViewer(false);
4129 sview.setVisible(false);
4135 } catch (InvocationTargetException ex)
4137 warn("Unexpected error when opening Jmol view.", ex);
4139 } catch (InterruptedException e)
4141 // e.printStackTrace();
4147 * Generates a name for the entry in the project jar file to hold state
4148 * information for a structure viewer
4153 protected String getViewerJarEntryName(String viewId)
4155 return VIEWER_PREFIX + viewId;
4159 * Returns any open frame that matches given structure viewer data. The match
4160 * is based on the unique viewId, or (for older project versions) the frame's
4166 protected StructureViewerBase findMatchingViewer(
4167 Entry<String, StructureViewerModel> viewerData)
4169 final String sviewid = viewerData.getKey();
4170 final StructureViewerModel svattrib = viewerData.getValue();
4171 StructureViewerBase comp = null;
4172 JInternalFrame[] frames = getAllFrames();
4173 for (JInternalFrame frame : frames)
4175 if (frame instanceof StructureViewerBase)
4178 * Post jalview 2.4 schema includes structure view id
4181 && ((StructureViewerBase) frame).getViewId()
4184 comp = (StructureViewerBase) frame;
4185 break; // break added in 2.9
4188 * Otherwise test for matching position and size of viewer frame
4190 else if (frame.getX() == svattrib.getX()
4191 && frame.getY() == svattrib.getY()
4192 && frame.getHeight() == svattrib.getHeight()
4193 && frame.getWidth() == svattrib.getWidth())
4195 comp = (StructureViewerBase) frame;
4196 // no break in faint hope of an exact match on viewId
4204 * Link an AlignmentPanel to an existing structure viewer.
4209 * @param useinViewerSuperpos
4210 * @param usetoColourbyseq
4211 * @param viewerColouring
4213 protected void linkStructureViewer(AlignmentPanel ap,
4214 StructureViewerBase viewer, StructureViewerModel stateData)
4216 // NOTE: if the jalview project is part of a shared session then
4217 // view synchronization should/could be done here.
4219 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4220 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4221 final boolean viewerColouring = stateData.isColourByViewer();
4222 Map<File, StructureData> oldFiles = stateData.getFileData();
4225 * Add mapping for sequences in this view to an already open viewer
4227 final AAStructureBindingModel binding = viewer.getBinding();
4228 for (File id : oldFiles.keySet())
4230 // add this and any other pdb files that should be present in the
4232 StructureData filedat = oldFiles.get(id);
4233 String pdbFile = filedat.getFilePath();
4234 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4235 binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE);
4236 binding.addSequenceForStructFile(pdbFile, seq);
4238 // and add the AlignmentPanel's reference to the view panel
4239 viewer.addAlignmentPanel(ap);
4240 if (useinViewerSuperpos)
4242 viewer.useAlignmentPanelForSuperposition(ap);
4246 viewer.excludeAlignmentPanelForSuperposition(ap);
4248 if (usetoColourbyseq)
4250 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4254 viewer.excludeAlignmentPanelForColourbyseq(ap);
4259 * Get all frames within the Desktop.
4263 protected JInternalFrame[] getAllFrames()
4265 JInternalFrame[] frames = null;
4266 // TODO is this necessary - is it safe - risk of hanging?
4271 frames = Desktop.desktop.getAllFrames();
4272 } catch (ArrayIndexOutOfBoundsException e)
4274 // occasional No such child exceptions are thrown here...
4278 } catch (InterruptedException f)
4282 } while (frames == null);
4287 * Answers true if 'version' is equal to or later than 'supported', where each
4288 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4289 * changes. Development and test values for 'version' are leniently treated
4293 * - minimum version we are comparing against
4295 * - version of data being processsed
4298 public static boolean isVersionStringLaterThan(String supported,
4301 if (supported == null || version == null
4302 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4303 || version.equalsIgnoreCase("Test")
4304 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4306 System.err.println("Assuming project file with "
4307 + (version == null ? "null" : version)
4308 + " is compatible with Jalview version " + supported);
4313 return StringUtils.compareVersions(version, supported, "b") >= 0;
4317 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4319 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4321 if (newStructureViewers != null)
4323 sview.getBinding().setFinishedLoadingFromArchive(false);
4324 newStructureViewers.add(sview);
4328 protected void setLoadingFinishedForNewStructureViewers()
4330 if (newStructureViewers != null)
4332 for (JalviewStructureDisplayI sview : newStructureViewers)
4334 sview.getBinding().setFinishedLoadingFromArchive(true);
4336 newStructureViewers.clear();
4337 newStructureViewers = null;
4341 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4342 List<SequenceI> hiddenSeqs, AlignmentI al,
4343 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4344 String viewId, List<JvAnnotRow> autoAlan)
4346 AlignFrame af = null;
4347 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4348 uniqueSeqSetId, viewId);
4350 af.setFileName(file, FileFormat.Jalview);
4352 for (int i = 0; i < JSEQ.length; i++)
4354 af.viewport.setSequenceColour(af.viewport.getAlignment()
4355 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4360 af.getViewport().setColourByReferenceSeq(true);
4361 af.getViewport().setDisplayReferenceSeq(true);
4364 af.viewport.setGatherViewsHere(view.getGatheredViews());
4366 if (view.getSequenceSetId() != null)
4368 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4370 af.viewport.setSequenceSetId(uniqueSeqSetId);
4373 // propagate shared settings to this new view
4374 af.viewport.setHistoryList(av.getHistoryList());
4375 af.viewport.setRedoList(av.getRedoList());
4379 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4381 // TODO: check if this method can be called repeatedly without
4382 // side-effects if alignpanel already registered.
4383 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4385 // apply Hidden regions to view.
4386 if (hiddenSeqs != null)
4388 for (int s = 0; s < JSEQ.length; s++)
4390 SequenceGroup hidden = new SequenceGroup();
4391 boolean isRepresentative = false;
4392 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4394 isRepresentative = true;
4395 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4396 .getHiddenSequences(r));
4397 hidden.addSequence(sequenceToHide, false);
4398 // remove from hiddenSeqs list so we don't try to hide it twice
4399 hiddenSeqs.remove(sequenceToHide);
4401 if (isRepresentative)
4403 SequenceI representativeSequence = al.getSequenceAt(s);
4404 hidden.addSequence(representativeSequence, false);
4405 af.viewport.hideRepSequences(representativeSequence, hidden);
4409 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4411 af.viewport.hideSequence(hseqs);
4414 // recover view properties and display parameters
4415 if (view.getViewName() != null)
4417 af.viewport.viewName = view.getViewName();
4418 af.setInitialTabVisible();
4420 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4423 af.viewport.setShowAnnotation(view.getShowAnnotation());
4424 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4425 af.viewport.setThreshold(view.getPidThreshold());
4427 af.viewport.setColourText(view.getShowColourText());
4429 af.viewport.setConservationSelected(view.getConservationSelected());
4430 af.viewport.setIncrement(view.getConsThreshold());
4431 af.viewport.setShowJVSuffix(view.getShowFullId());
4432 af.viewport.setRightAlignIds(view.getRightAlignIds());
4433 af.viewport.setFont(
4434 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4435 .getFontSize()), true);
4436 ViewStyleI vs = af.viewport.getViewStyle();
4437 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4438 af.viewport.setViewStyle(vs);
4439 // TODO: allow custom charWidth/Heights to be restored by updating them
4440 // after setting font - which means set above to false
4441 af.viewport.setRenderGaps(view.getRenderGaps());
4442 af.viewport.setWrapAlignment(view.getWrapAlignment());
4443 af.viewport.setShowAnnotation(view.getShowAnnotation());
4445 af.viewport.setShowBoxes(view.getShowBoxes());
4447 af.viewport.setShowText(view.getShowText());
4449 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4450 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4451 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4452 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4453 .isShowUnconserved() : false);
4454 af.viewport.setStartRes(view.getStartRes());
4455 af.viewport.setStartSeq(view.getStartSeq());
4456 af.alignPanel.updateLayout();
4457 ColourSchemeI cs = null;
4458 // apply colourschemes
4459 if (view.getBgColour() != null)
4461 if (view.getBgColour().startsWith("ucs"))
4463 cs = getUserColourScheme(jms, view.getBgColour());
4465 else if (view.getBgColour().startsWith("Annotation"))
4467 AnnotationColours viewAnnColour = view.getAnnotationColours();
4468 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4475 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4480 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4484 af.viewport.setGlobalColourScheme(cs);
4485 af.viewport.setColourAppliesToAllGroups(false);
4487 if (view.getConservationSelected() && cs != null)
4489 cs.setConservationInc(view.getConsThreshold());
4492 af.changeColour(cs);
4494 af.viewport.setColourAppliesToAllGroups(true);
4496 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4498 if (view.hasCentreColumnLabels())
4500 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4502 if (view.hasIgnoreGapsinConsensus())
4504 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4507 if (view.hasFollowHighlight())
4509 af.viewport.setFollowHighlight(view.getFollowHighlight());
4511 if (view.hasFollowSelection())
4513 af.viewport.followSelection = view.getFollowSelection();
4515 if (view.hasShowConsensusHistogram())
4517 af.viewport.setShowConsensusHistogram(view
4518 .getShowConsensusHistogram());
4522 af.viewport.setShowConsensusHistogram(true);
4524 if (view.hasShowSequenceLogo())
4526 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4530 af.viewport.setShowSequenceLogo(false);
4532 if (view.hasNormaliseSequenceLogo())
4534 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4536 if (view.hasShowDbRefTooltip())
4538 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4540 if (view.hasShowNPfeatureTooltip())
4542 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4544 if (view.hasShowGroupConsensus())
4546 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4550 af.viewport.setShowGroupConsensus(false);
4552 if (view.hasShowGroupConservation())
4554 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4558 af.viewport.setShowGroupConservation(false);
4561 // recover featre settings
4562 if (jms.getFeatureSettings() != null)
4564 FeaturesDisplayed fdi;
4565 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4566 String[] renderOrder = new String[jms.getFeatureSettings()
4567 .getSettingCount()];
4568 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4569 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4571 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4573 Setting setting = jms.getFeatureSettings().getSetting(fs);
4574 if (setting.hasMincolour())
4576 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4577 new Color(setting.getMincolour()), new Color(
4578 setting.getColour()), setting.getMin(),
4579 setting.getMax()) : new FeatureColour(new Color(
4580 setting.getMincolour()), new Color(setting.getColour()),
4582 if (setting.hasThreshold())
4584 gc.setThreshold(setting.getThreshold());
4585 int threshstate = setting.getThreshstate();
4586 // -1 = None, 0 = Below, 1 = Above threshold
4587 if (threshstate == 0)
4589 gc.setBelowThreshold(true);
4591 else if (threshstate == 1)
4593 gc.setAboveThreshold(true);
4596 gc.setAutoScaled(true); // default
4597 if (setting.hasAutoScale())
4599 gc.setAutoScaled(setting.getAutoScale());
4601 if (setting.hasColourByLabel())
4603 gc.setColourByLabel(setting.getColourByLabel());
4605 // and put in the feature colour table.
4606 featureColours.put(setting.getType(), gc);
4610 featureColours.put(setting.getType(), new FeatureColour(
4611 new Color(setting.getColour())));
4613 renderOrder[fs] = setting.getType();
4614 if (setting.hasOrder())
4616 featureOrder.put(setting.getType(), setting.getOrder());
4620 featureOrder.put(setting.getType(), new Float(fs
4621 / jms.getFeatureSettings().getSettingCount()));
4623 if (setting.getDisplay())
4625 fdi.setVisible(setting.getType());
4628 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4629 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4631 Group grp = jms.getFeatureSettings().getGroup(gs);
4632 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4634 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4635 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4636 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4637 FeatureRendererSettings frs = new FeatureRendererSettings(
4638 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4639 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4640 .transferSettings(frs);
4644 if (view.getHiddenColumnsCount() > 0)
4646 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4648 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4649 .getHiddenColumns(c).getEnd() // +1
4653 if (view.getCalcIdParam() != null)
4655 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4657 if (calcIdParam != null)
4659 if (recoverCalcIdParam(calcIdParam, af.viewport))
4664 warn("Couldn't recover parameters for "
4665 + calcIdParam.getCalcId());
4670 af.setMenusFromViewport(af.viewport);
4671 af.setTitle(view.getTitle());
4672 // TODO: we don't need to do this if the viewport is aready visible.
4674 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4675 * has a 'cdna/protein complement' view, in which case save it in order to
4676 * populate a SplitFrame once all views have been read in.
4678 String complementaryViewId = view.getComplementId();
4679 if (complementaryViewId == null)
4681 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4683 // recompute any autoannotation
4684 af.alignPanel.updateAnnotation(false, true);
4685 reorderAutoannotation(af, al, autoAlan);
4686 af.alignPanel.alignmentChanged();
4690 splitFrameCandidates.put(view, af);
4695 private ColourSchemeI constructAnnotationColour(
4696 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4697 JalviewModelSequence jms, boolean checkGroupAnnColour)
4699 boolean propagateAnnColour = false;
4700 ColourSchemeI cs = null;
4701 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4702 if (checkGroupAnnColour && al.getGroups() != null
4703 && al.getGroups().size() > 0)
4705 // pre 2.8.1 behaviour
4706 // check to see if we should transfer annotation colours
4707 propagateAnnColour = true;
4708 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4710 if (sg.cs instanceof AnnotationColourGradient)
4712 propagateAnnColour = false;
4716 // int find annotation
4717 if (annAlignment.getAlignmentAnnotation() != null)
4719 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4721 if (annAlignment.getAlignmentAnnotation()[i].label
4722 .equals(viewAnnColour.getAnnotation()))
4724 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4726 annAlignment.getAlignmentAnnotation()[i]
4727 .setThreshold(new jalview.datamodel.GraphLine(
4728 viewAnnColour.getThreshold(), "Threshold",
4729 java.awt.Color.black)
4734 if (viewAnnColour.getColourScheme().equals("None"))
4736 cs = new AnnotationColourGradient(
4737 annAlignment.getAlignmentAnnotation()[i],
4738 new java.awt.Color(viewAnnColour.getMinColour()),
4739 new java.awt.Color(viewAnnColour.getMaxColour()),
4740 viewAnnColour.getAboveThreshold());
4742 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4744 cs = new AnnotationColourGradient(
4745 annAlignment.getAlignmentAnnotation()[i],
4746 getUserColourScheme(jms,
4747 viewAnnColour.getColourScheme()),
4748 viewAnnColour.getAboveThreshold());
4752 cs = new AnnotationColourGradient(
4753 annAlignment.getAlignmentAnnotation()[i],
4754 ColourSchemeProperty.getColour(al,
4755 viewAnnColour.getColourScheme()),
4756 viewAnnColour.getAboveThreshold());
4758 if (viewAnnColour.hasPerSequence())
4760 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4763 if (viewAnnColour.hasPredefinedColours())
4765 ((AnnotationColourGradient) cs)
4766 .setPredefinedColours(viewAnnColour
4767 .isPredefinedColours());
4769 if (propagateAnnColour && al.getGroups() != null)
4771 // Also use these settings for all the groups
4772 for (int g = 0; g < al.getGroups().size(); g++)
4774 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4782 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4783 * new AnnotationColourGradient(
4784 * annAlignment.getAlignmentAnnotation()[i], new
4785 * java.awt.Color(viewAnnColour. getMinColour()), new
4786 * java.awt.Color(viewAnnColour. getMaxColour()),
4787 * viewAnnColour.getAboveThreshold()); } else
4790 sg.cs = new AnnotationColourGradient(
4791 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4792 viewAnnColour.getAboveThreshold());
4793 if (cs instanceof AnnotationColourGradient)
4795 if (viewAnnColour.hasPerSequence())
4797 ((AnnotationColourGradient) cs)
4798 .setSeqAssociated(viewAnnColour.isPerSequence());
4800 if (viewAnnColour.hasPredefinedColours())
4802 ((AnnotationColourGradient) cs)
4803 .setPredefinedColours(viewAnnColour
4804 .isPredefinedColours());
4820 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4821 List<JvAnnotRow> autoAlan)
4823 // copy over visualization settings for autocalculated annotation in the
4825 if (al.getAlignmentAnnotation() != null)
4828 * Kludge for magic autoannotation names (see JAL-811)
4830 String[] magicNames = new String[] { "Consensus", "Quality",
4832 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4833 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4834 for (String nm : magicNames)
4836 visan.put(nm, nullAnnot);
4838 for (JvAnnotRow auan : autoAlan)
4840 visan.put(auan.template.label
4841 + (auan.template.getCalcId() == null ? "" : "\t"
4842 + auan.template.getCalcId()), auan);
4844 int hSize = al.getAlignmentAnnotation().length;
4845 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4846 // work through any autoCalculated annotation already on the view
4847 // removing it if it should be placed in a different location on the
4848 // annotation panel.
4849 List<String> remains = new ArrayList<String>(visan.keySet());
4850 for (int h = 0; h < hSize; h++)
4852 jalview.datamodel.AlignmentAnnotation jalan = al
4853 .getAlignmentAnnotation()[h];
4854 if (jalan.autoCalculated)
4857 JvAnnotRow valan = visan.get(k = jalan.label);
4858 if (jalan.getCalcId() != null)
4860 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4865 // delete the auto calculated row from the alignment
4866 al.deleteAnnotation(jalan, false);
4870 if (valan != nullAnnot)
4872 if (jalan != valan.template)
4874 // newly created autoannotation row instance
4875 // so keep a reference to the visible annotation row
4876 // and copy over all relevant attributes
4877 if (valan.template.graphHeight >= 0)
4880 jalan.graphHeight = valan.template.graphHeight;
4882 jalan.visible = valan.template.visible;
4884 reorder.add(new JvAnnotRow(valan.order, jalan));
4889 // Add any (possibly stale) autocalculated rows that were not appended to
4890 // the view during construction
4891 for (String other : remains)
4893 JvAnnotRow othera = visan.get(other);
4894 if (othera != nullAnnot && othera.template.getCalcId() != null
4895 && othera.template.getCalcId().length() > 0)
4897 reorder.add(othera);
4900 // now put the automatic annotation in its correct place
4901 int s = 0, srt[] = new int[reorder.size()];
4902 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4903 for (JvAnnotRow jvar : reorder)
4906 srt[s++] = jvar.order;
4909 jalview.util.QuickSort.sort(srt, rws);
4910 // and re-insert the annotation at its correct position
4911 for (JvAnnotRow jvar : rws)
4913 al.addAnnotation(jvar.template, jvar.order);
4915 af.alignPanel.adjustAnnotationHeight();
4919 Hashtable skipList = null;
4922 * TODO remove this method
4925 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4926 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4927 * throw new Error("Implementation Error. No skipList defined for this
4928 * Jalview2XML instance."); } return (AlignFrame)
4929 * skipList.get(view.getSequenceSetId()); }
4933 * Check if the Jalview view contained in object should be skipped or not.
4936 * @return true if view's sequenceSetId is a key in skipList
4938 private boolean skipViewport(JalviewModel object)
4940 if (skipList == null)
4945 if (skipList.containsKey(id = object.getJalviewModelSequence()
4946 .getViewport()[0].getSequenceSetId()))
4948 if (Cache.log != null && Cache.log.isDebugEnabled())
4950 Cache.log.debug("Skipping seuqence set id " + id);
4957 public void addToSkipList(AlignFrame af)
4959 if (skipList == null)
4961 skipList = new Hashtable();
4963 skipList.put(af.getViewport().getSequenceSetId(), af);
4966 public void clearSkipList()
4968 if (skipList != null)
4975 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4976 boolean ignoreUnrefed)
4978 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4980 Vector dseqs = null;
4983 // create a list of new dataset sequences
4984 dseqs = new Vector();
4986 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4988 Sequence vamsasSeq = vamsasSet.getSequence(i);
4989 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4991 // create a new dataset
4994 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4995 dseqs.copyInto(dsseqs);
4996 ds = new jalview.datamodel.Alignment(dsseqs);
4997 debug("Created new dataset " + vamsasSet.getDatasetId()
4998 + " for alignment " + System.identityHashCode(al));
4999 addDatasetRef(vamsasSet.getDatasetId(), ds);
5001 // set the dataset for the newly imported alignment.
5002 if (al.getDataset() == null && !ignoreUnrefed)
5011 * sequence definition to create/merge dataset sequence for
5015 * vector to add new dataset sequence to
5016 * @param ignoreUnrefed
5017 * - when true, don't create new sequences from vamsasSeq if it's id
5018 * doesn't already have an asssociated Jalview sequence.
5020 * - used to reorder the sequence in the alignment according to the
5021 * vamsasSeq array ordering, to preserve ordering of dataset
5023 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5024 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5026 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5028 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5029 boolean reorder = false;
5030 SequenceI dsq = null;
5031 if (sq != null && sq.getDatasetSequence() != null)
5033 dsq = sq.getDatasetSequence();
5039 if (sq == null && ignoreUnrefed)
5043 String sqid = vamsasSeq.getDsseqid();
5046 // need to create or add a new dataset sequence reference to this sequence
5049 dsq = seqRefIds.get(sqid);
5054 // make a new dataset sequence
5055 dsq = sq.createDatasetSequence();
5058 // make up a new dataset reference for this sequence
5059 sqid = seqHash(dsq);
5061 dsq.setVamsasId(uniqueSetSuffix + sqid);
5062 seqRefIds.put(sqid, dsq);
5067 dseqs.addElement(dsq);
5072 ds.addSequence(dsq);
5078 { // make this dataset sequence sq's dataset sequence
5079 sq.setDatasetSequence(dsq);
5080 // and update the current dataset alignment
5085 if (!dseqs.contains(dsq))
5092 if (ds.findIndex(dsq) < 0)
5094 ds.addSequence(dsq);
5101 // TODO: refactor this as a merge dataset sequence function
5102 // now check that sq (the dataset sequence) sequence really is the union of
5103 // all references to it
5104 // boolean pre = sq.getStart() < dsq.getStart();
5105 // boolean post = sq.getEnd() > dsq.getEnd();
5109 // StringBuffer sb = new StringBuffer();
5110 String newres = jalview.analysis.AlignSeq.extractGaps(
5111 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5112 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5113 && newres.length() > dsq.getLength())
5115 // Update with the longer sequence.
5119 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5120 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5121 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5122 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5124 dsq.setSequence(newres);
5126 // TODO: merges will never happen if we 'know' we have the real dataset
5127 // sequence - this should be detected when id==dssid
5129 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5130 // + (pre ? "prepended" : "") + " "
5131 // + (post ? "appended" : ""));
5136 // sequence refs are identical. We may need to update the existing dataset
5137 // alignment with this one, though.
5138 if (ds != null && dseqs == null)
5140 int opos = ds.findIndex(dsq);
5141 SequenceI tseq = null;
5142 if (opos != -1 && vseqpos != opos)
5144 // remove from old position
5145 ds.deleteSequence(dsq);
5147 if (vseqpos < ds.getHeight())
5149 if (vseqpos != opos)
5151 // save sequence at destination position
5152 tseq = ds.getSequenceAt(vseqpos);
5153 ds.replaceSequenceAt(vseqpos, dsq);
5154 ds.addSequence(tseq);
5159 ds.addSequence(dsq);
5166 * TODO use AlignmentI here and in related methods - needs
5167 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5169 Hashtable<String, AlignmentI> datasetIds = null;
5171 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5173 private AlignmentI getDatasetFor(String datasetId)
5175 if (datasetIds == null)
5177 datasetIds = new Hashtable<String, AlignmentI>();
5180 if (datasetIds.containsKey(datasetId))
5182 return datasetIds.get(datasetId);
5187 private void addDatasetRef(String datasetId, AlignmentI dataset)
5189 if (datasetIds == null)
5191 datasetIds = new Hashtable<String, AlignmentI>();
5193 datasetIds.put(datasetId, dataset);
5197 * make a new dataset ID for this jalview dataset alignment
5202 private String getDatasetIdRef(AlignmentI dataset)
5204 if (dataset.getDataset() != null)
5206 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5208 String datasetId = makeHashCode(dataset, null);
5209 if (datasetId == null)
5211 // make a new datasetId and record it
5212 if (dataset2Ids == null)
5214 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5218 datasetId = dataset2Ids.get(dataset);
5220 if (datasetId == null)
5222 datasetId = "ds" + dataset2Ids.size() + 1;
5223 dataset2Ids.put(dataset, datasetId);
5229 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5231 for (int d = 0; d < sequence.getDBRefCount(); d++)
5233 DBRef dr = sequence.getDBRef(d);
5234 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5235 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5236 .getVersion(), sequence.getDBRef(d).getAccessionId());
5237 if (dr.getMapping() != null)
5239 entry.setMap(addMapping(dr.getMapping()));
5241 datasetSequence.addDBRef(entry);
5245 private jalview.datamodel.Mapping addMapping(Mapping m)
5247 SequenceI dsto = null;
5248 // Mapping m = dr.getMapping();
5249 int fr[] = new int[m.getMapListFromCount() * 2];
5250 Enumeration f = m.enumerateMapListFrom();
5251 for (int _i = 0; f.hasMoreElements(); _i += 2)
5253 MapListFrom mf = (MapListFrom) f.nextElement();
5254 fr[_i] = mf.getStart();
5255 fr[_i + 1] = mf.getEnd();
5257 int fto[] = new int[m.getMapListToCount() * 2];
5258 f = m.enumerateMapListTo();
5259 for (int _i = 0; f.hasMoreElements(); _i += 2)
5261 MapListTo mf = (MapListTo) f.nextElement();
5262 fto[_i] = mf.getStart();
5263 fto[_i + 1] = mf.getEnd();
5265 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5266 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5267 if (m.getMappingChoice() != null)
5269 MappingChoice mc = m.getMappingChoice();
5270 if (mc.getDseqFor() != null)
5272 String dsfor = "" + mc.getDseqFor();
5273 if (seqRefIds.containsKey(dsfor))
5278 jmap.setTo(seqRefIds.get(dsfor));
5282 frefedSequence.add(newMappingRef(dsfor, jmap));
5288 * local sequence definition
5290 Sequence ms = mc.getSequence();
5291 SequenceI djs = null;
5292 String sqid = ms.getDsseqid();
5293 if (sqid != null && sqid.length() > 0)
5296 * recover dataset sequence
5298 djs = seqRefIds.get(sqid);
5303 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5304 sqid = ((Object) ms).toString(); // make up a new hascode for
5305 // undefined dataset sequence hash
5306 // (unlikely to happen)
5312 * make a new dataset sequence and add it to refIds hash
5314 djs = new jalview.datamodel.Sequence(ms.getName(),
5316 djs.setStart(jmap.getMap().getToLowest());
5317 djs.setEnd(jmap.getMap().getToHighest());
5318 djs.setVamsasId(uniqueSetSuffix + sqid);
5320 incompleteSeqs.put(sqid, djs);
5321 seqRefIds.put(sqid, djs);
5324 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5333 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5334 boolean keepSeqRefs)
5337 JalviewModel jm = saveState(ap, null, null, null);
5342 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5346 uniqueSetSuffix = "";
5347 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5352 if (this.frefedSequence == null)
5354 frefedSequence = new Vector();
5357 viewportsAdded.clear();
5359 AlignFrame af = loadFromObject(jm, null, false, null);
5360 af.alignPanels.clear();
5361 af.closeMenuItem_actionPerformed(true);
5364 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5365 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5366 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5367 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5368 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5371 return af.alignPanel;
5375 * flag indicating if hashtables should be cleared on finalization TODO this
5376 * flag may not be necessary
5378 private final boolean _cleartables = true;
5380 private Hashtable jvids2vobj;
5385 * @see java.lang.Object#finalize()
5388 protected void finalize() throws Throwable
5390 // really make sure we have no buried refs left.
5395 this.seqRefIds = null;
5396 this.seqsToIds = null;
5400 private void warn(String msg)
5405 private void warn(String msg, Exception e)
5407 if (Cache.log != null)
5411 Cache.log.warn(msg, e);
5415 Cache.log.warn(msg);
5420 System.err.println("Warning: " + msg);
5423 e.printStackTrace();
5428 private void debug(String string)
5430 debug(string, null);
5433 private void debug(String msg, Exception e)
5435 if (Cache.log != null)
5439 Cache.log.debug(msg, e);
5443 Cache.log.debug(msg);
5448 System.err.println("Warning: " + msg);
5451 e.printStackTrace();
5457 * set the object to ID mapping tables used to write/recover objects and XML
5458 * ID strings for the jalview project. If external tables are provided then
5459 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5460 * object goes out of scope. - also populates the datasetIds hashtable with
5461 * alignment objects containing dataset sequences
5464 * Map from ID strings to jalview datamodel
5466 * Map from jalview datamodel to ID strings
5470 public void setObjectMappingTables(Hashtable vobj2jv,
5471 IdentityHashMap jv2vobj)
5473 this.jv2vobj = jv2vobj;
5474 this.vobj2jv = vobj2jv;
5475 Iterator ds = jv2vobj.keySet().iterator();
5477 while (ds.hasNext())
5479 Object jvobj = ds.next();
5480 id = jv2vobj.get(jvobj).toString();
5481 if (jvobj instanceof jalview.datamodel.Alignment)
5483 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5485 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5488 else if (jvobj instanceof jalview.datamodel.Sequence)
5490 // register sequence object so the XML parser can recover it.
5491 if (seqRefIds == null)
5493 seqRefIds = new HashMap<String, SequenceI>();
5495 if (seqsToIds == null)
5497 seqsToIds = new IdentityHashMap<SequenceI, String>();
5499 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5500 seqsToIds.put((SequenceI) jvobj, id);
5502 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5505 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5506 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5507 if (jvann.annotationId == null)
5509 jvann.annotationId = anid;
5511 if (!jvann.annotationId.equals(anid))
5513 // TODO verify that this is the correct behaviour
5514 this.warn("Overriding Annotation ID for " + anid
5515 + " from different id : " + jvann.annotationId);
5516 jvann.annotationId = anid;
5519 else if (jvobj instanceof String)
5521 if (jvids2vobj == null)
5523 jvids2vobj = new Hashtable();
5524 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5529 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5535 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5536 * objects created from the project archive. If string is null (default for
5537 * construction) then suffix will be set automatically.
5541 public void setUniqueSetSuffix(String string)
5543 uniqueSetSuffix = string;
5548 * uses skipList2 as the skipList for skipping views on sequence sets
5549 * associated with keys in the skipList
5553 public void setSkipList(Hashtable skipList2)
5555 skipList = skipList2;
5559 * Reads the jar entry of given name and returns its contents, or null if the
5560 * entry is not found.
5563 * @param jarEntryName
5566 protected String readJarEntry(jarInputStreamProvider jprovider,
5567 String jarEntryName)
5569 String result = null;
5570 BufferedReader in = null;
5575 * Reopen the jar input stream and traverse its entries to find a matching
5578 JarInputStream jin = jprovider.getJarInputStream();
5579 JarEntry entry = null;
5582 entry = jin.getNextJarEntry();
5583 } while (entry != null && !entry.getName().equals(jarEntryName));
5587 StringBuilder out = new StringBuilder(256);
5588 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5591 while ((data = in.readLine()) != null)
5595 result = out.toString();
5599 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5601 } catch (Exception ex)
5603 ex.printStackTrace();
5611 } catch (IOException e)
5622 * Returns an incrementing counter (0, 1, 2...)
5626 private synchronized int nextCounter()