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.renderer.ResidueShaderI;
43 import jalview.schemabinding.version2.AlcodMap;
44 import jalview.schemabinding.version2.AlcodonFrame;
45 import jalview.schemabinding.version2.Annotation;
46 import jalview.schemabinding.version2.AnnotationColours;
47 import jalview.schemabinding.version2.AnnotationElement;
48 import jalview.schemabinding.version2.CalcIdParam;
49 import jalview.schemabinding.version2.DBRef;
50 import jalview.schemabinding.version2.Features;
51 import jalview.schemabinding.version2.Group;
52 import jalview.schemabinding.version2.HiddenColumns;
53 import jalview.schemabinding.version2.JGroup;
54 import jalview.schemabinding.version2.JSeq;
55 import jalview.schemabinding.version2.JalviewModel;
56 import jalview.schemabinding.version2.JalviewModelSequence;
57 import jalview.schemabinding.version2.MapListFrom;
58 import jalview.schemabinding.version2.MapListTo;
59 import jalview.schemabinding.version2.Mapping;
60 import jalview.schemabinding.version2.MappingChoice;
61 import jalview.schemabinding.version2.OtherData;
62 import jalview.schemabinding.version2.PdbentryItem;
63 import jalview.schemabinding.version2.Pdbids;
64 import jalview.schemabinding.version2.Property;
65 import jalview.schemabinding.version2.RnaViewer;
66 import jalview.schemabinding.version2.SecondaryStructure;
67 import jalview.schemabinding.version2.Sequence;
68 import jalview.schemabinding.version2.SequenceSet;
69 import jalview.schemabinding.version2.SequenceSetProperties;
70 import jalview.schemabinding.version2.Setting;
71 import jalview.schemabinding.version2.StructureState;
72 import jalview.schemabinding.version2.ThresholdLine;
73 import jalview.schemabinding.version2.Tree;
74 import jalview.schemabinding.version2.UserColours;
75 import jalview.schemabinding.version2.Viewport;
76 import jalview.schemes.AnnotationColourGradient;
77 import jalview.schemes.ColourSchemeI;
78 import jalview.schemes.ColourSchemeProperty;
79 import jalview.schemes.FeatureColour;
80 import jalview.schemes.ResidueColourScheme;
81 import jalview.schemes.ResidueProperties;
82 import jalview.schemes.UserColourScheme;
83 import jalview.structure.StructureSelectionManager;
84 import jalview.structures.models.AAStructureBindingModel;
85 import jalview.util.MessageManager;
86 import jalview.util.Platform;
87 import jalview.util.StringUtils;
88 import jalview.util.jarInputStreamProvider;
89 import jalview.viewmodel.AlignmentViewport;
90 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
91 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
92 import jalview.ws.jws2.Jws2Discoverer;
93 import jalview.ws.jws2.dm.AAConSettings;
94 import jalview.ws.jws2.jabaws2.Jws2Instance;
95 import jalview.ws.params.ArgumentI;
96 import jalview.ws.params.AutoCalcSetting;
97 import jalview.ws.params.WsParamSetI;
99 import java.awt.Color;
100 import java.awt.Rectangle;
101 import java.io.BufferedReader;
102 import java.io.DataInputStream;
103 import java.io.DataOutputStream;
105 import java.io.FileInputStream;
106 import java.io.FileOutputStream;
107 import java.io.IOException;
108 import java.io.InputStreamReader;
109 import java.io.OutputStreamWriter;
110 import java.io.PrintWriter;
111 import java.lang.reflect.InvocationTargetException;
112 import java.net.MalformedURLException;
114 import java.util.ArrayList;
115 import java.util.Arrays;
116 import java.util.Enumeration;
117 import java.util.HashMap;
118 import java.util.HashSet;
119 import java.util.Hashtable;
120 import java.util.IdentityHashMap;
121 import java.util.Iterator;
122 import java.util.LinkedHashMap;
123 import java.util.List;
124 import java.util.Map;
125 import java.util.Map.Entry;
126 import java.util.Set;
127 import java.util.Vector;
128 import java.util.jar.JarEntry;
129 import java.util.jar.JarInputStream;
130 import java.util.jar.JarOutputStream;
132 import javax.swing.JInternalFrame;
133 import javax.swing.SwingUtilities;
135 import org.exolab.castor.xml.Marshaller;
136 import org.exolab.castor.xml.Unmarshaller;
139 * Write out the current jalview desktop state as a Jalview XML stream.
141 * Note: the vamsas objects referred to here are primitive versions of the
142 * VAMSAS project schema elements - they are not the same and most likely never
146 * @version $Revision: 1.134 $
148 public class Jalview2XML
150 private static final String VIEWER_PREFIX = "viewer_";
152 private static final String RNA_PREFIX = "rna_";
154 private static final String UTF_8 = "UTF-8";
156 // use this with nextCounter() to make unique names for entities
157 private int counter = 0;
160 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
161 * of sequence objects are created.
163 IdentityHashMap<SequenceI, String> seqsToIds = null;
166 * jalview XML Sequence ID to jalview sequence object reference (both dataset
167 * and alignment sequences. Populated as XML reps of sequence objects are
170 Map<String, SequenceI> seqRefIds = null;
172 Map<String, SequenceI> incompleteSeqs = null;
174 List<SeqFref> frefedSequence = null;
176 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
179 * Map of reconstructed AlignFrame objects that appear to have come from
180 * SplitFrame objects (have a dna/protein complement view).
182 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
185 * Map from displayed rna structure models to their saved session state jar
188 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
191 * create/return unique hash string for sq
194 * @return new or existing unique string for sq
196 String seqHash(SequenceI sq)
198 if (seqsToIds == null)
202 if (seqsToIds.containsKey(sq))
204 return seqsToIds.get(sq);
208 // create sequential key
209 String key = "sq" + (seqsToIds.size() + 1);
210 key = makeHashCode(sq, key); // check we don't have an external reference
212 seqsToIds.put(sq, key);
221 if (seqRefIds != null)
225 if (seqsToIds != null)
229 if (incompleteSeqs != null)
231 incompleteSeqs.clear();
239 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
240 // seqRefIds = new Hashtable();
241 // seqsToIds = new IdentityHashMap();
247 if (seqsToIds == null)
249 seqsToIds = new IdentityHashMap<SequenceI, String>();
251 if (seqRefIds == null)
253 seqRefIds = new HashMap<String, SequenceI>();
255 if (incompleteSeqs == null)
257 incompleteSeqs = new HashMap<String, SequenceI>();
259 if (frefedSequence == null)
261 frefedSequence = new ArrayList<SeqFref>();
269 public Jalview2XML(boolean raiseGUI)
271 this.raiseGUI = raiseGUI;
275 * base class for resolving forward references to sequences by their ID
280 abstract class SeqFref
286 public SeqFref(String _sref, String type)
292 public String getSref()
297 public SequenceI getSrefSeq()
299 return seqRefIds.get(sref);
302 public boolean isResolvable()
304 return seqRefIds.get(sref) != null;
307 public SequenceI getSrefDatasetSeq()
309 SequenceI sq = seqRefIds.get(sref);
312 while (sq.getDatasetSequence() != null)
314 sq = sq.getDatasetSequence();
321 * @return true if the forward reference was fully resolved
323 abstract boolean resolve();
326 public String toString()
328 return type + " reference to " + sref;
333 * create forward reference for a mapping
339 public SeqFref newMappingRef(final String sref,
340 final jalview.datamodel.Mapping _jmap)
342 SeqFref fref = new SeqFref(sref, "Mapping")
344 public jalview.datamodel.Mapping jmap = _jmap;
349 SequenceI seq = getSrefDatasetSeq();
361 public SeqFref newAlcodMapRef(final String sref,
362 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
365 SeqFref fref = new SeqFref(sref, "Codon Frame")
367 AlignedCodonFrame cf = _cf;
369 public jalview.datamodel.Mapping mp = _jmap;
372 public boolean isResolvable()
374 return super.isResolvable() && mp.getTo() != null;
380 SequenceI seq = getSrefDatasetSeq();
385 cf.addMap(seq, mp.getTo(), mp.getMap());
392 public void resolveFrefedSequences()
394 Iterator<SeqFref> nextFref = frefedSequence.iterator();
395 int toresolve = frefedSequence.size();
396 int unresolved = 0, failedtoresolve = 0;
397 while (nextFref.hasNext())
399 SeqFref ref = nextFref.next();
400 if (ref.isResolvable())
412 } catch (Exception x)
415 .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
428 System.err.println("Jalview Project Import: There were " + unresolved
429 + " forward references left unresolved on the stack.");
431 if (failedtoresolve > 0)
433 System.err.println("SERIOUS! " + failedtoresolve
434 + " resolvable forward references failed to resolve.");
436 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
438 System.err.println("Jalview Project Import: There are "
439 + incompleteSeqs.size()
440 + " sequences which may have incomplete metadata.");
441 if (incompleteSeqs.size() < 10)
443 for (SequenceI s : incompleteSeqs.values())
445 System.err.println(s.toString());
451 .println("Too many to report. Skipping output of incomplete sequences.");
457 * This maintains a map of viewports, the key being the seqSetId. Important to
458 * set historyItem and redoList for multiple views
460 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
462 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
464 String uniqueSetSuffix = "";
467 * List of pdbfiles added to Jar
469 List<String> pdbfiles = null;
471 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
472 public void saveState(File statefile)
474 FileOutputStream fos = null;
477 fos = new FileOutputStream(statefile);
478 JarOutputStream jout = new JarOutputStream(fos);
481 } catch (Exception e)
483 // TODO: inform user of the problem - they need to know if their data was
485 if (errorMessage == null)
487 errorMessage = "Couldn't write Jalview Archive to output file '"
488 + statefile + "' - See console error log for details";
492 errorMessage += "(output file was '" + statefile + "')";
502 } catch (IOException e)
512 * Writes a jalview project archive to the given Jar output stream.
516 public void saveState(JarOutputStream jout)
518 AlignFrame[] frames = Desktop.getAlignFrames();
524 saveAllFrames(Arrays.asList(frames), jout);
528 * core method for storing state for a set of AlignFrames.
531 * - frames involving all data to be exported (including containing
534 * - project output stream
536 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
538 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
541 * ensure cached data is clear before starting
543 // todo tidy up seqRefIds, seqsToIds initialisation / reset
545 splitFrameCandidates.clear();
550 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
551 // //////////////////////////////////////////////////
553 List<String> shortNames = new ArrayList<String>();
554 List<String> viewIds = new ArrayList<String>();
557 for (int i = frames.size() - 1; i > -1; i--)
559 AlignFrame af = frames.get(i);
563 .containsKey(af.getViewport().getSequenceSetId()))
568 String shortName = makeFilename(af, shortNames);
570 int ap, apSize = af.alignPanels.size();
572 for (ap = 0; ap < apSize; ap++)
574 AlignmentPanel apanel = af.alignPanels.get(ap);
575 String fileName = apSize == 1 ? shortName : ap + shortName;
576 if (!fileName.endsWith(".xml"))
578 fileName = fileName + ".xml";
581 saveState(apanel, fileName, jout, viewIds);
583 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
585 if (!dsses.containsKey(dssid))
587 dsses.put(dssid, af);
592 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
598 } catch (Exception foo)
603 } catch (Exception ex)
605 // TODO: inform user of the problem - they need to know if their data was
607 if (errorMessage == null)
609 errorMessage = "Couldn't write Jalview Archive - see error output for details";
611 ex.printStackTrace();
616 * Generates a distinct file name, based on the title of the AlignFrame, by
617 * appending _n for increasing n until an unused name is generated. The new
618 * name (without its extension) is added to the list.
622 * @return the generated name, with .xml extension
624 protected String makeFilename(AlignFrame af, List<String> namesUsed)
626 String shortName = af.getTitle();
628 if (shortName.indexOf(File.separatorChar) > -1)
630 shortName = shortName.substring(shortName
631 .lastIndexOf(File.separatorChar) + 1);
636 while (namesUsed.contains(shortName))
638 if (shortName.endsWith("_" + (count - 1)))
640 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
643 shortName = shortName.concat("_" + count);
647 namesUsed.add(shortName);
649 if (!shortName.endsWith(".xml"))
651 shortName = shortName + ".xml";
656 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
657 public boolean saveAlignment(AlignFrame af, String jarFile,
662 FileOutputStream fos = new FileOutputStream(jarFile);
663 JarOutputStream jout = new JarOutputStream(fos);
664 List<AlignFrame> frames = new ArrayList<AlignFrame>();
666 // resolve splitframes
667 if (af.getViewport().getCodingComplement() != null)
669 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
675 saveAllFrames(frames, jout);
679 } catch (Exception foo)
685 } catch (Exception ex)
687 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
688 ex.printStackTrace();
693 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
694 String fileName, JarOutputStream jout)
697 for (String dssids : dsses.keySet())
699 AlignFrame _af = dsses.get(dssids);
700 String jfileName = fileName + " Dataset for " + _af.getTitle();
701 if (!jfileName.endsWith(".xml"))
703 jfileName = jfileName + ".xml";
705 saveState(_af.alignPanel, jfileName, true, jout, null);
710 * create a JalviewModel from an alignment view and marshall it to a
714 * panel to create jalview model for
716 * name of alignment panel written to output stream
723 public JalviewModel saveState(AlignmentPanel ap, String fileName,
724 JarOutputStream jout, List<String> viewIds)
726 return saveState(ap, fileName, false, jout, viewIds);
730 * create a JalviewModel from an alignment view and marshall it to a
734 * panel to create jalview model for
736 * name of alignment panel written to output stream
738 * when true, only write the dataset for the alignment, not the data
739 * associated with the view.
745 public JalviewModel saveState(AlignmentPanel ap, String fileName,
746 boolean storeDS, JarOutputStream jout, List<String> viewIds)
750 viewIds = new ArrayList<String>();
755 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
757 AlignViewport av = ap.av;
759 JalviewModel object = new JalviewModel();
760 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
762 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
763 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
764 "Development Build"));
767 * rjal is full height alignment, jal is actual alignment with full metadata
768 * but excludes hidden sequences.
770 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
772 if (av.hasHiddenRows())
774 rjal = jal.getHiddenSequences().getFullAlignment();
777 SequenceSet vamsasSet = new SequenceSet();
779 JalviewModelSequence jms = new JalviewModelSequence();
781 vamsasSet.setGapChar(jal.getGapCharacter() + "");
783 if (jal.getDataset() != null)
785 // dataset id is the dataset's hashcode
786 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
789 // switch jal and the dataset
790 jal = jal.getDataset();
794 if (jal.getProperties() != null)
796 Enumeration en = jal.getProperties().keys();
797 while (en.hasMoreElements())
799 String key = en.nextElement().toString();
800 SequenceSetProperties ssp = new SequenceSetProperties();
802 ssp.setValue(jal.getProperties().get(key).toString());
803 vamsasSet.addSequenceSetProperties(ssp);
808 Set<String> calcIdSet = new HashSet<String>();
809 // record the set of vamsas sequence XML POJO we create.
810 HashMap<String, Sequence> vamsasSetIds = new HashMap<String, Sequence>();
812 for (final SequenceI jds : rjal.getSequences())
814 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
815 : jds.getDatasetSequence();
816 String id = seqHash(jds);
817 if (vamsasSetIds.get(id) == null)
819 if (seqRefIds.get(id) != null && !storeDS)
821 // This happens for two reasons: 1. multiple views are being
823 // 2. the hashCode has collided with another sequence's code. This
825 // HAPPEN! (PF00072.15.stk does this)
826 // JBPNote: Uncomment to debug writing out of files that do not read
827 // back in due to ArrayOutOfBoundExceptions.
828 // System.err.println("vamsasSeq backref: "+id+"");
829 // System.err.println(jds.getName()+"
830 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
831 // System.err.println("Hashcode: "+seqHash(jds));
832 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
833 // System.err.println(rsq.getName()+"
834 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
835 // System.err.println("Hashcode: "+seqHash(rsq));
839 vamsasSeq = createVamsasSequence(id, jds);
840 vamsasSet.addSequence(vamsasSeq);
841 vamsasSetIds.put(id, vamsasSeq);
842 seqRefIds.put(id, jds);
846 jseq.setStart(jds.getStart());
847 jseq.setEnd(jds.getEnd());
848 jseq.setColour(av.getSequenceColour(jds).getRGB());
850 jseq.setId(id); // jseq id should be a string not a number
853 // Store any sequences this sequence represents
854 if (av.hasHiddenRows())
856 // use rjal, contains the full height alignment
857 jseq.setHidden(av.getAlignment().getHiddenSequences()
860 if (av.isHiddenRepSequence(jds))
862 jalview.datamodel.SequenceI[] reps = av
863 .getRepresentedSequences(jds).getSequencesInOrder(rjal);
865 for (int h = 0; h < reps.length; h++)
869 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
874 // mark sequence as reference - if it is the reference for this view
877 jseq.setViewreference(jds == jal.getSeqrep());
881 // TODO: omit sequence features from each alignment view's XML dump if we
882 // are storing dataset
883 if (jds.getSequenceFeatures() != null)
885 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
887 while (index < sf.length)
889 Features features = new Features();
891 features.setBegin(sf[index].getBegin());
892 features.setEnd(sf[index].getEnd());
893 features.setDescription(sf[index].getDescription());
894 features.setType(sf[index].getType());
895 features.setFeatureGroup(sf[index].getFeatureGroup());
896 features.setScore(sf[index].getScore());
897 if (sf[index].links != null)
899 for (int l = 0; l < sf[index].links.size(); l++)
901 OtherData keyValue = new OtherData();
902 keyValue.setKey("LINK_" + l);
903 keyValue.setValue(sf[index].links.elementAt(l).toString());
904 features.addOtherData(keyValue);
907 if (sf[index].otherDetails != null)
910 Iterator<String> keys = sf[index].otherDetails.keySet()
912 while (keys.hasNext())
915 OtherData keyValue = new OtherData();
916 keyValue.setKey(key);
917 keyValue.setValue(sf[index].otherDetails.get(key).toString());
918 features.addOtherData(keyValue);
922 jseq.addFeatures(features);
927 if (jdatasq.getAllPDBEntries() != null)
929 Enumeration en = jdatasq.getAllPDBEntries().elements();
930 while (en.hasMoreElements())
932 Pdbids pdb = new Pdbids();
933 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
936 String pdbId = entry.getId();
938 pdb.setType(entry.getType());
941 * Store any structure views associated with this sequence. This
942 * section copes with duplicate entries in the project, so a dataset
943 * only view *should* be coped with sensibly.
945 // This must have been loaded, is it still visible?
946 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
947 String matchedFile = null;
948 for (int f = frames.length - 1; f > -1; f--)
950 if (frames[f] instanceof StructureViewerBase)
952 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
953 matchedFile = saveStructureState(ap, jds, pdb, entry,
954 viewIds, matchedFile, viewFrame);
956 * Only store each structure viewer's state once in the project
957 * jar. First time through only (storeDS==false)
959 String viewId = viewFrame.getViewId();
960 if (!storeDS && !viewIds.contains(viewId))
965 String viewerState = viewFrame.getStateInfo();
966 writeJarEntry(jout, getViewerJarEntryName(viewId),
967 viewerState.getBytes());
968 } catch (IOException e)
970 System.err.println("Error saving viewer state: "
977 if (matchedFile != null || entry.getFile() != null)
979 if (entry.getFile() != null)
982 matchedFile = entry.getFile();
984 pdb.setFile(matchedFile); // entry.getFile());
985 if (pdbfiles == null)
987 pdbfiles = new ArrayList<String>();
990 if (!pdbfiles.contains(pdbId))
993 copyFileToJar(jout, matchedFile, pdbId);
997 Enumeration<String> props = entry.getProperties();
998 if (props.hasMoreElements())
1000 PdbentryItem item = new PdbentryItem();
1001 while (props.hasMoreElements())
1003 Property prop = new Property();
1004 String key = props.nextElement();
1006 prop.setValue(entry.getProperty(key).toString());
1007 item.addProperty(prop);
1009 pdb.addPdbentryItem(item);
1012 jseq.addPdbids(pdb);
1016 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1021 if (!storeDS && av.hasHiddenRows())
1023 jal = av.getAlignment();
1027 if (storeDS && jal.getCodonFrames() != null)
1029 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1030 for (AlignedCodonFrame acf : jac)
1032 AlcodonFrame alc = new AlcodonFrame();
1033 if (acf.getProtMappings() != null
1034 && acf.getProtMappings().length > 0)
1036 boolean hasMap = false;
1037 SequenceI[] dnas = acf.getdnaSeqs();
1038 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1039 for (int m = 0; m < pmaps.length; m++)
1041 AlcodMap alcmap = new AlcodMap();
1042 alcmap.setDnasq(seqHash(dnas[m]));
1043 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1045 alc.addAlcodMap(alcmap);
1050 vamsasSet.addAlcodonFrame(alc);
1053 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1055 // AlcodonFrame alc = new AlcodonFrame();
1056 // vamsasSet.addAlcodonFrame(alc);
1057 // for (int p = 0; p < acf.aaWidth; p++)
1059 // Alcodon cmap = new Alcodon();
1060 // if (acf.codons[p] != null)
1062 // // Null codons indicate a gapped column in the translated peptide
1064 // cmap.setPos1(acf.codons[p][0]);
1065 // cmap.setPos2(acf.codons[p][1]);
1066 // cmap.setPos3(acf.codons[p][2]);
1068 // alc.addAlcodon(cmap);
1070 // if (acf.getProtMappings() != null
1071 // && acf.getProtMappings().length > 0)
1073 // SequenceI[] dnas = acf.getdnaSeqs();
1074 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1075 // for (int m = 0; m < pmaps.length; m++)
1077 // AlcodMap alcmap = new AlcodMap();
1078 // alcmap.setDnasq(seqHash(dnas[m]));
1079 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1081 // alc.addAlcodMap(alcmap);
1088 // /////////////////////////////////
1089 if (!storeDS && av.currentTree != null)
1091 // FIND ANY ASSOCIATED TREES
1092 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1093 if (Desktop.desktop != null)
1095 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1097 for (int t = 0; t < frames.length; t++)
1099 if (frames[t] instanceof TreePanel)
1101 TreePanel tp = (TreePanel) frames[t];
1103 if (tp.treeCanvas.av.getAlignment() == jal)
1105 Tree tree = new Tree();
1106 tree.setTitle(tp.getTitle());
1107 tree.setCurrentTree((av.currentTree == tp.getTree()));
1108 tree.setNewick(tp.getTree().toString());
1109 tree.setThreshold(tp.treeCanvas.threshold);
1111 tree.setFitToWindow(tp.fitToWindow.getState());
1112 tree.setFontName(tp.getTreeFont().getName());
1113 tree.setFontSize(tp.getTreeFont().getSize());
1114 tree.setFontStyle(tp.getTreeFont().getStyle());
1115 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1117 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1118 tree.setShowDistances(tp.distanceMenu.getState());
1120 tree.setHeight(tp.getHeight());
1121 tree.setWidth(tp.getWidth());
1122 tree.setXpos(tp.getX());
1123 tree.setYpos(tp.getY());
1124 tree.setId(makeHashCode(tp, null));
1134 * store forward refs from an annotationRow to any groups
1136 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1139 for (SequenceI sq : jal.getSequences())
1141 // Store annotation on dataset sequences only
1142 AlignmentAnnotation[] aa = sq.getAnnotation();
1143 if (aa != null && aa.length > 0)
1145 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1152 if (jal.getAlignmentAnnotation() != null)
1154 // Store the annotation shown on the alignment.
1155 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1156 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1161 if (jal.getGroups() != null)
1163 JGroup[] groups = new JGroup[jal.getGroups().size()];
1165 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1167 JGroup jGroup = new JGroup();
1168 groups[++i] = jGroup;
1170 jGroup.setStart(sg.getStartRes());
1171 jGroup.setEnd(sg.getEndRes());
1172 jGroup.setName(sg.getName());
1173 if (groupRefs.containsKey(sg))
1175 // group has references so set its ID field
1176 jGroup.setId(groupRefs.get(sg));
1178 ColourSchemeI colourScheme = sg.getColourScheme();
1179 if (colourScheme != null)
1181 ResidueShaderI groupColourScheme = sg
1182 .getGroupColourScheme();
1183 if (groupColourScheme.conservationApplied())
1185 jGroup.setConsThreshold(groupColourScheme.getConservationInc());
1187 if (colourScheme instanceof jalview.schemes.UserColourScheme)
1189 jGroup.setColour(setUserColourScheme(colourScheme,
1194 jGroup.setColour(colourScheme.getSchemeName());
1197 else if (colourScheme instanceof jalview.schemes.AnnotationColourGradient)
1199 jGroup.setColour("AnnotationColourGradient");
1200 jGroup.setAnnotationColours(constructAnnotationColours(
1201 (jalview.schemes.AnnotationColourGradient) colourScheme,
1204 else if (colourScheme instanceof jalview.schemes.UserColourScheme)
1206 jGroup.setColour(setUserColourScheme(colourScheme,
1211 jGroup.setColour(colourScheme.getSchemeName());
1214 jGroup.setPidThreshold(groupColourScheme.getThreshold());
1217 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1218 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1219 jGroup.setDisplayText(sg.getDisplayText());
1220 jGroup.setColourText(sg.getColourText());
1221 jGroup.setTextCol1(sg.textColour.getRGB());
1222 jGroup.setTextCol2(sg.textColour2.getRGB());
1223 jGroup.setTextColThreshold(sg.thresholdTextColour);
1224 jGroup.setShowUnconserved(sg.getShowNonconserved());
1225 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1226 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1227 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1228 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1229 for (SequenceI seq : sg.getSequences())
1231 jGroup.addSeq(seqHash(seq));
1235 jms.setJGroup(groups);
1239 // /////////SAVE VIEWPORT
1240 Viewport view = new Viewport();
1241 view.setTitle(ap.alignFrame.getTitle());
1242 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1243 av.getSequenceSetId()));
1244 view.setId(av.getViewId());
1245 if (av.getCodingComplement() != null)
1247 view.setComplementId(av.getCodingComplement().getViewId());
1249 view.setViewName(av.viewName);
1250 view.setGatheredViews(av.isGatherViewsHere());
1252 Rectangle size = ap.av.getExplodedGeometry();
1253 Rectangle position = size;
1256 size = ap.alignFrame.getBounds();
1257 if (av.getCodingComplement() != null)
1259 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1267 view.setXpos(position.x);
1268 view.setYpos(position.y);
1270 view.setWidth(size.width);
1271 view.setHeight(size.height);
1273 view.setStartRes(av.startRes);
1274 view.setStartSeq(av.startSeq);
1276 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1278 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1281 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1283 AnnotationColours ac = constructAnnotationColours(
1284 (jalview.schemes.AnnotationColourGradient) av
1285 .getGlobalColourScheme(),
1288 view.setAnnotationColours(ac);
1289 view.setBgColour("AnnotationColourGradient");
1293 view.setBgColour(ColourSchemeProperty.getColourName(av
1294 .getGlobalColourScheme()));
1297 ResidueShaderI vcs = av.getResidueShading();
1298 ColourSchemeI cs = av.getGlobalColourScheme();
1302 if (vcs.conservationApplied())
1304 view.setConsThreshold(vcs.getConservationInc());
1305 if (cs instanceof jalview.schemes.UserColourScheme)
1307 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1310 view.setPidThreshold(vcs.getThreshold());
1313 view.setConservationSelected(av.getConservationSelected());
1314 view.setPidSelected(av.getAbovePIDThreshold());
1315 view.setFontName(av.font.getName());
1316 view.setFontSize(av.font.getSize());
1317 view.setFontStyle(av.font.getStyle());
1318 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1319 view.setRenderGaps(av.isRenderGaps());
1320 view.setShowAnnotation(av.isShowAnnotation());
1321 view.setShowBoxes(av.getShowBoxes());
1322 view.setShowColourText(av.getColourText());
1323 view.setShowFullId(av.getShowJVSuffix());
1324 view.setRightAlignIds(av.isRightAlignIds());
1325 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1326 view.setShowText(av.getShowText());
1327 view.setShowUnconserved(av.getShowUnconserved());
1328 view.setWrapAlignment(av.getWrapAlignment());
1329 view.setTextCol1(av.getTextColour().getRGB());
1330 view.setTextCol2(av.getTextColour2().getRGB());
1331 view.setTextColThreshold(av.getThresholdTextColour());
1332 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1333 view.setShowSequenceLogo(av.isShowSequenceLogo());
1334 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1335 view.setShowGroupConsensus(av.isShowGroupConsensus());
1336 view.setShowGroupConservation(av.isShowGroupConservation());
1337 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1338 view.setShowDbRefTooltip(av.isShowDBRefs());
1339 view.setFollowHighlight(av.isFollowHighlight());
1340 view.setFollowSelection(av.followSelection);
1341 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1342 if (av.getFeaturesDisplayed() != null)
1344 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1346 String[] renderOrder = ap.getSeqPanel().seqCanvas
1347 .getFeatureRenderer().getRenderOrder()
1348 .toArray(new String[0]);
1350 Vector<String> settingsAdded = new Vector<String>();
1351 if (renderOrder != null)
1353 for (String featureType : renderOrder)
1355 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1356 .getFeatureRenderer().getFeatureStyle(featureType);
1357 Setting setting = new Setting();
1358 setting.setType(featureType);
1359 if (!fcol.isSimpleColour())
1361 setting.setColour(fcol.getMaxColour().getRGB());
1362 setting.setMincolour(fcol.getMinColour().getRGB());
1363 setting.setMin(fcol.getMin());
1364 setting.setMax(fcol.getMax());
1365 setting.setColourByLabel(fcol.isColourByLabel());
1366 setting.setAutoScale(fcol.isAutoScaled());
1367 setting.setThreshold(fcol.getThreshold());
1368 // -1 = No threshold, 0 = Below, 1 = Above
1369 setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
1370 .isBelowThreshold() ? 0 : -1));
1374 setting.setColour(fcol.getColour().getRGB());
1377 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1379 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1380 .getOrder(featureType);
1383 setting.setOrder(rorder);
1385 fs.addSetting(setting);
1386 settingsAdded.addElement(featureType);
1390 // is groups actually supposed to be a map here ?
1391 Iterator<String> en = ap.getSeqPanel().seqCanvas
1392 .getFeatureRenderer().getFeatureGroups().iterator();
1393 Vector<String> groupsAdded = new Vector<String>();
1394 while (en.hasNext())
1396 String grp = en.next();
1397 if (groupsAdded.contains(grp))
1401 Group g = new Group();
1403 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1404 .getFeatureRenderer().checkGroupVisibility(grp, false))
1407 groupsAdded.addElement(grp);
1409 jms.setFeatureSettings(fs);
1412 if (av.hasHiddenColumns())
1414 if (av.getColumnSelection() == null
1415 || av.getColumnSelection().getHiddenColumns() == null)
1417 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1421 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1424 int[] region = av.getColumnSelection().getHiddenColumns()
1426 HiddenColumns hc = new HiddenColumns();
1427 hc.setStart(region[0]);
1428 hc.setEnd(region[1]);
1429 view.addHiddenColumns(hc);
1433 if (calcIdSet.size() > 0)
1435 for (String calcId : calcIdSet)
1437 if (calcId.trim().length() > 0)
1439 CalcIdParam cidp = createCalcIdParam(calcId, av);
1440 // Some calcIds have no parameters.
1443 view.addCalcIdParam(cidp);
1449 jms.addViewport(view);
1451 object.setJalviewModelSequence(jms);
1452 object.getVamsasModel().addSequenceSet(vamsasSet);
1454 if (jout != null && fileName != null)
1456 // We may not want to write the object to disk,
1457 // eg we can copy the alignViewport to a new view object
1458 // using save and then load
1461 System.out.println("Writing jar entry " + fileName);
1462 JarEntry entry = new JarEntry(fileName);
1463 jout.putNextEntry(entry);
1464 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1466 Marshaller marshaller = new Marshaller(pout);
1467 marshaller.marshal(object);
1470 } catch (Exception ex)
1472 // TODO: raise error in GUI if marshalling failed.
1473 ex.printStackTrace();
1480 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1481 * for each viewer, with
1483 * <li>viewer geometry (position, size, split pane divider location)</li>
1484 * <li>index of the selected structure in the viewer (currently shows gapped
1486 * <li>the id of the annotation holding RNA secondary structure</li>
1487 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1489 * Varna viewer state is also written out (in native Varna XML) to separate
1490 * project jar entries. A separate entry is written for each RNA structure
1491 * displayed, with the naming convention
1493 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1501 * @param storeDataset
1503 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1504 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1505 boolean storeDataset)
1507 if (Desktop.desktop == null)
1511 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1512 for (int f = frames.length - 1; f > -1; f--)
1514 if (frames[f] instanceof AppVarna)
1516 AppVarna varna = (AppVarna) frames[f];
1518 * link the sequence to every viewer that is showing it and is linked to
1519 * its alignment panel
1521 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1523 String viewId = varna.getViewId();
1524 RnaViewer rna = new RnaViewer();
1525 rna.setViewId(viewId);
1526 rna.setTitle(varna.getTitle());
1527 rna.setXpos(varna.getX());
1528 rna.setYpos(varna.getY());
1529 rna.setWidth(varna.getWidth());
1530 rna.setHeight(varna.getHeight());
1531 rna.setDividerLocation(varna.getDividerLocation());
1532 rna.setSelectedRna(varna.getSelectedIndex());
1533 jseq.addRnaViewer(rna);
1536 * Store each Varna panel's state once in the project per sequence.
1537 * First time through only (storeDataset==false)
1539 // boolean storeSessions = false;
1540 // String sequenceViewId = viewId + seqsToIds.get(jds);
1541 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1543 // viewIds.add(sequenceViewId);
1544 // storeSessions = true;
1546 for (RnaModel model : varna.getModels())
1548 if (model.seq == jds)
1551 * VARNA saves each view (sequence or alignment secondary
1552 * structure, gapped or trimmed) as a separate XML file
1554 String jarEntryName = rnaSessions.get(model);
1555 if (jarEntryName == null)
1558 String varnaStateFile = varna.getStateInfo(model.rna);
1559 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1560 copyFileToJar(jout, varnaStateFile, jarEntryName);
1561 rnaSessions.put(model, jarEntryName);
1563 SecondaryStructure ss = new SecondaryStructure();
1564 String annotationId = varna.getAnnotation(jds).annotationId;
1565 ss.setAnnotationId(annotationId);
1566 ss.setViewerState(jarEntryName);
1567 ss.setGapped(model.gapped);
1568 ss.setTitle(model.title);
1569 rna.addSecondaryStructure(ss);
1578 * Copy the contents of a file to a new entry added to the output jar
1582 * @param jarEntryName
1584 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1585 String jarEntryName)
1587 DataInputStream dis = null;
1590 File file = new File(infilePath);
1591 if (file.exists() && jout != null)
1593 dis = new DataInputStream(new FileInputStream(file));
1594 byte[] data = new byte[(int) file.length()];
1595 dis.readFully(data);
1596 writeJarEntry(jout, jarEntryName, data);
1598 } catch (Exception ex)
1600 ex.printStackTrace();
1608 } catch (IOException e)
1617 * Write the data to a new entry of given name in the output jar file
1620 * @param jarEntryName
1622 * @throws IOException
1624 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1625 byte[] data) throws IOException
1629 System.out.println("Writing jar entry " + jarEntryName);
1630 jout.putNextEntry(new JarEntry(jarEntryName));
1631 DataOutputStream dout = new DataOutputStream(jout);
1632 dout.write(data, 0, data.length);
1639 * Save the state of a structure viewer
1644 * the archive XML element under which to save the state
1647 * @param matchedFile
1651 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1652 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1653 String matchedFile, StructureViewerBase viewFrame)
1655 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1658 * Look for any bindings for this viewer to the PDB file of interest
1659 * (including part matches excluding chain id)
1661 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1663 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1664 final String pdbId = pdbentry.getId();
1665 if (!pdbId.equals(entry.getId())
1666 && !(entry.getId().length() > 4 && entry.getId()
1667 .toLowerCase().startsWith(pdbId.toLowerCase())))
1670 * not interested in a binding to a different PDB entry here
1674 if (matchedFile == null)
1676 matchedFile = pdbentry.getFile();
1678 else if (!matchedFile.equals(pdbentry.getFile()))
1681 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1682 + pdbentry.getFile());
1686 // can get at it if the ID
1687 // match is ambiguous (e.g.
1690 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1692 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1693 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1695 StructureState state = new StructureState();
1696 state.setVisible(true);
1697 state.setXpos(viewFrame.getX());
1698 state.setYpos(viewFrame.getY());
1699 state.setWidth(viewFrame.getWidth());
1700 state.setHeight(viewFrame.getHeight());
1701 final String viewId = viewFrame.getViewId();
1702 state.setViewId(viewId);
1703 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1704 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1705 state.setColourByJmol(viewFrame.isColouredByViewer());
1706 state.setType(viewFrame.getViewerType().toString());
1707 pdb.addStructureState(state);
1714 private AnnotationColours constructAnnotationColours(
1715 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1716 JalviewModelSequence jms)
1718 AnnotationColours ac = new AnnotationColours();
1719 ac.setAboveThreshold(acg.getAboveThreshold());
1720 ac.setThreshold(acg.getAnnotationThreshold());
1721 ac.setAnnotation(acg.getAnnotation());
1722 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1724 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1729 ac.setColourScheme(ColourSchemeProperty.getColourName(acg.getBaseColour()));
1732 ac.setMaxColour(acg.getMaxColour().getRGB());
1733 ac.setMinColour(acg.getMinColour().getRGB());
1734 ac.setPerSequence(acg.isSeqAssociated());
1735 ac.setPredefinedColours(acg.isPredefinedColours());
1739 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1740 IdentityHashMap<SequenceGroup, String> groupRefs,
1741 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1742 SequenceSet vamsasSet)
1745 for (int i = 0; i < aa.length; i++)
1747 Annotation an = new Annotation();
1749 AlignmentAnnotation annotation = aa[i];
1750 if (annotation.annotationId != null)
1752 annotationIds.put(annotation.annotationId, annotation);
1755 an.setId(annotation.annotationId);
1757 an.setVisible(annotation.visible);
1759 an.setDescription(annotation.description);
1761 if (annotation.sequenceRef != null)
1763 // 2.9 JAL-1781 xref on sequence id rather than name
1764 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1766 if (annotation.groupRef != null)
1768 String groupIdr = groupRefs.get(annotation.groupRef);
1769 if (groupIdr == null)
1771 // make a locally unique String
1773 annotation.groupRef,
1774 groupIdr = ("" + System.currentTimeMillis()
1775 + annotation.groupRef.getName() + groupRefs
1778 an.setGroupRef(groupIdr.toString());
1781 // store all visualization attributes for annotation
1782 an.setGraphHeight(annotation.graphHeight);
1783 an.setCentreColLabels(annotation.centreColLabels);
1784 an.setScaleColLabels(annotation.scaleColLabel);
1785 an.setShowAllColLabels(annotation.showAllColLabels);
1786 an.setBelowAlignment(annotation.belowAlignment);
1788 if (annotation.graph > 0)
1791 an.setGraphType(annotation.graph);
1792 an.setGraphGroup(annotation.graphGroup);
1793 if (annotation.getThreshold() != null)
1795 ThresholdLine line = new ThresholdLine();
1796 line.setLabel(annotation.getThreshold().label);
1797 line.setValue(annotation.getThreshold().value);
1798 line.setColour(annotation.getThreshold().colour.getRGB());
1799 an.setThresholdLine(line);
1807 an.setLabel(annotation.label);
1809 if (annotation == av.getAlignmentQualityAnnot()
1810 || annotation == av.getAlignmentConservationAnnotation()
1811 || annotation == av.getAlignmentConsensusAnnotation()
1812 || annotation.autoCalculated)
1814 // new way of indicating autocalculated annotation -
1815 an.setAutoCalculated(annotation.autoCalculated);
1817 if (annotation.hasScore())
1819 an.setScore(annotation.getScore());
1822 if (annotation.getCalcId() != null)
1824 calcIdSet.add(annotation.getCalcId());
1825 an.setCalcId(annotation.getCalcId());
1827 if (annotation.hasProperties())
1829 for (String pr : annotation.getProperties())
1831 Property prop = new Property();
1833 prop.setValue(annotation.getProperty(pr));
1834 an.addProperty(prop);
1838 AnnotationElement ae;
1839 if (annotation.annotations != null)
1841 an.setScoreOnly(false);
1842 for (int a = 0; a < annotation.annotations.length; a++)
1844 if ((annotation == null) || (annotation.annotations[a] == null))
1849 ae = new AnnotationElement();
1850 if (annotation.annotations[a].description != null)
1852 ae.setDescription(annotation.annotations[a].description);
1854 if (annotation.annotations[a].displayCharacter != null)
1856 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1859 if (!Float.isNaN(annotation.annotations[a].value))
1861 ae.setValue(annotation.annotations[a].value);
1865 if (annotation.annotations[a].secondaryStructure > ' ')
1867 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1871 if (annotation.annotations[a].colour != null
1872 && annotation.annotations[a].colour != java.awt.Color.black)
1874 ae.setColour(annotation.annotations[a].colour.getRGB());
1877 an.addAnnotationElement(ae);
1878 if (annotation.autoCalculated)
1880 // only write one non-null entry into the annotation row -
1881 // sufficient to get the visualization attributes necessary to
1889 an.setScoreOnly(true);
1891 if (!storeDS || (storeDS && !annotation.autoCalculated))
1893 // skip autocalculated annotation - these are only provided for
1895 vamsasSet.addAnnotation(an);
1901 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1903 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1904 if (settings != null)
1906 CalcIdParam vCalcIdParam = new CalcIdParam();
1907 vCalcIdParam.setCalcId(calcId);
1908 vCalcIdParam.addServiceURL(settings.getServiceURI());
1909 // generic URI allowing a third party to resolve another instance of the
1910 // service used for this calculation
1911 for (String urls : settings.getServiceURLs())
1913 vCalcIdParam.addServiceURL(urls);
1915 vCalcIdParam.setVersion("1.0");
1916 if (settings.getPreset() != null)
1918 WsParamSetI setting = settings.getPreset();
1919 vCalcIdParam.setName(setting.getName());
1920 vCalcIdParam.setDescription(setting.getDescription());
1924 vCalcIdParam.setName("");
1925 vCalcIdParam.setDescription("Last used parameters");
1927 // need to be able to recover 1) settings 2) user-defined presets or
1928 // recreate settings from preset 3) predefined settings provided by
1929 // service - or settings that can be transferred (or discarded)
1930 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1932 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1933 // todo - decide if updateImmediately is needed for any projects.
1935 return vCalcIdParam;
1940 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1943 if (calcIdParam.getVersion().equals("1.0"))
1945 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1946 .getPreferredServiceFor(calcIdParam.getServiceURL());
1947 if (service != null)
1949 WsParamSetI parmSet = null;
1952 parmSet = service.getParamStore().parseServiceParameterFile(
1953 calcIdParam.getName(), calcIdParam.getDescription(),
1954 calcIdParam.getServiceURL(),
1955 calcIdParam.getParameters().replace("|\\n|", "\n"));
1956 } catch (IOException x)
1958 warn("Couldn't parse parameter data for "
1959 + calcIdParam.getCalcId(), x);
1962 List<ArgumentI> argList = null;
1963 if (calcIdParam.getName().length() > 0)
1965 parmSet = service.getParamStore()
1966 .getPreset(calcIdParam.getName());
1967 if (parmSet != null)
1969 // TODO : check we have a good match with settings in AACon -
1970 // otherwise we'll need to create a new preset
1975 argList = parmSet.getArguments();
1978 AAConSettings settings = new AAConSettings(
1979 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1980 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1981 calcIdParam.isNeedsUpdate());
1986 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1990 throw new Error(MessageManager.formatMessage(
1991 "error.unsupported_version_calcIdparam",
1992 new Object[] { calcIdParam.toString() }));
1996 * External mapping between jalview objects and objects yielding a valid and
1997 * unique object ID string. This is null for normal Jalview project IO, but
1998 * non-null when a jalview project is being read or written as part of a
2001 IdentityHashMap jv2vobj = null;
2004 * Construct a unique ID for jvobj using either existing bindings or if none
2005 * exist, the result of the hashcode call for the object.
2008 * jalview data object
2009 * @return unique ID for referring to jvobj
2011 private String makeHashCode(Object jvobj, String altCode)
2013 if (jv2vobj != null)
2015 Object id = jv2vobj.get(jvobj);
2018 return id.toString();
2020 // check string ID mappings
2021 if (jvids2vobj != null && jvobj instanceof String)
2023 id = jvids2vobj.get(jvobj);
2027 return id.toString();
2029 // give up and warn that something has gone wrong
2030 warn("Cannot find ID for object in external mapping : " + jvobj);
2036 * return local jalview object mapped to ID, if it exists
2040 * @return null or object bound to idcode
2042 private Object retrieveExistingObj(String idcode)
2044 if (idcode != null && vobj2jv != null)
2046 return vobj2jv.get(idcode);
2052 * binding from ID strings from external mapping table to jalview data model
2055 private Hashtable vobj2jv;
2057 private Sequence createVamsasSequence(String id, SequenceI jds)
2059 return createVamsasSequence(true, id, jds, null);
2062 private Sequence createVamsasSequence(boolean recurse, String id,
2063 SequenceI jds, SequenceI parentseq)
2065 Sequence vamsasSeq = new Sequence();
2066 vamsasSeq.setId(id);
2067 vamsasSeq.setName(jds.getName());
2068 vamsasSeq.setSequence(jds.getSequenceAsString());
2069 vamsasSeq.setDescription(jds.getDescription());
2070 jalview.datamodel.DBRefEntry[] dbrefs = null;
2071 if (jds.getDatasetSequence() != null)
2073 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2077 // seqId==dsseqid so we can tell which sequences really are
2078 // dataset sequences only
2079 vamsasSeq.setDsseqid(id);
2080 dbrefs = jds.getDBRefs();
2081 if (parentseq == null)
2088 for (int d = 0; d < dbrefs.length; d++)
2090 DBRef dbref = new DBRef();
2091 dbref.setSource(dbrefs[d].getSource());
2092 dbref.setVersion(dbrefs[d].getVersion());
2093 dbref.setAccessionId(dbrefs[d].getAccessionId());
2094 if (dbrefs[d].hasMap())
2096 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2098 dbref.setMapping(mp);
2100 vamsasSeq.addDBRef(dbref);
2106 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2107 SequenceI parentseq, SequenceI jds, boolean recurse)
2110 if (jmp.getMap() != null)
2114 jalview.util.MapList mlst = jmp.getMap();
2115 List<int[]> r = mlst.getFromRanges();
2116 for (int[] range : r)
2118 MapListFrom mfrom = new MapListFrom();
2119 mfrom.setStart(range[0]);
2120 mfrom.setEnd(range[1]);
2121 mp.addMapListFrom(mfrom);
2123 r = mlst.getToRanges();
2124 for (int[] range : r)
2126 MapListTo mto = new MapListTo();
2127 mto.setStart(range[0]);
2128 mto.setEnd(range[1]);
2129 mp.addMapListTo(mto);
2131 mp.setMapFromUnit(mlst.getFromRatio());
2132 mp.setMapToUnit(mlst.getToRatio());
2133 if (jmp.getTo() != null)
2135 MappingChoice mpc = new MappingChoice();
2137 // check/create ID for the sequence referenced by getTo()
2140 SequenceI ps = null;
2141 if (parentseq != jmp.getTo()
2142 && parentseq.getDatasetSequence() != jmp.getTo())
2144 // chaining dbref rather than a handshaking one
2145 jmpid = seqHash(ps = jmp.getTo());
2149 jmpid = seqHash(ps = parentseq);
2151 mpc.setDseqFor(jmpid);
2152 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2154 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2155 seqRefIds.put(mpc.getDseqFor(), ps);
2159 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2162 mp.setMappingChoice(mpc);
2168 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2169 List<UserColourScheme> userColours, JalviewModelSequence jms)
2172 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2173 boolean newucs = false;
2174 if (!userColours.contains(ucs))
2176 userColours.add(ucs);
2179 id = "ucs" + userColours.indexOf(ucs);
2182 // actually create the scheme's entry in the XML model
2183 java.awt.Color[] colours = ucs.getColours();
2184 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2185 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2187 for (int i = 0; i < colours.length; i++)
2189 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2190 col.setName(ResidueProperties.aa[i]);
2191 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2192 jbucs.addColour(col);
2194 if (ucs.getLowerCaseColours() != null)
2196 colours = ucs.getLowerCaseColours();
2197 for (int i = 0; i < colours.length; i++)
2199 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2200 col.setName(ResidueProperties.aa[i].toLowerCase());
2201 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2202 jbucs.addColour(col);
2207 uc.setUserColourScheme(jbucs);
2208 jms.addUserColours(uc);
2214 jalview.schemes.UserColourScheme getUserColourScheme(
2215 JalviewModelSequence jms, String id)
2217 UserColours[] uc = jms.getUserColours();
2218 UserColours colours = null;
2220 for (int i = 0; i < uc.length; i++)
2222 if (uc[i].getId().equals(id))
2230 java.awt.Color[] newColours = new java.awt.Color[24];
2232 for (int i = 0; i < 24; i++)
2234 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2235 .getUserColourScheme().getColour(i).getRGB(), 16));
2238 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2241 if (colours.getUserColourScheme().getColourCount() > 24)
2243 newColours = new java.awt.Color[23];
2244 for (int i = 0; i < 23; i++)
2246 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2247 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2249 ucs.setLowerCaseColours(newColours);
2256 * contains last error message (if any) encountered by XML loader.
2258 String errorMessage = null;
2261 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2262 * exceptions are raised during project XML parsing
2264 public boolean attemptversion1parse = true;
2267 * Load a jalview project archive from a jar file
2270 * - HTTP URL or filename
2272 public AlignFrame loadJalviewAlign(final String file)
2275 jalview.gui.AlignFrame af = null;
2279 // create list to store references for any new Jmol viewers created
2280 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2281 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2282 // Workaround is to make sure caller implements the JarInputStreamProvider
2284 // so we can re-open the jar input stream for each entry.
2286 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2287 af = loadJalviewAlign(jprovider);
2289 } catch (MalformedURLException e)
2291 errorMessage = "Invalid URL format for '" + file + "'";
2297 SwingUtilities.invokeAndWait(new Runnable()
2302 setLoadingFinishedForNewStructureViewers();
2305 } catch (Exception x)
2307 System.err.println("Error loading alignment: " + x.getMessage());
2313 private jarInputStreamProvider createjarInputStreamProvider(
2314 final String file) throws MalformedURLException
2317 errorMessage = null;
2318 uniqueSetSuffix = null;
2320 viewportsAdded.clear();
2321 frefedSequence = null;
2323 if (file.startsWith("http://"))
2325 url = new URL(file);
2327 final URL _url = url;
2328 return new jarInputStreamProvider()
2332 public JarInputStream getJarInputStream() throws IOException
2336 return new JarInputStream(_url.openStream());
2340 return new JarInputStream(new FileInputStream(file));
2345 public String getFilename()
2353 * Recover jalview session from a jalview project archive. Caller may
2354 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2355 * themselves. Any null fields will be initialised with default values,
2356 * non-null fields are left alone.
2361 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2363 errorMessage = null;
2364 if (uniqueSetSuffix == null)
2366 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2368 if (seqRefIds == null)
2372 AlignFrame af = null, _af = null;
2373 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2374 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2375 final String file = jprovider.getFilename();
2378 JarInputStream jin = null;
2379 JarEntry jarentry = null;
2384 jin = jprovider.getJarInputStream();
2385 for (int i = 0; i < entryCount; i++)
2387 jarentry = jin.getNextJarEntry();
2390 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2392 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2393 JalviewModel object = new JalviewModel();
2395 Unmarshaller unmar = new Unmarshaller(object);
2396 unmar.setValidation(false);
2397 object = (JalviewModel) unmar.unmarshal(in);
2398 if (true) // !skipViewport(object))
2400 _af = loadFromObject(object, file, true, jprovider);
2402 && object.getJalviewModelSequence().getViewportCount() > 0)
2406 // store a reference to the first view
2409 if (_af.viewport.isGatherViewsHere())
2411 // if this is a gathered view, keep its reference since
2412 // after gathering views, only this frame will remain
2414 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2416 // Save dataset to register mappings once all resolved
2417 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2418 af.viewport.getAlignment().getDataset());
2423 else if (jarentry != null)
2425 // Some other file here.
2428 } while (jarentry != null);
2429 resolveFrefedSequences();
2430 } catch (IOException ex)
2432 ex.printStackTrace();
2433 errorMessage = "Couldn't locate Jalview XML file : " + file;
2434 System.err.println("Exception whilst loading jalview XML file : "
2436 } catch (Exception ex)
2438 System.err.println("Parsing as Jalview Version 2 file failed.");
2439 ex.printStackTrace(System.err);
2440 if (attemptversion1parse)
2442 // Is Version 1 Jar file?
2445 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2446 } catch (Exception ex2)
2448 System.err.println("Exception whilst loading as jalviewXMLV1:");
2449 ex2.printStackTrace();
2453 if (Desktop.instance != null)
2455 Desktop.instance.stopLoading();
2459 System.out.println("Successfully loaded archive file");
2462 ex.printStackTrace();
2464 System.err.println("Exception whilst loading jalview XML file : "
2466 } catch (OutOfMemoryError e)
2468 // Don't use the OOM Window here
2469 errorMessage = "Out of memory loading jalview XML file";
2470 System.err.println("Out of memory whilst loading jalview XML file");
2471 e.printStackTrace();
2475 * Regather multiple views (with the same sequence set id) to the frame (if
2476 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2477 * views instead of separate frames. Note this doesn't restore a state where
2478 * some expanded views in turn have tabbed views - the last "first tab" read
2479 * in will play the role of gatherer for all.
2481 for (AlignFrame fr : gatherToThisFrame.values())
2483 Desktop.instance.gatherViews(fr);
2486 restoreSplitFrames();
2487 for (AlignmentI ds : importedDatasets.keySet())
2489 if (ds.getCodonFrames() != null)
2491 StructureSelectionManager.getStructureSelectionManager(
2492 Desktop.instance).registerMappings(ds.getCodonFrames());
2495 if (errorMessage != null)
2500 if (Desktop.instance != null)
2502 Desktop.instance.stopLoading();
2509 * Try to reconstruct and display SplitFrame windows, where each contains
2510 * complementary dna and protein alignments. Done by pairing up AlignFrame
2511 * objects (created earlier) which have complementary viewport ids associated.
2513 protected void restoreSplitFrames()
2515 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2516 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2517 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2520 * Identify the DNA alignments
2522 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2525 AlignFrame af = candidate.getValue();
2526 if (af.getViewport().getAlignment().isNucleotide())
2528 dna.put(candidate.getKey().getId(), af);
2533 * Try to match up the protein complements
2535 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2538 AlignFrame af = candidate.getValue();
2539 if (!af.getViewport().getAlignment().isNucleotide())
2541 String complementId = candidate.getKey().getComplementId();
2542 // only non-null complements should be in the Map
2543 if (complementId != null && dna.containsKey(complementId))
2545 final AlignFrame dnaFrame = dna.get(complementId);
2546 SplitFrame sf = createSplitFrame(dnaFrame, af);
2547 addedToSplitFrames.add(dnaFrame);
2548 addedToSplitFrames.add(af);
2549 dnaFrame.setMenusForViewport();
2550 af.setMenusForViewport();
2551 if (af.viewport.isGatherViewsHere())
2560 * Open any that we failed to pair up (which shouldn't happen!) as
2561 * standalone AlignFrame's.
2563 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2566 AlignFrame af = candidate.getValue();
2567 if (!addedToSplitFrames.contains(af))
2569 Viewport view = candidate.getKey();
2570 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2572 af.setMenusForViewport();
2573 System.err.println("Failed to restore view " + view.getTitle()
2574 + " to split frame");
2579 * Gather back into tabbed views as flagged.
2581 for (SplitFrame sf : gatherTo)
2583 Desktop.instance.gatherViews(sf);
2586 splitFrameCandidates.clear();
2590 * Construct and display one SplitFrame holding DNA and protein alignments.
2593 * @param proteinFrame
2596 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2597 AlignFrame proteinFrame)
2599 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2600 String title = MessageManager.getString("label.linked_view_title");
2601 int width = (int) dnaFrame.getBounds().getWidth();
2602 int height = (int) (dnaFrame.getBounds().getHeight()
2603 + proteinFrame.getBounds().getHeight() + 50);
2606 * SplitFrame location is saved to both enclosed frames
2608 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2609 Desktop.addInternalFrame(splitFrame, title, width, height);
2612 * And compute cDNA consensus (couldn't do earlier with consensus as
2613 * mappings were not yet present)
2615 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2621 * check errorMessage for a valid error message and raise an error box in the
2622 * GUI or write the current errorMessage to stderr and then clear the error
2625 protected void reportErrors()
2627 reportErrors(false);
2630 protected void reportErrors(final boolean saving)
2632 if (errorMessage != null)
2634 final String finalErrorMessage = errorMessage;
2637 javax.swing.SwingUtilities.invokeLater(new Runnable()
2642 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2643 finalErrorMessage, "Error "
2644 + (saving ? "saving" : "loading")
2645 + " Jalview file", JvOptionPane.WARNING_MESSAGE);
2651 System.err.println("Problem loading Jalview file: " + errorMessage);
2654 errorMessage = null;
2657 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2660 * when set, local views will be updated from view stored in JalviewXML
2661 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2662 * sync if this is set to true.
2664 private final boolean updateLocalViews = false;
2667 * Returns the path to a temporary file holding the PDB file for the given PDB
2668 * id. The first time of asking, searches for a file of that name in the
2669 * Jalview project jar, and copies it to a new temporary file. Any repeat
2670 * requests just return the path to the file previously created.
2676 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2679 if (alreadyLoadedPDB.containsKey(pdbId))
2681 return alreadyLoadedPDB.get(pdbId).toString();
2684 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2686 if (tempFile != null)
2688 alreadyLoadedPDB.put(pdbId, tempFile);
2694 * Copies the jar entry of given name to a new temporary file and returns the
2695 * path to the file, or null if the entry is not found.
2698 * @param jarEntryName
2700 * a prefix for the temporary file name, must be at least three
2703 * null or original file - so new file can be given the same suffix
2707 protected String copyJarEntry(jarInputStreamProvider jprovider,
2708 String jarEntryName, String prefix, String origFile)
2710 BufferedReader in = null;
2711 PrintWriter out = null;
2712 String suffix = ".tmp";
2713 if (origFile == null)
2715 origFile = jarEntryName;
2717 int sfpos = origFile.lastIndexOf(".");
2718 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2720 suffix = "." + origFile.substring(sfpos + 1);
2724 JarInputStream jin = jprovider.getJarInputStream();
2726 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2727 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2728 * FileInputStream(jprovider)); }
2731 JarEntry entry = null;
2734 entry = jin.getNextJarEntry();
2735 } while (entry != null && !entry.getName().equals(jarEntryName));
2738 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2739 File outFile = File.createTempFile(prefix, suffix);
2740 outFile.deleteOnExit();
2741 out = new PrintWriter(new FileOutputStream(outFile));
2744 while ((data = in.readLine()) != null)
2749 String t = outFile.getAbsolutePath();
2754 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2756 } catch (Exception ex)
2758 ex.printStackTrace();
2766 } catch (IOException e)
2780 private class JvAnnotRow
2782 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2789 * persisted version of annotation row from which to take vis properties
2791 public jalview.datamodel.AlignmentAnnotation template;
2794 * original position of the annotation row in the alignment
2800 * Load alignment frame from jalview XML DOM object
2805 * filename source string
2806 * @param loadTreesAndStructures
2807 * when false only create Viewport
2809 * data source provider
2810 * @return alignment frame created from view stored in DOM
2812 AlignFrame loadFromObject(JalviewModel object, String file,
2813 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2815 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2816 Sequence[] vamsasSeq = vamsasSet.getSequence();
2818 JalviewModelSequence jms = object.getJalviewModelSequence();
2820 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2823 // ////////////////////////////////
2826 List<SequenceI> hiddenSeqs = null;
2828 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2830 boolean multipleView = false;
2831 SequenceI referenceseqForView = null;
2832 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2833 int vi = 0; // counter in vamsasSeq array
2834 for (int i = 0; i < jseqs.length; i++)
2836 String seqId = jseqs[i].getId();
2838 SequenceI tmpSeq = seqRefIds.get(seqId);
2841 if (!incompleteSeqs.containsKey(seqId))
2843 // may not need this check, but keep it for at least 2.9,1 release
2844 if (tmpSeq.getStart() != jseqs[i].getStart()
2845 || tmpSeq.getEnd() != jseqs[i].getEnd())
2848 .println("Warning JAL-2154 regression: updating start/end for sequence "
2849 + tmpSeq.toString() + " to " + jseqs[i]);
2854 incompleteSeqs.remove(seqId);
2856 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2858 // most likely we are reading a dataset XML document so
2859 // update from vamsasSeq section of XML for this sequence
2860 tmpSeq.setName(vamsasSeq[vi].getName());
2861 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2862 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2867 // reading multiple views, so vamsasSeq set is a subset of JSeq
2868 multipleView = true;
2870 tmpSeq.setStart(jseqs[i].getStart());
2871 tmpSeq.setEnd(jseqs[i].getEnd());
2872 tmpseqs.add(tmpSeq);
2876 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2877 vamsasSeq[vi].getSequence());
2878 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2879 tmpSeq.setStart(jseqs[i].getStart());
2880 tmpSeq.setEnd(jseqs[i].getEnd());
2881 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2882 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2883 tmpseqs.add(tmpSeq);
2887 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2889 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2892 if (jseqs[i].getHidden())
2894 if (hiddenSeqs == null)
2896 hiddenSeqs = new ArrayList<SequenceI>();
2899 hiddenSeqs.add(tmpSeq);
2904 // Create the alignment object from the sequence set
2905 // ///////////////////////////////
2906 SequenceI[] orderedSeqs = tmpseqs
2907 .toArray(new SequenceI[tmpseqs.size()]);
2909 AlignmentI al = null;
2910 // so we must create or recover the dataset alignment before going further
2911 // ///////////////////////////////
2912 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2914 // older jalview projects do not have a dataset - so creat alignment and
2916 al = new Alignment(orderedSeqs);
2917 al.setDataset(null);
2921 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2924 // we are importing a dataset record, so
2925 // recover reference to an alignment already materialsed as dataset
2926 al = getDatasetFor(vamsasSet.getDatasetId());
2930 // materialse the alignment
2931 al = new Alignment(orderedSeqs);
2935 addDatasetRef(vamsasSet.getDatasetId(), al);
2938 // finally, verify all data in vamsasSet is actually present in al
2939 // passing on flag indicating if it is actually a stored dataset
2940 recoverDatasetFor(vamsasSet, al, isdsal);
2943 if (referenceseqForView != null)
2945 al.setSeqrep(referenceseqForView);
2947 // / Add the alignment properties
2948 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2950 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2951 al.setProperty(ssp.getKey(), ssp.getValue());
2954 // ///////////////////////////////
2956 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2959 // load sequence features, database references and any associated PDB
2960 // structures for the alignment
2962 // prior to 2.10, this part would only be executed the first time a
2963 // sequence was encountered, but not afterwards.
2964 // now, for 2.10 projects, this is also done if the xml doc includes
2965 // dataset sequences not actually present in any particular view.
2967 for (int i = 0; i < vamsasSeq.length; i++)
2969 if (jseqs[i].getFeaturesCount() > 0)
2971 Features[] features = jseqs[i].getFeatures();
2972 for (int f = 0; f < features.length; f++)
2974 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2975 features[f].getType(), features[f].getDescription(),
2976 features[f].getStatus(), features[f].getBegin(),
2977 features[f].getEnd(), features[f].getFeatureGroup());
2979 sf.setScore(features[f].getScore());
2980 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2982 OtherData keyValue = features[f].getOtherData(od);
2983 if (keyValue.getKey().startsWith("LINK"))
2985 sf.addLink(keyValue.getValue());
2989 sf.setValue(keyValue.getKey(), keyValue.getValue());
2993 // adds feature to datasequence's feature set (since Jalview 2.10)
2994 al.getSequenceAt(i).addSequenceFeature(sf);
2997 if (vamsasSeq[i].getDBRefCount() > 0)
2999 // adds dbrefs to datasequence's set (since Jalview 2.10)
3001 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
3002 : al.getSequenceAt(i).getDatasetSequence(),
3005 if (jseqs[i].getPdbidsCount() > 0)
3007 Pdbids[] ids = jseqs[i].getPdbids();
3008 for (int p = 0; p < ids.length; p++)
3010 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
3011 entry.setId(ids[p].getId());
3012 if (ids[p].getType() != null)
3014 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3016 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3020 entry.setType(PDBEntry.Type.FILE);
3023 // jprovider is null when executing 'New View'
3024 if (ids[p].getFile() != null && jprovider != null)
3026 if (!pdbloaded.containsKey(ids[p].getFile()))
3028 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3033 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3036 if (ids[p].getPdbentryItem() != null)
3038 for (PdbentryItem item : ids[p].getPdbentryItem())
3040 for (Property pr : item.getProperty())
3042 entry.setProperty(pr.getName(), pr.getValue());
3046 StructureSelectionManager.getStructureSelectionManager(
3047 Desktop.instance).registerPDBEntry(entry);
3048 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3049 if (al.getSequenceAt(i).getDatasetSequence() != null)
3051 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3055 al.getSequenceAt(i).addPDBId(entry);
3060 } // end !multipleview
3062 // ///////////////////////////////
3063 // LOAD SEQUENCE MAPPINGS
3065 if (vamsasSet.getAlcodonFrameCount() > 0)
3067 // TODO Potentially this should only be done once for all views of an
3069 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3070 for (int i = 0; i < alc.length; i++)
3072 AlignedCodonFrame cf = new AlignedCodonFrame();
3073 if (alc[i].getAlcodMapCount() > 0)
3075 AlcodMap[] maps = alc[i].getAlcodMap();
3076 for (int m = 0; m < maps.length; m++)
3078 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3080 jalview.datamodel.Mapping mapping = null;
3081 // attach to dna sequence reference.
3082 if (maps[m].getMapping() != null)
3084 mapping = addMapping(maps[m].getMapping());
3085 if (dnaseq != null && mapping.getTo() != null)
3087 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3092 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3097 al.addCodonFrame(cf);
3102 // ////////////////////////////////
3104 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3107 * store any annotations which forward reference a group's ID
3109 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3111 if (vamsasSet.getAnnotationCount() > 0)
3113 Annotation[] an = vamsasSet.getAnnotation();
3115 for (int i = 0; i < an.length; i++)
3117 Annotation annotation = an[i];
3120 * test if annotation is automatically calculated for this view only
3122 boolean autoForView = false;
3123 if (annotation.getLabel().equals("Quality")
3124 || annotation.getLabel().equals("Conservation")
3125 || annotation.getLabel().equals("Consensus"))
3127 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3129 if (!annotation.hasAutoCalculated())
3131 annotation.setAutoCalculated(true);
3135 || (annotation.hasAutoCalculated() && annotation
3136 .isAutoCalculated()))
3138 // remove ID - we don't recover annotation from other views for
3139 // view-specific annotation
3140 annotation.setId(null);
3143 // set visiblity for other annotation in this view
3144 String annotationId = annotation.getId();
3145 if (annotationId != null && annotationIds.containsKey(annotationId))
3147 AlignmentAnnotation jda = annotationIds.get(annotationId);
3148 // in principle Visible should always be true for annotation displayed
3149 // in multiple views
3150 if (annotation.hasVisible())
3152 jda.visible = annotation.getVisible();
3155 al.addAnnotation(jda);
3159 // Construct new annotation from model.
3160 AnnotationElement[] ae = annotation.getAnnotationElement();
3161 jalview.datamodel.Annotation[] anot = null;
3162 java.awt.Color firstColour = null;
3164 if (!annotation.getScoreOnly())
3166 anot = new jalview.datamodel.Annotation[al.getWidth()];
3167 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3169 anpos = ae[aa].getPosition();
3171 if (anpos >= anot.length)
3176 anot[anpos] = new jalview.datamodel.Annotation(
3178 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3179 (ae[aa].getSecondaryStructure() == null || ae[aa]
3180 .getSecondaryStructure().length() == 0) ? ' '
3181 : ae[aa].getSecondaryStructure().charAt(0),
3185 // JBPNote: Consider verifying dataflow for IO of secondary
3186 // structure annotation read from Stockholm files
3187 // this was added to try to ensure that
3188 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3190 // anot[ae[aa].getPosition()].displayCharacter = "";
3192 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3193 if (firstColour == null)
3195 firstColour = anot[anpos].colour;
3199 jalview.datamodel.AlignmentAnnotation jaa = null;
3201 if (annotation.getGraph())
3203 float llim = 0, hlim = 0;
3204 // if (autoForView || an[i].isAutoCalculated()) {
3207 jaa = new jalview.datamodel.AlignmentAnnotation(
3208 annotation.getLabel(), annotation.getDescription(), anot,
3209 llim, hlim, annotation.getGraphType());
3211 jaa.graphGroup = annotation.getGraphGroup();
3212 jaa._linecolour = firstColour;
3213 if (annotation.getThresholdLine() != null)
3215 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3216 .getThresholdLine().getValue(), annotation
3217 .getThresholdLine().getLabel(), new java.awt.Color(
3218 annotation.getThresholdLine().getColour())));
3221 if (autoForView || annotation.isAutoCalculated())
3223 // Hardwire the symbol display line to ensure that labels for
3224 // histograms are displayed
3230 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3231 an[i].getDescription(), anot);
3232 jaa._linecolour = firstColour;
3234 // register new annotation
3235 if (an[i].getId() != null)
3237 annotationIds.put(an[i].getId(), jaa);
3238 jaa.annotationId = an[i].getId();
3240 // recover sequence association
3241 String sequenceRef = an[i].getSequenceRef();
3242 if (sequenceRef != null)
3244 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3245 SequenceI sequence = seqRefIds.get(sequenceRef);
3246 if (sequence == null)
3248 // in pre-2.9 projects sequence ref is to sequence name
3249 sequence = al.findName(sequenceRef);
3251 if (sequence != null)
3253 jaa.createSequenceMapping(sequence, 1, true);
3254 sequence.addAlignmentAnnotation(jaa);
3257 // and make a note of any group association
3258 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3260 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3261 .get(an[i].getGroupRef());
3264 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3265 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3270 if (an[i].hasScore())
3272 jaa.setScore(an[i].getScore());
3274 if (an[i].hasVisible())
3276 jaa.visible = an[i].getVisible();
3279 if (an[i].hasCentreColLabels())
3281 jaa.centreColLabels = an[i].getCentreColLabels();
3284 if (an[i].hasScaleColLabels())
3286 jaa.scaleColLabel = an[i].getScaleColLabels();
3288 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3290 // newer files have an 'autoCalculated' flag and store calculation
3291 // state in viewport properties
3292 jaa.autoCalculated = true; // means annotation will be marked for
3293 // update at end of load.
3295 if (an[i].hasGraphHeight())
3297 jaa.graphHeight = an[i].getGraphHeight();
3299 if (an[i].hasBelowAlignment())
3301 jaa.belowAlignment = an[i].isBelowAlignment();
3303 jaa.setCalcId(an[i].getCalcId());
3304 if (an[i].getPropertyCount() > 0)
3306 for (jalview.schemabinding.version2.Property prop : an[i]
3309 jaa.setProperty(prop.getName(), prop.getValue());
3312 if (jaa.autoCalculated)
3314 autoAlan.add(new JvAnnotRow(i, jaa));
3317 // if (!autoForView)
3319 // add autocalculated group annotation and any user created annotation
3321 al.addAnnotation(jaa);
3325 // ///////////////////////
3327 // Create alignment markup and styles for this view
3328 if (jms.getJGroupCount() > 0)
3330 JGroup[] groups = jms.getJGroup();
3331 boolean addAnnotSchemeGroup = false;
3332 for (int i = 0; i < groups.length; i++)
3334 JGroup jGroup = groups[i];
3335 ColourSchemeI cs = null;
3336 if (jGroup.getColour() != null)
3338 if (jGroup.getColour().startsWith("ucs"))
3340 cs = getUserColourScheme(jms, jGroup.getColour());
3342 else if (jGroup.getColour().equals("AnnotationColourGradient")
3343 && jGroup.getAnnotationColours() != null)
3345 addAnnotSchemeGroup = true;
3349 cs = ColourSchemeProperty.getColourScheme(al, jGroup.getColour());
3352 int pidThreshold = jGroup.getPidThreshold();
3354 Vector<SequenceI> seqs = new Vector<SequenceI>();
3356 for (int s = 0; s < jGroup.getSeqCount(); s++)
3358 String seqId = jGroup.getSeq(s) + "";
3359 SequenceI ts = seqRefIds.get(seqId);
3363 seqs.addElement(ts);
3367 if (seqs.size() < 1)
3372 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3373 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3374 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3375 sg.getGroupColourScheme().setThreshold(pidThreshold, true);
3376 sg.getGroupColourScheme().setConservationInc(jGroup.getConsThreshold());
3377 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3379 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3380 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3381 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3382 .isShowUnconserved() : false);
3383 sg.thresholdTextColour = jGroup.getTextColThreshold();
3384 if (jGroup.hasShowConsensusHistogram())
3386 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3389 if (jGroup.hasShowSequenceLogo())
3391 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3393 if (jGroup.hasNormaliseSequenceLogo())
3395 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3397 if (jGroup.hasIgnoreGapsinConsensus())
3399 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3401 if (jGroup.getConsThreshold() != 0)
3403 Conservation c = new Conservation("All", sg.getSequences(null),
3404 0, sg.getWidth() - 1);
3406 c.verdict(false, 25);
3407 sg.cs.setConservation(c);
3410 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3412 // re-instate unique group/annotation row reference
3413 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3417 for (AlignmentAnnotation jaa : jaal)
3420 if (jaa.autoCalculated)
3422 // match up and try to set group autocalc alignment row for this
3424 if (jaa.label.startsWith("Consensus for "))
3426 sg.setConsensus(jaa);
3428 // match up and try to set group autocalc alignment row for this
3430 if (jaa.label.startsWith("Conservation for "))
3432 sg.setConservationRow(jaa);
3439 if (addAnnotSchemeGroup)
3441 // reconstruct the annotation colourscheme
3442 sg.setColourScheme(constructAnnotationColour(
3443 jGroup.getAnnotationColours(), null, al, jms, false));
3449 // only dataset in this model, so just return.
3452 // ///////////////////////////////
3455 // If we just load in the same jar file again, the sequenceSetId
3456 // will be the same, and we end up with multiple references
3457 // to the same sequenceSet. We must modify this id on load
3458 // so that each load of the file gives a unique id
3459 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3460 String viewId = (view.getId() == null ? null : view.getId()
3462 AlignFrame af = null;
3463 AlignViewport av = null;
3464 // now check to see if we really need to create a new viewport.
3465 if (multipleView && viewportsAdded.size() == 0)
3467 // We recovered an alignment for which a viewport already exists.
3468 // TODO: fix up any settings necessary for overlaying stored state onto
3469 // state recovered from another document. (may not be necessary).
3470 // we may need a binding from a viewport in memory to one recovered from
3472 // and then recover its containing af to allow the settings to be applied.
3473 // TODO: fix for vamsas demo
3475 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3477 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3478 if (seqsetobj != null)
3480 if (seqsetobj instanceof String)
3482 uniqueSeqSetId = (String) seqsetobj;
3484 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3490 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3496 * indicate that annotation colours are applied across all groups (pre
3497 * Jalview 2.8.1 behaviour)
3499 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3500 "2.8.1", object.getVersion());
3502 AlignmentPanel ap = null;
3503 boolean isnewview = true;
3506 // Check to see if this alignment already has a view id == viewId
3507 jalview.gui.AlignmentPanel views[] = Desktop
3508 .getAlignmentPanels(uniqueSeqSetId);
3509 if (views != null && views.length > 0)
3511 for (int v = 0; v < views.length; v++)
3513 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3515 // recover the existing alignpanel, alignframe, viewport
3516 af = views[v].alignFrame;
3519 // TODO: could even skip resetting view settings if we don't want to
3520 // change the local settings from other jalview processes
3529 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3530 uniqueSeqSetId, viewId, autoAlan);
3536 * Load any trees, PDB structures and viewers
3538 * Not done if flag is false (when this method is used for New View)
3540 if (loadTreesAndStructures)
3542 loadTrees(jms, view, af, av, ap);
3543 loadPDBStructures(jprovider, jseqs, af, ap);
3544 loadRnaViewers(jprovider, jseqs, ap);
3546 // and finally return.
3551 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3552 * panel is restored from separate jar entries, two (gapped and trimmed) per
3553 * sequence and secondary structure.
3555 * Currently each viewer shows just one sequence and structure (gapped and
3556 * trimmed), however this method is designed to support multiple sequences or
3557 * structures in viewers if wanted in future.
3563 private void loadRnaViewers(jarInputStreamProvider jprovider,
3564 JSeq[] jseqs, AlignmentPanel ap)
3567 * scan the sequences for references to viewers; create each one the first
3568 * time it is referenced, add Rna models to existing viewers
3570 for (JSeq jseq : jseqs)
3572 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3574 RnaViewer viewer = jseq.getRnaViewer(i);
3575 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3576 uniqueSetSuffix, ap);
3578 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3580 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3581 SequenceI seq = seqRefIds.get(jseq.getId());
3582 AlignmentAnnotation ann = this.annotationIds.get(ss
3583 .getAnnotationId());
3586 * add the structure to the Varna display (with session state copied
3587 * from the jar to a temporary file)
3589 boolean gapped = ss.isGapped();
3590 String rnaTitle = ss.getTitle();
3591 String sessionState = ss.getViewerState();
3592 String tempStateFile = copyJarEntry(jprovider, sessionState,
3594 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3595 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3597 appVarna.setInitialSelection(viewer.getSelectedRna());
3603 * Locate and return an already instantiated matching AppVarna, or create one
3607 * @param viewIdSuffix
3611 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3612 String viewIdSuffix, AlignmentPanel ap)
3615 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3616 * if load is repeated
3618 String postLoadId = viewer.getViewId() + viewIdSuffix;
3619 for (JInternalFrame frame : getAllFrames())
3621 if (frame instanceof AppVarna)
3623 AppVarna varna = (AppVarna) frame;
3624 if (postLoadId.equals(varna.getViewId()))
3626 // this viewer is already instantiated
3627 // could in future here add ap as another 'parent' of the
3628 // AppVarna window; currently just 1-to-many
3635 * viewer not found - make it
3637 RnaViewerModel model = new RnaViewerModel(postLoadId,
3638 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3639 viewer.getWidth(), viewer.getHeight(),
3640 viewer.getDividerLocation());
3641 AppVarna varna = new AppVarna(model, ap);
3647 * Load any saved trees
3655 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3656 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3658 // TODO result of automated refactoring - are all these parameters needed?
3661 for (int t = 0; t < jms.getTreeCount(); t++)
3664 Tree tree = jms.getTree(t);
3666 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3669 tp = af.ShowNewickTree(
3670 new jalview.io.NewickFile(tree.getNewick()),
3671 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3672 tree.getXpos(), tree.getYpos());
3673 if (tree.getId() != null)
3675 // perhaps bind the tree id to something ?
3680 // update local tree attributes ?
3681 // TODO: should check if tp has been manipulated by user - if so its
3682 // settings shouldn't be modified
3683 tp.setTitle(tree.getTitle());
3684 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3685 .getWidth(), tree.getHeight()));
3686 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3689 tp.treeCanvas.av = av; // af.viewport;
3690 tp.treeCanvas.ap = ap; // af.alignPanel;
3695 warn("There was a problem recovering stored Newick tree: \n"
3696 + tree.getNewick());
3700 tp.fitToWindow.setState(tree.getFitToWindow());
3701 tp.fitToWindow_actionPerformed(null);
3703 if (tree.getFontName() != null)
3705 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3706 .getFontStyle(), tree.getFontSize()));
3710 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3711 .getFontStyle(), tree.getFontSize()));
3714 tp.showPlaceholders(tree.getMarkUnlinked());
3715 tp.showBootstrap(tree.getShowBootstrap());
3716 tp.showDistances(tree.getShowDistances());
3718 tp.treeCanvas.threshold = tree.getThreshold();
3720 if (tree.getCurrentTree())
3722 af.viewport.setCurrentTree(tp.getTree());
3726 } catch (Exception ex)
3728 ex.printStackTrace();
3733 * Load and link any saved structure viewers.
3740 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3741 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3744 * Run through all PDB ids on the alignment, and collect mappings between
3745 * distinct view ids and all sequences referring to that view.
3747 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3749 for (int i = 0; i < jseqs.length; i++)
3751 if (jseqs[i].getPdbidsCount() > 0)
3753 Pdbids[] ids = jseqs[i].getPdbids();
3754 for (int p = 0; p < ids.length; p++)
3756 final int structureStateCount = ids[p].getStructureStateCount();
3757 for (int s = 0; s < structureStateCount; s++)
3759 // check to see if we haven't already created this structure view
3760 final StructureState structureState = ids[p]
3761 .getStructureState(s);
3762 String sviewid = (structureState.getViewId() == null) ? null
3763 : structureState.getViewId() + uniqueSetSuffix;
3764 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3765 // Originally : ids[p].getFile()
3766 // : TODO: verify external PDB file recovery still works in normal
3767 // jalview project load
3768 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3770 jpdb.setId(ids[p].getId());
3772 int x = structureState.getXpos();
3773 int y = structureState.getYpos();
3774 int width = structureState.getWidth();
3775 int height = structureState.getHeight();
3777 // Probably don't need to do this anymore...
3778 // Desktop.desktop.getComponentAt(x, y);
3779 // TODO: NOW: check that this recovers the PDB file correctly.
3780 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3782 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3784 if (sviewid == null)
3786 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3789 if (!structureViewers.containsKey(sviewid))
3791 structureViewers.put(sviewid,
3792 new StructureViewerModel(x, y, width, height, false,
3793 false, true, structureState.getViewId(),
3794 structureState.getType()));
3795 // Legacy pre-2.7 conversion JAL-823 :
3796 // do not assume any view has to be linked for colour by
3800 // assemble String[] { pdb files }, String[] { id for each
3801 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3802 // seqs_file 2}, boolean[] {
3803 // linkAlignPanel,superposeWithAlignpanel}} from hash
3804 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3805 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3806 | (structureState.hasAlignwithAlignPanel() ? structureState
3807 .getAlignwithAlignPanel() : false));
3810 * Default colour by linked panel to false if not specified (e.g.
3811 * for pre-2.7 projects)
3813 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3814 colourWithAlignPanel |= (structureState
3815 .hasColourwithAlignPanel() ? structureState
3816 .getColourwithAlignPanel() : false);
3817 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3820 * Default colour by viewer to true if not specified (e.g. for
3823 boolean colourByViewer = jmoldat.isColourByViewer();
3824 colourByViewer &= structureState.hasColourByJmol() ? structureState
3825 .getColourByJmol() : true;
3826 jmoldat.setColourByViewer(colourByViewer);
3828 if (jmoldat.getStateData().length() < structureState
3829 .getContent().length())
3832 jmoldat.setStateData(structureState.getContent());
3835 if (ids[p].getFile() != null)
3837 File mapkey = new File(ids[p].getFile());
3838 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3839 if (seqstrmaps == null)
3841 jmoldat.getFileData().put(
3843 seqstrmaps = jmoldat.new StructureData(pdbFile,
3846 if (!seqstrmaps.getSeqList().contains(seq))
3848 seqstrmaps.getSeqList().add(seq);
3854 errorMessage = ("The Jmol views in this project were imported\nfrom an older version of Jalview.\nPlease review the sequence colour associations\nin the Colour by section of the Jmol View menu.\n\nIn the case of problems, see note at\nhttp://issues.jalview.org/browse/JAL-747");
3861 // Instantiate the associated structure views
3862 for (Entry<String, StructureViewerModel> entry : structureViewers
3867 createOrLinkStructureViewer(entry, af, ap, jprovider);
3868 } catch (Exception e)
3870 System.err.println("Error loading structure viewer: "
3872 // failed - try the next one
3884 protected void createOrLinkStructureViewer(
3885 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3886 AlignmentPanel ap, jarInputStreamProvider jprovider)
3888 final StructureViewerModel stateData = viewerData.getValue();
3891 * Search for any viewer windows already open from other alignment views
3892 * that exactly match the stored structure state
3894 StructureViewerBase comp = findMatchingViewer(viewerData);
3898 linkStructureViewer(ap, comp, stateData);
3903 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3904 * "viewer_"+stateData.viewId
3906 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3908 createChimeraViewer(viewerData, af, jprovider);
3913 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3915 createJmolViewer(viewerData, af, jprovider);
3920 * Create a new Chimera viewer.
3926 protected void createChimeraViewer(
3927 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3928 jarInputStreamProvider jprovider)
3930 StructureViewerModel data = viewerData.getValue();
3931 String chimeraSessionFile = data.getStateData();
3934 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3936 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3937 * 'uniquified' sviewid used to reconstruct the viewer here
3939 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3940 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3943 Set<Entry<File, StructureData>> fileData = data.getFileData()
3945 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3946 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3947 for (Entry<File, StructureData> pdb : fileData)
3949 String filePath = pdb.getValue().getFilePath();
3950 String pdbId = pdb.getValue().getPdbId();
3951 // pdbs.add(new PDBEntry(filePath, pdbId));
3952 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3953 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3954 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3958 boolean colourByChimera = data.isColourByViewer();
3959 boolean colourBySequence = data.isColourWithAlignPanel();
3961 // TODO use StructureViewer as a factory here, see JAL-1761
3962 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3963 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3965 String newViewId = viewerData.getKey();
3967 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3968 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3969 colourBySequence, newViewId);
3970 cvf.setSize(data.getWidth(), data.getHeight());
3971 cvf.setLocation(data.getX(), data.getY());
3975 * Create a new Jmol window. First parse the Jmol state to translate filenames
3976 * loaded into the view, and record the order in which files are shown in the
3977 * Jmol view, so we can add the sequence mappings in same order.
3983 protected void createJmolViewer(
3984 final Entry<String, StructureViewerModel> viewerData,
3985 AlignFrame af, jarInputStreamProvider jprovider)
3987 final StructureViewerModel svattrib = viewerData.getValue();
3988 String state = svattrib.getStateData();
3991 * Pre-2.9: state element value is the Jmol state string
3993 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3996 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3998 state = readJarEntry(jprovider,
3999 getViewerJarEntryName(svattrib.getViewId()));
4002 List<String> pdbfilenames = new ArrayList<String>();
4003 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
4004 List<String> pdbids = new ArrayList<String>();
4005 StringBuilder newFileLoc = new StringBuilder(64);
4006 int cp = 0, ncp, ecp;
4007 Map<File, StructureData> oldFiles = svattrib.getFileData();
4008 while ((ncp = state.indexOf("load ", cp)) > -1)
4012 // look for next filename in load statement
4013 newFileLoc.append(state.substring(cp,
4014 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4015 String oldfilenam = state.substring(ncp,
4016 ecp = state.indexOf("\"", ncp));
4017 // recover the new mapping data for this old filename
4018 // have to normalize filename - since Jmol and jalview do
4020 // translation differently.
4021 StructureData filedat = oldFiles.get(new File(oldfilenam));
4022 if (filedat == null)
4024 String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
4025 filedat = oldFiles.get(new File(reformatedOldFilename));
4027 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4028 pdbfilenames.add(filedat.getFilePath());
4029 pdbids.add(filedat.getPdbId());
4030 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4031 newFileLoc.append("\"");
4032 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4033 // look for next file statement.
4034 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4038 // just append rest of state
4039 newFileLoc.append(state.substring(cp));
4043 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4044 newFileLoc = new StringBuilder(state);
4045 newFileLoc.append("; load append ");
4046 for (File id : oldFiles.keySet())
4048 // add this and any other pdb files that should be present in
4050 StructureData filedat = oldFiles.get(id);
4051 newFileLoc.append(filedat.getFilePath());
4052 pdbfilenames.add(filedat.getFilePath());
4053 pdbids.add(filedat.getPdbId());
4054 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4055 newFileLoc.append(" \"");
4056 newFileLoc.append(filedat.getFilePath());
4057 newFileLoc.append("\"");
4060 newFileLoc.append(";");
4063 if (newFileLoc.length() == 0)
4067 int histbug = newFileLoc.indexOf("history = ");
4071 * change "history = [true|false];" to "history = [1|0];"
4074 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4075 String val = (diff == -1) ? null : newFileLoc
4076 .substring(histbug, diff);
4077 if (val != null && val.length() >= 4)
4079 if (val.contains("e")) // eh? what can it be?
4081 if (val.trim().equals("true"))
4089 newFileLoc.replace(histbug, diff, val);
4094 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4096 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4097 final SequenceI[][] sq = seqmaps
4098 .toArray(new SequenceI[seqmaps.size()][]);
4099 final String fileloc = newFileLoc.toString();
4100 final String sviewid = viewerData.getKey();
4101 final AlignFrame alf = af;
4102 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4103 svattrib.getWidth(), svattrib.getHeight());
4106 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4111 JalviewStructureDisplayI sview = null;
4114 sview = new StructureViewer(alf.alignPanel
4115 .getStructureSelectionManager()).createView(
4116 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4117 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4118 addNewStructureViewer(sview);
4119 } catch (OutOfMemoryError ex)
4121 new OOMWarning("restoring structure view for PDB id " + id,
4122 (OutOfMemoryError) ex.getCause());
4123 if (sview != null && sview.isVisible())
4125 sview.closeViewer(false);
4126 sview.setVisible(false);
4132 } catch (InvocationTargetException ex)
4134 warn("Unexpected error when opening Jmol view.", ex);
4136 } catch (InterruptedException e)
4138 // e.printStackTrace();
4144 * Generates a name for the entry in the project jar file to hold state
4145 * information for a structure viewer
4150 protected String getViewerJarEntryName(String viewId)
4152 return VIEWER_PREFIX + viewId;
4156 * Returns any open frame that matches given structure viewer data. The match
4157 * is based on the unique viewId, or (for older project versions) the frame's
4163 protected StructureViewerBase findMatchingViewer(
4164 Entry<String, StructureViewerModel> viewerData)
4166 final String sviewid = viewerData.getKey();
4167 final StructureViewerModel svattrib = viewerData.getValue();
4168 StructureViewerBase comp = null;
4169 JInternalFrame[] frames = getAllFrames();
4170 for (JInternalFrame frame : frames)
4172 if (frame instanceof StructureViewerBase)
4175 * Post jalview 2.4 schema includes structure view id
4178 && ((StructureViewerBase) frame).getViewId()
4181 comp = (StructureViewerBase) frame;
4182 break; // break added in 2.9
4185 * Otherwise test for matching position and size of viewer frame
4187 else if (frame.getX() == svattrib.getX()
4188 && frame.getY() == svattrib.getY()
4189 && frame.getHeight() == svattrib.getHeight()
4190 && frame.getWidth() == svattrib.getWidth())
4192 comp = (StructureViewerBase) frame;
4193 // no break in faint hope of an exact match on viewId
4201 * Link an AlignmentPanel to an existing structure viewer.
4206 * @param useinViewerSuperpos
4207 * @param usetoColourbyseq
4208 * @param viewerColouring
4210 protected void linkStructureViewer(AlignmentPanel ap,
4211 StructureViewerBase viewer, StructureViewerModel stateData)
4213 // NOTE: if the jalview project is part of a shared session then
4214 // view synchronization should/could be done here.
4216 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4217 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4218 final boolean viewerColouring = stateData.isColourByViewer();
4219 Map<File, StructureData> oldFiles = stateData.getFileData();
4222 * Add mapping for sequences in this view to an already open viewer
4224 final AAStructureBindingModel binding = viewer.getBinding();
4225 for (File id : oldFiles.keySet())
4227 // add this and any other pdb files that should be present in the
4229 StructureData filedat = oldFiles.get(id);
4230 String pdbFile = filedat.getFilePath();
4231 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4232 binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE);
4233 binding.addSequenceForStructFile(pdbFile, seq);
4235 // and add the AlignmentPanel's reference to the view panel
4236 viewer.addAlignmentPanel(ap);
4237 if (useinViewerSuperpos)
4239 viewer.useAlignmentPanelForSuperposition(ap);
4243 viewer.excludeAlignmentPanelForSuperposition(ap);
4245 if (usetoColourbyseq)
4247 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4251 viewer.excludeAlignmentPanelForColourbyseq(ap);
4256 * Get all frames within the Desktop.
4260 protected JInternalFrame[] getAllFrames()
4262 JInternalFrame[] frames = null;
4263 // TODO is this necessary - is it safe - risk of hanging?
4268 frames = Desktop.desktop.getAllFrames();
4269 } catch (ArrayIndexOutOfBoundsException e)
4271 // occasional No such child exceptions are thrown here...
4275 } catch (InterruptedException f)
4279 } while (frames == null);
4284 * Answers true if 'version' is equal to or later than 'supported', where each
4285 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4286 * changes. Development and test values for 'version' are leniently treated
4290 * - minimum version we are comparing against
4292 * - version of data being processsed
4295 public static boolean isVersionStringLaterThan(String supported,
4298 if (supported == null || version == null
4299 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4300 || version.equalsIgnoreCase("Test")
4301 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4303 System.err.println("Assuming project file with "
4304 + (version == null ? "null" : version)
4305 + " is compatible with Jalview version " + supported);
4310 return StringUtils.compareVersions(version, supported, "b") >= 0;
4314 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4316 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4318 if (newStructureViewers != null)
4320 sview.getBinding().setFinishedLoadingFromArchive(false);
4321 newStructureViewers.add(sview);
4325 protected void setLoadingFinishedForNewStructureViewers()
4327 if (newStructureViewers != null)
4329 for (JalviewStructureDisplayI sview : newStructureViewers)
4331 sview.getBinding().setFinishedLoadingFromArchive(true);
4333 newStructureViewers.clear();
4334 newStructureViewers = null;
4338 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4339 List<SequenceI> hiddenSeqs, AlignmentI al,
4340 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4341 String viewId, List<JvAnnotRow> autoAlan)
4343 AlignFrame af = null;
4344 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4345 uniqueSeqSetId, viewId);
4347 af.setFileName(file, FileFormat.Jalview);
4349 for (int i = 0; i < JSEQ.length; i++)
4351 af.viewport.setSequenceColour(af.viewport.getAlignment()
4352 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4357 af.getViewport().setColourByReferenceSeq(true);
4358 af.getViewport().setDisplayReferenceSeq(true);
4361 af.viewport.setGatherViewsHere(view.getGatheredViews());
4363 if (view.getSequenceSetId() != null)
4365 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4367 af.viewport.setSequenceSetId(uniqueSeqSetId);
4370 // propagate shared settings to this new view
4371 af.viewport.setHistoryList(av.getHistoryList());
4372 af.viewport.setRedoList(av.getRedoList());
4376 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4378 // TODO: check if this method can be called repeatedly without
4379 // side-effects if alignpanel already registered.
4380 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4382 // apply Hidden regions to view.
4383 if (hiddenSeqs != null)
4385 for (int s = 0; s < JSEQ.length; s++)
4387 SequenceGroup hidden = new SequenceGroup();
4388 boolean isRepresentative = false;
4389 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4391 isRepresentative = true;
4392 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4393 .getHiddenSequences(r));
4394 hidden.addSequence(sequenceToHide, false);
4395 // remove from hiddenSeqs list so we don't try to hide it twice
4396 hiddenSeqs.remove(sequenceToHide);
4398 if (isRepresentative)
4400 SequenceI representativeSequence = al.getSequenceAt(s);
4401 hidden.addSequence(representativeSequence, false);
4402 af.viewport.hideRepSequences(representativeSequence, hidden);
4406 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4408 af.viewport.hideSequence(hseqs);
4411 // recover view properties and display parameters
4412 if (view.getViewName() != null)
4414 af.viewport.viewName = view.getViewName();
4415 af.setInitialTabVisible();
4417 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4420 af.viewport.setShowAnnotation(view.getShowAnnotation());
4421 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4422 af.viewport.setThreshold(view.getPidThreshold());
4424 af.viewport.setColourText(view.getShowColourText());
4426 af.viewport.setConservationSelected(view.getConservationSelected());
4427 af.viewport.setIncrement(view.getConsThreshold());
4428 af.viewport.setShowJVSuffix(view.getShowFullId());
4429 af.viewport.setRightAlignIds(view.getRightAlignIds());
4430 af.viewport.setFont(
4431 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4432 .getFontSize()), true);
4433 ViewStyleI vs = af.viewport.getViewStyle();
4434 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4435 af.viewport.setViewStyle(vs);
4436 // TODO: allow custom charWidth/Heights to be restored by updating them
4437 // after setting font - which means set above to false
4438 af.viewport.setRenderGaps(view.getRenderGaps());
4439 af.viewport.setWrapAlignment(view.getWrapAlignment());
4440 af.viewport.setShowAnnotation(view.getShowAnnotation());
4442 af.viewport.setShowBoxes(view.getShowBoxes());
4444 af.viewport.setShowText(view.getShowText());
4446 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4447 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4448 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4449 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4450 .isShowUnconserved() : false);
4451 af.viewport.setStartRes(view.getStartRes());
4452 af.viewport.setStartSeq(view.getStartSeq());
4453 af.alignPanel.updateLayout();
4454 ColourSchemeI cs = null;
4455 // apply colourschemes
4456 if (view.getBgColour() != null)
4458 if (view.getBgColour().startsWith("ucs"))
4460 cs = getUserColourScheme(jms, view.getBgColour());
4462 else if (view.getBgColour().startsWith("Annotation"))
4464 AnnotationColours viewAnnColour = view.getAnnotationColours();
4465 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4472 cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour());
4476 af.viewport.setGlobalColourScheme(cs);
4477 af.viewport.getResidueShading().setThreshold(
4478 view.getPidThreshold(), true);
4479 af.viewport.getResidueShading().setConsensus(
4480 af.viewport.getSequenceConsensusHash());
4481 af.viewport.setColourAppliesToAllGroups(false);
4483 if (view.getConservationSelected() && cs != null)
4485 af.viewport.getResidueShading().setConservationInc(
4486 view.getConsThreshold());
4489 af.changeColour(cs);
4491 af.viewport.setColourAppliesToAllGroups(true);
4493 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4495 if (view.hasCentreColumnLabels())
4497 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4499 if (view.hasIgnoreGapsinConsensus())
4501 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4504 if (view.hasFollowHighlight())
4506 af.viewport.setFollowHighlight(view.getFollowHighlight());
4508 if (view.hasFollowSelection())
4510 af.viewport.followSelection = view.getFollowSelection();
4512 if (view.hasShowConsensusHistogram())
4514 af.viewport.setShowConsensusHistogram(view
4515 .getShowConsensusHistogram());
4519 af.viewport.setShowConsensusHistogram(true);
4521 if (view.hasShowSequenceLogo())
4523 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4527 af.viewport.setShowSequenceLogo(false);
4529 if (view.hasNormaliseSequenceLogo())
4531 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4533 if (view.hasShowDbRefTooltip())
4535 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4537 if (view.hasShowNPfeatureTooltip())
4539 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4541 if (view.hasShowGroupConsensus())
4543 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4547 af.viewport.setShowGroupConsensus(false);
4549 if (view.hasShowGroupConservation())
4551 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4555 af.viewport.setShowGroupConservation(false);
4558 // recover featre settings
4559 if (jms.getFeatureSettings() != null)
4561 FeaturesDisplayed fdi;
4562 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4563 String[] renderOrder = new String[jms.getFeatureSettings()
4564 .getSettingCount()];
4565 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4566 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4568 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4570 Setting setting = jms.getFeatureSettings().getSetting(fs);
4571 if (setting.hasMincolour())
4573 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4574 new Color(setting.getMincolour()), new Color(
4575 setting.getColour()), setting.getMin(),
4576 setting.getMax()) : new FeatureColour(new Color(
4577 setting.getMincolour()), new Color(setting.getColour()),
4579 if (setting.hasThreshold())
4581 gc.setThreshold(setting.getThreshold());
4582 int threshstate = setting.getThreshstate();
4583 // -1 = None, 0 = Below, 1 = Above threshold
4584 if (threshstate == 0)
4586 gc.setBelowThreshold(true);
4588 else if (threshstate == 1)
4590 gc.setAboveThreshold(true);
4593 gc.setAutoScaled(true); // default
4594 if (setting.hasAutoScale())
4596 gc.setAutoScaled(setting.getAutoScale());
4598 if (setting.hasColourByLabel())
4600 gc.setColourByLabel(setting.getColourByLabel());
4602 // and put in the feature colour table.
4603 featureColours.put(setting.getType(), gc);
4607 featureColours.put(setting.getType(), new FeatureColour(
4608 new Color(setting.getColour())));
4610 renderOrder[fs] = setting.getType();
4611 if (setting.hasOrder())
4613 featureOrder.put(setting.getType(), setting.getOrder());
4617 featureOrder.put(setting.getType(), new Float(fs
4618 / jms.getFeatureSettings().getSettingCount()));
4620 if (setting.getDisplay())
4622 fdi.setVisible(setting.getType());
4625 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4626 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4628 Group grp = jms.getFeatureSettings().getGroup(gs);
4629 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4631 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4632 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4633 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4634 FeatureRendererSettings frs = new FeatureRendererSettings(
4635 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4636 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4637 .transferSettings(frs);
4641 if (view.getHiddenColumnsCount() > 0)
4643 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4645 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4646 .getHiddenColumns(c).getEnd() // +1
4650 if (view.getCalcIdParam() != null)
4652 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4654 if (calcIdParam != null)
4656 if (recoverCalcIdParam(calcIdParam, af.viewport))
4661 warn("Couldn't recover parameters for "
4662 + calcIdParam.getCalcId());
4667 af.setMenusFromViewport(af.viewport);
4668 af.setTitle(view.getTitle());
4669 // TODO: we don't need to do this if the viewport is aready visible.
4671 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4672 * has a 'cdna/protein complement' view, in which case save it in order to
4673 * populate a SplitFrame once all views have been read in.
4675 String complementaryViewId = view.getComplementId();
4676 if (complementaryViewId == null)
4678 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4680 // recompute any autoannotation
4681 af.alignPanel.updateAnnotation(false, true);
4682 reorderAutoannotation(af, al, autoAlan);
4683 af.alignPanel.alignmentChanged();
4687 splitFrameCandidates.put(view, af);
4692 private ColourSchemeI constructAnnotationColour(
4693 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4694 JalviewModelSequence jms, boolean checkGroupAnnColour)
4696 boolean propagateAnnColour = false;
4697 ColourSchemeI cs = null;
4698 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4699 if (checkGroupAnnColour && al.getGroups() != null
4700 && al.getGroups().size() > 0)
4702 // pre 2.8.1 behaviour
4703 // check to see if we should transfer annotation colours
4704 propagateAnnColour = true;
4705 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4707 if (sg.getColourScheme() instanceof AnnotationColourGradient)
4709 propagateAnnColour = false;
4713 // int find annotation
4714 if (annAlignment.getAlignmentAnnotation() != null)
4716 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4718 if (annAlignment.getAlignmentAnnotation()[i].label
4719 .equals(viewAnnColour.getAnnotation()))
4721 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4723 annAlignment.getAlignmentAnnotation()[i]
4724 .setThreshold(new jalview.datamodel.GraphLine(
4725 viewAnnColour.getThreshold(), "Threshold",
4726 java.awt.Color.black)
4731 if (viewAnnColour.getColourScheme().equals(
4732 ResidueColourScheme.NONE))
4734 cs = new AnnotationColourGradient(
4735 annAlignment.getAlignmentAnnotation()[i],
4736 new java.awt.Color(viewAnnColour.getMinColour()),
4737 new java.awt.Color(viewAnnColour.getMaxColour()),
4738 viewAnnColour.getAboveThreshold());
4740 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4742 cs = new AnnotationColourGradient(
4743 annAlignment.getAlignmentAnnotation()[i],
4744 getUserColourScheme(jms,
4745 viewAnnColour.getColourScheme()),
4746 viewAnnColour.getAboveThreshold());
4750 cs = new AnnotationColourGradient(
4751 annAlignment.getAlignmentAnnotation()[i],
4752 ColourSchemeProperty.getColourScheme(al,
4753 viewAnnColour.getColourScheme()),
4754 viewAnnColour.getAboveThreshold());
4756 if (viewAnnColour.hasPerSequence())
4758 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4761 if (viewAnnColour.hasPredefinedColours())
4763 ((AnnotationColourGradient) cs)
4764 .setPredefinedColours(viewAnnColour
4765 .isPredefinedColours());
4767 if (propagateAnnColour && al.getGroups() != null)
4769 // Also use these settings for all the groups
4770 for (int g = 0; g < al.getGroups().size(); g++)
4772 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4780 * if (viewAnnColour.getColourScheme().equals(ResidueColourScheme.NONE)) { sg.cs =
4781 * new AnnotationColourGradient(
4782 * annAlignment.getAlignmentAnnotation()[i], new
4783 * java.awt.Color(viewAnnColour. getMinColour()), new
4784 * java.awt.Color(viewAnnColour. getMaxColour()),
4785 * viewAnnColour.getAboveThreshold()); } else
4788 sg.setColourScheme(new AnnotationColourGradient(
4789 annAlignment.getAlignmentAnnotation()[i], sg
4790 .getColourScheme(), viewAnnColour
4791 .getAboveThreshold()));
4792 if (cs instanceof AnnotationColourGradient)
4794 if (viewAnnColour.hasPerSequence())
4796 ((AnnotationColourGradient) cs)
4797 .setSeqAssociated(viewAnnColour.isPerSequence());
4799 if (viewAnnColour.hasPredefinedColours())
4801 ((AnnotationColourGradient) cs)
4802 .setPredefinedColours(viewAnnColour
4803 .isPredefinedColours());
4819 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4820 List<JvAnnotRow> autoAlan)
4822 // copy over visualization settings for autocalculated annotation in the
4824 if (al.getAlignmentAnnotation() != null)
4827 * Kludge for magic autoannotation names (see JAL-811)
4829 String[] magicNames = new String[] { "Consensus", "Quality",
4831 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4832 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4833 for (String nm : magicNames)
4835 visan.put(nm, nullAnnot);
4837 for (JvAnnotRow auan : autoAlan)
4839 visan.put(auan.template.label
4840 + (auan.template.getCalcId() == null ? "" : "\t"
4841 + auan.template.getCalcId()), auan);
4843 int hSize = al.getAlignmentAnnotation().length;
4844 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4845 // work through any autoCalculated annotation already on the view
4846 // removing it if it should be placed in a different location on the
4847 // annotation panel.
4848 List<String> remains = new ArrayList<String>(visan.keySet());
4849 for (int h = 0; h < hSize; h++)
4851 jalview.datamodel.AlignmentAnnotation jalan = al
4852 .getAlignmentAnnotation()[h];
4853 if (jalan.autoCalculated)
4856 JvAnnotRow valan = visan.get(k = jalan.label);
4857 if (jalan.getCalcId() != null)
4859 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4864 // delete the auto calculated row from the alignment
4865 al.deleteAnnotation(jalan, false);
4869 if (valan != nullAnnot)
4871 if (jalan != valan.template)
4873 // newly created autoannotation row instance
4874 // so keep a reference to the visible annotation row
4875 // and copy over all relevant attributes
4876 if (valan.template.graphHeight >= 0)
4879 jalan.graphHeight = valan.template.graphHeight;
4881 jalan.visible = valan.template.visible;
4883 reorder.add(new JvAnnotRow(valan.order, jalan));
4888 // Add any (possibly stale) autocalculated rows that were not appended to
4889 // the view during construction
4890 for (String other : remains)
4892 JvAnnotRow othera = visan.get(other);
4893 if (othera != nullAnnot && othera.template.getCalcId() != null
4894 && othera.template.getCalcId().length() > 0)
4896 reorder.add(othera);
4899 // now put the automatic annotation in its correct place
4900 int s = 0, srt[] = new int[reorder.size()];
4901 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4902 for (JvAnnotRow jvar : reorder)
4905 srt[s++] = jvar.order;
4908 jalview.util.QuickSort.sort(srt, rws);
4909 // and re-insert the annotation at its correct position
4910 for (JvAnnotRow jvar : rws)
4912 al.addAnnotation(jvar.template, jvar.order);
4914 af.alignPanel.adjustAnnotationHeight();
4918 Hashtable skipList = null;
4921 * TODO remove this method
4924 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4925 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4926 * throw new Error("Implementation Error. No skipList defined for this
4927 * Jalview2XML instance."); } return (AlignFrame)
4928 * skipList.get(view.getSequenceSetId()); }
4932 * Check if the Jalview view contained in object should be skipped or not.
4935 * @return true if view's sequenceSetId is a key in skipList
4937 private boolean skipViewport(JalviewModel object)
4939 if (skipList == null)
4944 if (skipList.containsKey(id = object.getJalviewModelSequence()
4945 .getViewport()[0].getSequenceSetId()))
4947 if (Cache.log != null && Cache.log.isDebugEnabled())
4949 Cache.log.debug("Skipping seuqence set id " + id);
4956 public void addToSkipList(AlignFrame af)
4958 if (skipList == null)
4960 skipList = new Hashtable();
4962 skipList.put(af.getViewport().getSequenceSetId(), af);
4965 public void clearSkipList()
4967 if (skipList != null)
4974 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4975 boolean ignoreUnrefed)
4977 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4979 Vector dseqs = null;
4982 // create a list of new dataset sequences
4983 dseqs = new Vector();
4985 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4987 Sequence vamsasSeq = vamsasSet.getSequence(i);
4988 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4990 // create a new dataset
4993 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4994 dseqs.copyInto(dsseqs);
4995 ds = new jalview.datamodel.Alignment(dsseqs);
4996 debug("Created new dataset " + vamsasSet.getDatasetId()
4997 + " for alignment " + System.identityHashCode(al));
4998 addDatasetRef(vamsasSet.getDatasetId(), ds);
5000 // set the dataset for the newly imported alignment.
5001 if (al.getDataset() == null && !ignoreUnrefed)
5010 * sequence definition to create/merge dataset sequence for
5014 * vector to add new dataset sequence to
5015 * @param ignoreUnrefed
5016 * - when true, don't create new sequences from vamsasSeq if it's id
5017 * doesn't already have an asssociated Jalview sequence.
5019 * - used to reorder the sequence in the alignment according to the
5020 * vamsasSeq array ordering, to preserve ordering of dataset
5022 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5023 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5025 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5027 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5028 boolean reorder = false;
5029 SequenceI dsq = null;
5030 if (sq != null && sq.getDatasetSequence() != null)
5032 dsq = sq.getDatasetSequence();
5038 if (sq == null && ignoreUnrefed)
5042 String sqid = vamsasSeq.getDsseqid();
5045 // need to create or add a new dataset sequence reference to this sequence
5048 dsq = seqRefIds.get(sqid);
5053 // make a new dataset sequence
5054 dsq = sq.createDatasetSequence();
5057 // make up a new dataset reference for this sequence
5058 sqid = seqHash(dsq);
5060 dsq.setVamsasId(uniqueSetSuffix + sqid);
5061 seqRefIds.put(sqid, dsq);
5066 dseqs.addElement(dsq);
5071 ds.addSequence(dsq);
5077 { // make this dataset sequence sq's dataset sequence
5078 sq.setDatasetSequence(dsq);
5079 // and update the current dataset alignment
5084 if (!dseqs.contains(dsq))
5091 if (ds.findIndex(dsq) < 0)
5093 ds.addSequence(dsq);
5100 // TODO: refactor this as a merge dataset sequence function
5101 // now check that sq (the dataset sequence) sequence really is the union of
5102 // all references to it
5103 // boolean pre = sq.getStart() < dsq.getStart();
5104 // boolean post = sq.getEnd() > dsq.getEnd();
5108 // StringBuffer sb = new StringBuffer();
5109 String newres = jalview.analysis.AlignSeq.extractGaps(
5110 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5111 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5112 && newres.length() > dsq.getLength())
5114 // Update with the longer sequence.
5118 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5119 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5120 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5121 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5123 dsq.setSequence(newres);
5125 // TODO: merges will never happen if we 'know' we have the real dataset
5126 // sequence - this should be detected when id==dssid
5128 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5129 // + (pre ? "prepended" : "") + " "
5130 // + (post ? "appended" : ""));
5135 // sequence refs are identical. We may need to update the existing dataset
5136 // alignment with this one, though.
5137 if (ds != null && dseqs == null)
5139 int opos = ds.findIndex(dsq);
5140 SequenceI tseq = null;
5141 if (opos != -1 && vseqpos != opos)
5143 // remove from old position
5144 ds.deleteSequence(dsq);
5146 if (vseqpos < ds.getHeight())
5148 if (vseqpos != opos)
5150 // save sequence at destination position
5151 tseq = ds.getSequenceAt(vseqpos);
5152 ds.replaceSequenceAt(vseqpos, dsq);
5153 ds.addSequence(tseq);
5158 ds.addSequence(dsq);
5165 * TODO use AlignmentI here and in related methods - needs
5166 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5168 Hashtable<String, AlignmentI> datasetIds = null;
5170 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5172 private AlignmentI getDatasetFor(String datasetId)
5174 if (datasetIds == null)
5176 datasetIds = new Hashtable<String, AlignmentI>();
5179 if (datasetIds.containsKey(datasetId))
5181 return datasetIds.get(datasetId);
5186 private void addDatasetRef(String datasetId, AlignmentI dataset)
5188 if (datasetIds == null)
5190 datasetIds = new Hashtable<String, AlignmentI>();
5192 datasetIds.put(datasetId, dataset);
5196 * make a new dataset ID for this jalview dataset alignment
5201 private String getDatasetIdRef(AlignmentI dataset)
5203 if (dataset.getDataset() != null)
5205 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5207 String datasetId = makeHashCode(dataset, null);
5208 if (datasetId == null)
5210 // make a new datasetId and record it
5211 if (dataset2Ids == null)
5213 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5217 datasetId = dataset2Ids.get(dataset);
5219 if (datasetId == null)
5221 datasetId = "ds" + dataset2Ids.size() + 1;
5222 dataset2Ids.put(dataset, datasetId);
5228 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5230 for (int d = 0; d < sequence.getDBRefCount(); d++)
5232 DBRef dr = sequence.getDBRef(d);
5233 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5234 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5235 .getVersion(), sequence.getDBRef(d).getAccessionId());
5236 if (dr.getMapping() != null)
5238 entry.setMap(addMapping(dr.getMapping()));
5240 datasetSequence.addDBRef(entry);
5244 private jalview.datamodel.Mapping addMapping(Mapping m)
5246 SequenceI dsto = null;
5247 // Mapping m = dr.getMapping();
5248 int fr[] = new int[m.getMapListFromCount() * 2];
5249 Enumeration f = m.enumerateMapListFrom();
5250 for (int _i = 0; f.hasMoreElements(); _i += 2)
5252 MapListFrom mf = (MapListFrom) f.nextElement();
5253 fr[_i] = mf.getStart();
5254 fr[_i + 1] = mf.getEnd();
5256 int fto[] = new int[m.getMapListToCount() * 2];
5257 f = m.enumerateMapListTo();
5258 for (int _i = 0; f.hasMoreElements(); _i += 2)
5260 MapListTo mf = (MapListTo) f.nextElement();
5261 fto[_i] = mf.getStart();
5262 fto[_i + 1] = mf.getEnd();
5264 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5265 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5266 if (m.getMappingChoice() != null)
5268 MappingChoice mc = m.getMappingChoice();
5269 if (mc.getDseqFor() != null)
5271 String dsfor = "" + mc.getDseqFor();
5272 if (seqRefIds.containsKey(dsfor))
5277 jmap.setTo(seqRefIds.get(dsfor));
5281 frefedSequence.add(newMappingRef(dsfor, jmap));
5287 * local sequence definition
5289 Sequence ms = mc.getSequence();
5290 SequenceI djs = null;
5291 String sqid = ms.getDsseqid();
5292 if (sqid != null && sqid.length() > 0)
5295 * recover dataset sequence
5297 djs = seqRefIds.get(sqid);
5302 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5303 sqid = ((Object) ms).toString(); // make up a new hascode for
5304 // undefined dataset sequence hash
5305 // (unlikely to happen)
5311 * make a new dataset sequence and add it to refIds hash
5313 djs = new jalview.datamodel.Sequence(ms.getName(),
5315 djs.setStart(jmap.getMap().getToLowest());
5316 djs.setEnd(jmap.getMap().getToHighest());
5317 djs.setVamsasId(uniqueSetSuffix + sqid);
5319 incompleteSeqs.put(sqid, djs);
5320 seqRefIds.put(sqid, djs);
5323 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5332 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5333 boolean keepSeqRefs)
5336 JalviewModel jm = saveState(ap, null, null, null);
5341 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5345 uniqueSetSuffix = "";
5346 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5351 if (this.frefedSequence == null)
5353 frefedSequence = new Vector();
5356 viewportsAdded.clear();
5358 AlignFrame af = loadFromObject(jm, null, false, null);
5359 af.alignPanels.clear();
5360 af.closeMenuItem_actionPerformed(true);
5363 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5364 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5365 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5366 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5367 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5370 return af.alignPanel;
5374 * flag indicating if hashtables should be cleared on finalization TODO this
5375 * flag may not be necessary
5377 private final boolean _cleartables = true;
5379 private Hashtable jvids2vobj;
5384 * @see java.lang.Object#finalize()
5387 protected void finalize() throws Throwable
5389 // really make sure we have no buried refs left.
5394 this.seqRefIds = null;
5395 this.seqsToIds = null;
5399 private void warn(String msg)
5404 private void warn(String msg, Exception e)
5406 if (Cache.log != null)
5410 Cache.log.warn(msg, e);
5414 Cache.log.warn(msg);
5419 System.err.println("Warning: " + msg);
5422 e.printStackTrace();
5427 private void debug(String string)
5429 debug(string, null);
5432 private void debug(String msg, Exception e)
5434 if (Cache.log != null)
5438 Cache.log.debug(msg, e);
5442 Cache.log.debug(msg);
5447 System.err.println("Warning: " + msg);
5450 e.printStackTrace();
5456 * set the object to ID mapping tables used to write/recover objects and XML
5457 * ID strings for the jalview project. If external tables are provided then
5458 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5459 * object goes out of scope. - also populates the datasetIds hashtable with
5460 * alignment objects containing dataset sequences
5463 * Map from ID strings to jalview datamodel
5465 * Map from jalview datamodel to ID strings
5469 public void setObjectMappingTables(Hashtable vobj2jv,
5470 IdentityHashMap jv2vobj)
5472 this.jv2vobj = jv2vobj;
5473 this.vobj2jv = vobj2jv;
5474 Iterator ds = jv2vobj.keySet().iterator();
5476 while (ds.hasNext())
5478 Object jvobj = ds.next();
5479 id = jv2vobj.get(jvobj).toString();
5480 if (jvobj instanceof jalview.datamodel.Alignment)
5482 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5484 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5487 else if (jvobj instanceof jalview.datamodel.Sequence)
5489 // register sequence object so the XML parser can recover it.
5490 if (seqRefIds == null)
5492 seqRefIds = new HashMap<String, SequenceI>();
5494 if (seqsToIds == null)
5496 seqsToIds = new IdentityHashMap<SequenceI, String>();
5498 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5499 seqsToIds.put((SequenceI) jvobj, id);
5501 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5504 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5505 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5506 if (jvann.annotationId == null)
5508 jvann.annotationId = anid;
5510 if (!jvann.annotationId.equals(anid))
5512 // TODO verify that this is the correct behaviour
5513 this.warn("Overriding Annotation ID for " + anid
5514 + " from different id : " + jvann.annotationId);
5515 jvann.annotationId = anid;
5518 else if (jvobj instanceof String)
5520 if (jvids2vobj == null)
5522 jvids2vobj = new Hashtable();
5523 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5528 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5534 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5535 * objects created from the project archive. If string is null (default for
5536 * construction) then suffix will be set automatically.
5540 public void setUniqueSetSuffix(String string)
5542 uniqueSetSuffix = string;
5547 * uses skipList2 as the skipList for skipping views on sequence sets
5548 * associated with keys in the skipList
5552 public void setSkipList(Hashtable skipList2)
5554 skipList = skipList2;
5558 * Reads the jar entry of given name and returns its contents, or null if the
5559 * entry is not found.
5562 * @param jarEntryName
5565 protected String readJarEntry(jarInputStreamProvider jprovider,
5566 String jarEntryName)
5568 String result = null;
5569 BufferedReader in = null;
5574 * Reopen the jar input stream and traverse its entries to find a matching
5577 JarInputStream jin = jprovider.getJarInputStream();
5578 JarEntry entry = null;
5581 entry = jin.getNextJarEntry();
5582 } while (entry != null && !entry.getName().equals(jarEntryName));
5586 StringBuilder out = new StringBuilder(256);
5587 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5590 while ((data = in.readLine()) != null)
5594 result = out.toString();
5598 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5600 } catch (Exception ex)
5602 ex.printStackTrace();
5610 } catch (IOException e)
5621 * Returns an incrementing counter (0, 1, 2...)
5625 private synchronized int nextCounter()