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.GraphLine;
33 import jalview.datamodel.PDBEntry;
34 import jalview.datamodel.RnaViewerModel;
35 import jalview.datamodel.SequenceFeature;
36 import jalview.datamodel.SequenceGroup;
37 import jalview.datamodel.SequenceI;
38 import jalview.datamodel.StructureViewerModel;
39 import jalview.datamodel.StructureViewerModel.StructureData;
40 import jalview.ext.varna.RnaModel;
41 import jalview.gui.StructureViewer.ViewerType;
42 import jalview.io.DataSourceType;
43 import jalview.io.FileFormat;
44 import jalview.renderer.ResidueShaderI;
45 import jalview.schemabinding.version2.AlcodMap;
46 import jalview.schemabinding.version2.AlcodonFrame;
47 import jalview.schemabinding.version2.Annotation;
48 import jalview.schemabinding.version2.AnnotationColours;
49 import jalview.schemabinding.version2.AnnotationElement;
50 import jalview.schemabinding.version2.CalcIdParam;
51 import jalview.schemabinding.version2.DBRef;
52 import jalview.schemabinding.version2.Features;
53 import jalview.schemabinding.version2.Group;
54 import jalview.schemabinding.version2.HiddenColumns;
55 import jalview.schemabinding.version2.JGroup;
56 import jalview.schemabinding.version2.JSeq;
57 import jalview.schemabinding.version2.JalviewModel;
58 import jalview.schemabinding.version2.JalviewModelSequence;
59 import jalview.schemabinding.version2.MapListFrom;
60 import jalview.schemabinding.version2.MapListTo;
61 import jalview.schemabinding.version2.Mapping;
62 import jalview.schemabinding.version2.MappingChoice;
63 import jalview.schemabinding.version2.OtherData;
64 import jalview.schemabinding.version2.PdbentryItem;
65 import jalview.schemabinding.version2.Pdbids;
66 import jalview.schemabinding.version2.Property;
67 import jalview.schemabinding.version2.RnaViewer;
68 import jalview.schemabinding.version2.SecondaryStructure;
69 import jalview.schemabinding.version2.Sequence;
70 import jalview.schemabinding.version2.SequenceSet;
71 import jalview.schemabinding.version2.SequenceSetProperties;
72 import jalview.schemabinding.version2.Setting;
73 import jalview.schemabinding.version2.StructureState;
74 import jalview.schemabinding.version2.ThresholdLine;
75 import jalview.schemabinding.version2.Tree;
76 import jalview.schemabinding.version2.UserColours;
77 import jalview.schemabinding.version2.Viewport;
78 import jalview.schemes.AnnotationColourGradient;
79 import jalview.schemes.ColourSchemeI;
80 import jalview.schemes.ColourSchemeProperty;
81 import jalview.schemes.FeatureColour;
82 import jalview.schemes.ResidueProperties;
83 import jalview.schemes.UserColourScheme;
84 import jalview.structure.StructureSelectionManager;
85 import jalview.structures.models.AAStructureBindingModel;
86 import jalview.util.MessageManager;
87 import jalview.util.Platform;
88 import jalview.util.StringUtils;
89 import jalview.util.jarInputStreamProvider;
90 import jalview.viewmodel.AlignmentViewport;
91 import jalview.viewmodel.ViewportRanges;
92 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
93 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
94 import jalview.ws.jws2.Jws2Discoverer;
95 import jalview.ws.jws2.dm.AAConSettings;
96 import jalview.ws.jws2.jabaws2.Jws2Instance;
97 import jalview.ws.params.ArgumentI;
98 import jalview.ws.params.AutoCalcSetting;
99 import jalview.ws.params.WsParamSetI;
101 import java.awt.Color;
102 import java.awt.Rectangle;
103 import java.io.BufferedReader;
104 import java.io.DataInputStream;
105 import java.io.DataOutputStream;
107 import java.io.FileInputStream;
108 import java.io.FileOutputStream;
109 import java.io.IOException;
110 import java.io.InputStreamReader;
111 import java.io.OutputStreamWriter;
112 import java.io.PrintWriter;
113 import java.lang.reflect.InvocationTargetException;
114 import java.net.MalformedURLException;
116 import java.util.ArrayList;
117 import java.util.Arrays;
118 import java.util.Enumeration;
119 import java.util.HashMap;
120 import java.util.HashSet;
121 import java.util.Hashtable;
122 import java.util.IdentityHashMap;
123 import java.util.Iterator;
124 import java.util.LinkedHashMap;
125 import java.util.List;
126 import java.util.Map;
127 import java.util.Map.Entry;
128 import java.util.Set;
129 import java.util.Vector;
130 import java.util.jar.JarEntry;
131 import java.util.jar.JarInputStream;
132 import java.util.jar.JarOutputStream;
134 import javax.swing.JInternalFrame;
135 import javax.swing.SwingUtilities;
137 import org.exolab.castor.xml.Marshaller;
138 import org.exolab.castor.xml.Unmarshaller;
141 * Write out the current jalview desktop state as a Jalview XML stream.
143 * Note: the vamsas objects referred to here are primitive versions of the
144 * VAMSAS project schema elements - they are not the same and most likely never
148 * @version $Revision: 1.134 $
150 public class Jalview2XML
152 private static final String VIEWER_PREFIX = "viewer_";
154 private static final String RNA_PREFIX = "rna_";
156 private static final String UTF_8 = "UTF-8";
158 // use this with nextCounter() to make unique names for entities
159 private int counter = 0;
162 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
163 * of sequence objects are created.
165 IdentityHashMap<SequenceI, String> seqsToIds = null;
168 * jalview XML Sequence ID to jalview sequence object reference (both dataset
169 * and alignment sequences. Populated as XML reps of sequence objects are
172 Map<String, SequenceI> seqRefIds = null;
174 Map<String, SequenceI> incompleteSeqs = null;
176 List<SeqFref> frefedSequence = null;
178 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
181 * Map of reconstructed AlignFrame objects that appear to have come from
182 * SplitFrame objects (have a dna/protein complement view).
184 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<>();
187 * Map from displayed rna structure models to their saved session state jar
190 private Map<RnaModel, String> rnaSessions = new HashMap<>();
193 * create/return unique hash string for sq
196 * @return new or existing unique string for sq
198 String seqHash(SequenceI sq)
200 if (seqsToIds == null)
204 if (seqsToIds.containsKey(sq))
206 return seqsToIds.get(sq);
210 // create sequential key
211 String key = "sq" + (seqsToIds.size() + 1);
212 key = makeHashCode(sq, key); // check we don't have an external reference
214 seqsToIds.put(sq, key);
221 if (seqsToIds == null)
223 seqsToIds = new IdentityHashMap<>();
225 if (seqRefIds == null)
227 seqRefIds = new HashMap<>();
229 if (incompleteSeqs == null)
231 incompleteSeqs = new HashMap<>();
233 if (frefedSequence == null)
235 frefedSequence = new ArrayList<>();
243 public Jalview2XML(boolean raiseGUI)
245 this.raiseGUI = raiseGUI;
249 * base class for resolving forward references to sequences by their ID
254 abstract class SeqFref
260 public SeqFref(String _sref, String type)
266 public String getSref()
271 public SequenceI getSrefSeq()
273 return seqRefIds.get(sref);
276 public boolean isResolvable()
278 return seqRefIds.get(sref) != null;
281 public SequenceI getSrefDatasetSeq()
283 SequenceI sq = seqRefIds.get(sref);
286 while (sq.getDatasetSequence() != null)
288 sq = sq.getDatasetSequence();
295 * @return true if the forward reference was fully resolved
297 abstract boolean resolve();
300 public String toString()
302 return type + " reference to " + sref;
307 * create forward reference for a mapping
313 public SeqFref newMappingRef(final String sref,
314 final jalview.datamodel.Mapping _jmap)
316 SeqFref fref = new SeqFref(sref, "Mapping")
318 public jalview.datamodel.Mapping jmap = _jmap;
323 SequenceI seq = getSrefDatasetSeq();
335 public SeqFref newAlcodMapRef(final String sref,
336 final AlignedCodonFrame _cf,
337 final jalview.datamodel.Mapping _jmap)
340 SeqFref fref = new SeqFref(sref, "Codon Frame")
342 AlignedCodonFrame cf = _cf;
344 public jalview.datamodel.Mapping mp = _jmap;
347 public boolean isResolvable()
349 return super.isResolvable() && mp.getTo() != null;
355 SequenceI seq = getSrefDatasetSeq();
360 cf.addMap(seq, mp.getTo(), mp.getMap());
367 public void resolveFrefedSequences()
369 Iterator<SeqFref> nextFref = frefedSequence.iterator();
370 int toresolve = frefedSequence.size();
371 int unresolved = 0, failedtoresolve = 0;
372 while (nextFref.hasNext())
374 SeqFref ref = nextFref.next();
375 if (ref.isResolvable())
387 } catch (Exception x)
390 "IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
403 System.err.println("Jalview Project Import: There were " + unresolved
404 + " forward references left unresolved on the stack.");
406 if (failedtoresolve > 0)
408 System.err.println("SERIOUS! " + failedtoresolve
409 + " resolvable forward references failed to resolve.");
411 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
414 "Jalview Project Import: There are " + incompleteSeqs.size()
415 + " sequences which may have incomplete metadata.");
416 if (incompleteSeqs.size() < 10)
418 for (SequenceI s : incompleteSeqs.values())
420 System.err.println(s.toString());
426 "Too many to report. Skipping output of incomplete sequences.");
432 * This maintains a map of viewports, the key being the seqSetId. Important to
433 * set historyItem and redoList for multiple views
435 Map<String, AlignViewport> viewportsAdded = new HashMap<>();
437 Map<String, AlignmentAnnotation> annotationIds = new HashMap<>();
439 String uniqueSetSuffix = "";
442 * List of pdbfiles added to Jar
444 List<String> pdbfiles = null;
446 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
447 public void saveState(File statefile)
449 FileOutputStream fos = null;
452 fos = new FileOutputStream(statefile);
453 JarOutputStream jout = new JarOutputStream(fos);
456 } catch (Exception e)
458 // TODO: inform user of the problem - they need to know if their data was
460 if (errorMessage == null)
462 errorMessage = "Couldn't write Jalview Archive to output file '"
463 + statefile + "' - See console error log for details";
467 errorMessage += "(output file was '" + statefile + "')";
477 } catch (IOException e)
487 * Writes a jalview project archive to the given Jar output stream.
491 public void saveState(JarOutputStream jout)
493 AlignFrame[] frames = Desktop.getAlignFrames();
499 saveAllFrames(Arrays.asList(frames), jout);
503 * core method for storing state for a set of AlignFrames.
506 * - frames involving all data to be exported (including containing
509 * - project output stream
511 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
513 Hashtable<String, AlignFrame> dsses = new Hashtable<>();
516 * ensure cached data is clear before starting
518 // todo tidy up seqRefIds, seqsToIds initialisation / reset
520 splitFrameCandidates.clear();
525 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
526 // //////////////////////////////////////////////////
528 List<String> shortNames = new ArrayList<>();
529 List<String> viewIds = new ArrayList<>();
532 for (int i = frames.size() - 1; i > -1; i--)
534 AlignFrame af = frames.get(i);
536 if (skipList != null && skipList
537 .containsKey(af.getViewport().getSequenceSetId()))
542 String shortName = makeFilename(af, shortNames);
544 int ap, apSize = af.alignPanels.size();
546 for (ap = 0; ap < apSize; ap++)
548 AlignmentPanel apanel = af.alignPanels.get(ap);
549 String fileName = apSize == 1 ? shortName : ap + shortName;
550 if (!fileName.endsWith(".xml"))
552 fileName = fileName + ".xml";
555 saveState(apanel, fileName, jout, viewIds);
557 String dssid = getDatasetIdRef(
558 af.getViewport().getAlignment().getDataset());
559 if (!dsses.containsKey(dssid))
561 dsses.put(dssid, af);
566 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
572 } catch (Exception foo)
577 } catch (Exception ex)
579 // TODO: inform user of the problem - they need to know if their data was
581 if (errorMessage == null)
583 errorMessage = "Couldn't write Jalview Archive - see error output for details";
585 ex.printStackTrace();
590 * Generates a distinct file name, based on the title of the AlignFrame, by
591 * appending _n for increasing n until an unused name is generated. The new
592 * name (without its extension) is added to the list.
596 * @return the generated name, with .xml extension
598 protected String makeFilename(AlignFrame af, List<String> namesUsed)
600 String shortName = af.getTitle();
602 if (shortName.indexOf(File.separatorChar) > -1)
604 shortName = shortName
605 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
610 while (namesUsed.contains(shortName))
612 if (shortName.endsWith("_" + (count - 1)))
614 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
617 shortName = shortName.concat("_" + count);
621 namesUsed.add(shortName);
623 if (!shortName.endsWith(".xml"))
625 shortName = shortName + ".xml";
630 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
631 public boolean saveAlignment(AlignFrame af, String jarFile,
636 FileOutputStream fos = new FileOutputStream(jarFile);
637 JarOutputStream jout = new JarOutputStream(fos);
638 List<AlignFrame> frames = new ArrayList<>();
640 // resolve splitframes
641 if (af.getViewport().getCodingComplement() != null)
643 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
649 saveAllFrames(frames, jout);
653 } catch (Exception foo)
659 } catch (Exception ex)
661 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
662 ex.printStackTrace();
667 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
668 String fileName, JarOutputStream jout)
671 for (String dssids : dsses.keySet())
673 AlignFrame _af = dsses.get(dssids);
674 String jfileName = fileName + " Dataset for " + _af.getTitle();
675 if (!jfileName.endsWith(".xml"))
677 jfileName = jfileName + ".xml";
679 saveState(_af.alignPanel, jfileName, true, jout, null);
684 * create a JalviewModel from an alignment view and marshall it to a
688 * panel to create jalview model for
690 * name of alignment panel written to output stream
697 public JalviewModel saveState(AlignmentPanel ap, String fileName,
698 JarOutputStream jout, List<String> viewIds)
700 return saveState(ap, fileName, false, jout, viewIds);
704 * create a JalviewModel from an alignment view and marshall it to a
708 * panel to create jalview model for
710 * name of alignment panel written to output stream
712 * when true, only write the dataset for the alignment, not the data
713 * associated with the view.
719 public JalviewModel saveState(AlignmentPanel ap, String fileName,
720 boolean storeDS, JarOutputStream jout, List<String> viewIds)
724 viewIds = new ArrayList<>();
729 List<UserColourScheme> userColours = new ArrayList<>();
731 AlignViewport av = ap.av;
732 ViewportRanges vpRanges = av.getRanges();
734 JalviewModel object = new JalviewModel();
735 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
737 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
739 jalview.bin.Cache.getDefault("VERSION", "Development Build"));
742 * rjal is full height alignment, jal is actual alignment with full metadata
743 * but excludes hidden sequences.
745 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
747 if (av.hasHiddenRows())
749 rjal = jal.getHiddenSequences().getFullAlignment();
752 SequenceSet vamsasSet = new SequenceSet();
754 JalviewModelSequence jms = new JalviewModelSequence();
756 vamsasSet.setGapChar(jal.getGapCharacter() + "");
758 if (jal.getDataset() != null)
760 // dataset id is the dataset's hashcode
761 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
764 // switch jal and the dataset
765 jal = jal.getDataset();
769 if (jal.getProperties() != null)
771 Enumeration en = jal.getProperties().keys();
772 while (en.hasMoreElements())
774 String key = en.nextElement().toString();
775 SequenceSetProperties ssp = new SequenceSetProperties();
777 ssp.setValue(jal.getProperties().get(key).toString());
778 vamsasSet.addSequenceSetProperties(ssp);
783 Set<String> calcIdSet = new HashSet<>();
784 // record the set of vamsas sequence XML POJO we create.
785 HashMap<String, Sequence> vamsasSetIds = new HashMap<>();
787 for (final SequenceI jds : rjal.getSequences())
789 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
790 : jds.getDatasetSequence();
791 String id = seqHash(jds);
792 if (vamsasSetIds.get(id) == null)
794 if (seqRefIds.get(id) != null && !storeDS)
796 // This happens for two reasons: 1. multiple views are being
798 // 2. the hashCode has collided with another sequence's code. This
800 // HAPPEN! (PF00072.15.stk does this)
801 // JBPNote: Uncomment to debug writing out of files that do not read
802 // back in due to ArrayOutOfBoundExceptions.
803 // System.err.println("vamsasSeq backref: "+id+"");
804 // System.err.println(jds.getName()+"
805 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
806 // System.err.println("Hashcode: "+seqHash(jds));
807 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
808 // System.err.println(rsq.getName()+"
809 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
810 // System.err.println("Hashcode: "+seqHash(rsq));
814 vamsasSeq = createVamsasSequence(id, jds);
815 vamsasSet.addSequence(vamsasSeq);
816 vamsasSetIds.put(id, vamsasSeq);
817 seqRefIds.put(id, jds);
821 jseq.setStart(jds.getStart());
822 jseq.setEnd(jds.getEnd());
823 jseq.setColour(av.getSequenceColour(jds).getRGB());
825 jseq.setId(id); // jseq id should be a string not a number
828 // Store any sequences this sequence represents
829 if (av.hasHiddenRows())
831 // use rjal, contains the full height alignment
833 av.getAlignment().getHiddenSequences().isHidden(jds));
835 if (av.isHiddenRepSequence(jds))
837 jalview.datamodel.SequenceI[] reps = av
838 .getRepresentedSequences(jds).getSequencesInOrder(rjal);
840 for (int h = 0; h < reps.length; h++)
844 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
849 // mark sequence as reference - if it is the reference for this view
852 jseq.setViewreference(jds == jal.getSeqrep());
856 // TODO: omit sequence features from each alignment view's XML dump if we
857 // are storing dataset
858 List<jalview.datamodel.SequenceFeature> sfs = jds
859 .getSequenceFeatures();
860 for (SequenceFeature sf : sfs)
862 Features features = new Features();
864 features.setBegin(sf.getBegin());
865 features.setEnd(sf.getEnd());
866 features.setDescription(sf.getDescription());
867 features.setType(sf.getType());
868 features.setFeatureGroup(sf.getFeatureGroup());
869 features.setScore(sf.getScore());
870 if (sf.links != null)
872 for (int l = 0; l < sf.links.size(); l++)
874 OtherData keyValue = new OtherData();
875 keyValue.setKey("LINK_" + l);
876 keyValue.setValue(sf.links.elementAt(l).toString());
877 features.addOtherData(keyValue);
880 if (sf.otherDetails != null)
883 Iterator<String> keys = sf.otherDetails.keySet().iterator();
884 while (keys.hasNext())
887 OtherData keyValue = new OtherData();
888 keyValue.setKey(key);
889 keyValue.setValue(sf.otherDetails.get(key).toString());
890 features.addOtherData(keyValue);
894 jseq.addFeatures(features);
897 if (jdatasq.getAllPDBEntries() != null)
899 Enumeration en = jdatasq.getAllPDBEntries().elements();
900 while (en.hasMoreElements())
902 Pdbids pdb = new Pdbids();
903 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
906 String pdbId = entry.getId();
908 pdb.setType(entry.getType());
911 * Store any structure views associated with this sequence. This
912 * section copes with duplicate entries in the project, so a dataset
913 * only view *should* be coped with sensibly.
915 // This must have been loaded, is it still visible?
916 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
917 String matchedFile = null;
918 for (int f = frames.length - 1; f > -1; f--)
920 if (frames[f] instanceof StructureViewerBase)
922 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
923 matchedFile = saveStructureState(ap, jds, pdb, entry, viewIds,
924 matchedFile, viewFrame);
926 * Only store each structure viewer's state once in the project
927 * jar. First time through only (storeDS==false)
929 String viewId = viewFrame.getViewId();
930 if (!storeDS && !viewIds.contains(viewId))
935 String viewerState = viewFrame.getStateInfo();
936 writeJarEntry(jout, getViewerJarEntryName(viewId),
937 viewerState.getBytes());
938 } catch (IOException e)
941 "Error saving viewer state: " + e.getMessage());
947 if (matchedFile != null || entry.getFile() != null)
949 if (entry.getFile() != null)
952 matchedFile = entry.getFile();
954 pdb.setFile(matchedFile); // entry.getFile());
955 if (pdbfiles == null)
957 pdbfiles = new ArrayList<>();
960 if (!pdbfiles.contains(pdbId))
963 copyFileToJar(jout, matchedFile, pdbId);
967 Enumeration<String> props = entry.getProperties();
968 if (props.hasMoreElements())
970 PdbentryItem item = new PdbentryItem();
971 while (props.hasMoreElements())
973 Property prop = new Property();
974 String key = props.nextElement();
976 prop.setValue(entry.getProperty(key).toString());
977 item.addProperty(prop);
979 pdb.addPdbentryItem(item);
986 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
991 if (!storeDS && av.hasHiddenRows())
993 jal = av.getAlignment();
997 if (storeDS && jal.getCodonFrames() != null)
999 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1000 for (AlignedCodonFrame acf : jac)
1002 AlcodonFrame alc = new AlcodonFrame();
1003 if (acf.getProtMappings() != null
1004 && acf.getProtMappings().length > 0)
1006 boolean hasMap = false;
1007 SequenceI[] dnas = acf.getdnaSeqs();
1008 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1009 for (int m = 0; m < pmaps.length; m++)
1011 AlcodMap alcmap = new AlcodMap();
1012 alcmap.setDnasq(seqHash(dnas[m]));
1014 createVamsasMapping(pmaps[m], dnas[m], null, false));
1015 alc.addAlcodMap(alcmap);
1020 vamsasSet.addAlcodonFrame(alc);
1023 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1025 // AlcodonFrame alc = new AlcodonFrame();
1026 // vamsasSet.addAlcodonFrame(alc);
1027 // for (int p = 0; p < acf.aaWidth; p++)
1029 // Alcodon cmap = new Alcodon();
1030 // if (acf.codons[p] != null)
1032 // // Null codons indicate a gapped column in the translated peptide
1034 // cmap.setPos1(acf.codons[p][0]);
1035 // cmap.setPos2(acf.codons[p][1]);
1036 // cmap.setPos3(acf.codons[p][2]);
1038 // alc.addAlcodon(cmap);
1040 // if (acf.getProtMappings() != null
1041 // && acf.getProtMappings().length > 0)
1043 // SequenceI[] dnas = acf.getdnaSeqs();
1044 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1045 // for (int m = 0; m < pmaps.length; m++)
1047 // AlcodMap alcmap = new AlcodMap();
1048 // alcmap.setDnasq(seqHash(dnas[m]));
1049 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1051 // alc.addAlcodMap(alcmap);
1058 // /////////////////////////////////
1059 if (!storeDS && av.getCurrentTree() != null)
1061 // FIND ANY ASSOCIATED TREES
1062 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1063 if (Desktop.desktop != null)
1065 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1067 for (int t = 0; t < frames.length; t++)
1069 if (frames[t] instanceof TreePanel)
1071 TreePanel tp = (TreePanel) frames[t];
1073 if (tp.treeCanvas.av.getAlignment() == jal)
1075 Tree tree = new Tree();
1076 tree.setTitle(tp.getTitle());
1077 tree.setCurrentTree((av.getCurrentTree() == tp.getTree()));
1078 tree.setNewick(tp.getTree().print());
1079 tree.setThreshold(tp.treeCanvas.threshold);
1081 tree.setFitToWindow(tp.fitToWindow.getState());
1082 tree.setFontName(tp.getTreeFont().getName());
1083 tree.setFontSize(tp.getTreeFont().getSize());
1084 tree.setFontStyle(tp.getTreeFont().getStyle());
1085 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1087 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1088 tree.setShowDistances(tp.distanceMenu.getState());
1090 tree.setHeight(tp.getHeight());
1091 tree.setWidth(tp.getWidth());
1092 tree.setXpos(tp.getX());
1093 tree.setYpos(tp.getY());
1094 tree.setId(makeHashCode(tp, null));
1104 * store forward refs from an annotationRow to any groups
1106 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<>();
1109 for (SequenceI sq : jal.getSequences())
1111 // Store annotation on dataset sequences only
1112 AlignmentAnnotation[] aa = sq.getAnnotation();
1113 if (aa != null && aa.length > 0)
1115 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1122 if (jal.getAlignmentAnnotation() != null)
1124 // Store the annotation shown on the alignment.
1125 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1126 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1131 if (jal.getGroups() != null)
1133 JGroup[] groups = new JGroup[jal.getGroups().size()];
1135 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1137 JGroup jGroup = new JGroup();
1138 groups[++i] = jGroup;
1140 jGroup.setStart(sg.getStartRes());
1141 jGroup.setEnd(sg.getEndRes());
1142 jGroup.setName(sg.getName());
1143 if (groupRefs.containsKey(sg))
1145 // group has references so set its ID field
1146 jGroup.setId(groupRefs.get(sg));
1148 ColourSchemeI colourScheme = sg.getColourScheme();
1149 if (colourScheme != null)
1151 ResidueShaderI groupColourScheme = sg.getGroupColourScheme();
1152 if (groupColourScheme.conservationApplied())
1154 jGroup.setConsThreshold(groupColourScheme.getConservationInc());
1156 if (colourScheme instanceof jalview.schemes.UserColourScheme)
1159 setUserColourScheme(colourScheme, userColours, jms));
1163 jGroup.setColour(colourScheme.getSchemeName());
1166 else if (colourScheme instanceof jalview.schemes.AnnotationColourGradient)
1168 jGroup.setColour("AnnotationColourGradient");
1169 jGroup.setAnnotationColours(constructAnnotationColours(
1170 (jalview.schemes.AnnotationColourGradient) colourScheme,
1173 else if (colourScheme instanceof jalview.schemes.UserColourScheme)
1176 setUserColourScheme(colourScheme, userColours, jms));
1180 jGroup.setColour(colourScheme.getSchemeName());
1183 jGroup.setPidThreshold(groupColourScheme.getThreshold());
1186 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1187 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1188 jGroup.setDisplayText(sg.getDisplayText());
1189 jGroup.setColourText(sg.getColourText());
1190 jGroup.setTextCol1(sg.textColour.getRGB());
1191 jGroup.setTextCol2(sg.textColour2.getRGB());
1192 jGroup.setTextColThreshold(sg.thresholdTextColour);
1193 jGroup.setShowUnconserved(sg.getShowNonconserved());
1194 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1195 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1196 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1197 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1198 for (SequenceI seq : sg.getSequences())
1200 jGroup.addSeq(seqHash(seq));
1204 jms.setJGroup(groups);
1208 // /////////SAVE VIEWPORT
1209 Viewport view = new Viewport();
1210 view.setTitle(ap.alignFrame.getTitle());
1211 view.setSequenceSetId(
1212 makeHashCode(av.getSequenceSetId(), av.getSequenceSetId()));
1213 view.setId(av.getViewId());
1214 if (av.getCodingComplement() != null)
1216 view.setComplementId(av.getCodingComplement().getViewId());
1218 view.setViewName(av.viewName);
1219 view.setGatheredViews(av.isGatherViewsHere());
1221 Rectangle size = ap.av.getExplodedGeometry();
1222 Rectangle position = size;
1225 size = ap.alignFrame.getBounds();
1226 if (av.getCodingComplement() != null)
1228 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1236 view.setXpos(position.x);
1237 view.setYpos(position.y);
1239 view.setWidth(size.width);
1240 view.setHeight(size.height);
1242 view.setStartRes(vpRanges.getStartRes());
1243 view.setStartSeq(vpRanges.getStartSeq());
1245 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1247 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1251 .getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1253 AnnotationColours ac = constructAnnotationColours(
1254 (jalview.schemes.AnnotationColourGradient) av
1255 .getGlobalColourScheme(),
1258 view.setAnnotationColours(ac);
1259 view.setBgColour("AnnotationColourGradient");
1263 view.setBgColour(ColourSchemeProperty
1264 .getColourName(av.getGlobalColourScheme()));
1267 ResidueShaderI vcs = av.getResidueShading();
1268 ColourSchemeI cs = av.getGlobalColourScheme();
1272 if (vcs.conservationApplied())
1274 view.setConsThreshold(vcs.getConservationInc());
1275 if (cs instanceof jalview.schemes.UserColourScheme)
1277 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1280 view.setPidThreshold(vcs.getThreshold());
1283 view.setConservationSelected(av.getConservationSelected());
1284 view.setPidSelected(av.getAbovePIDThreshold());
1285 view.setFontName(av.font.getName());
1286 view.setFontSize(av.font.getSize());
1287 view.setFontStyle(av.font.getStyle());
1288 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1289 view.setRenderGaps(av.isRenderGaps());
1290 view.setShowAnnotation(av.isShowAnnotation());
1291 view.setShowBoxes(av.getShowBoxes());
1292 view.setShowColourText(av.getColourText());
1293 view.setShowFullId(av.getShowJVSuffix());
1294 view.setRightAlignIds(av.isRightAlignIds());
1295 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1296 view.setShowText(av.getShowText());
1297 view.setShowUnconserved(av.getShowUnconserved());
1298 view.setWrapAlignment(av.getWrapAlignment());
1299 view.setTextCol1(av.getTextColour().getRGB());
1300 view.setTextCol2(av.getTextColour2().getRGB());
1301 view.setTextColThreshold(av.getThresholdTextColour());
1302 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1303 view.setShowSequenceLogo(av.isShowSequenceLogo());
1304 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1305 view.setShowGroupConsensus(av.isShowGroupConsensus());
1306 view.setShowGroupConservation(av.isShowGroupConservation());
1307 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1308 view.setShowDbRefTooltip(av.isShowDBRefs());
1309 view.setFollowHighlight(av.isFollowHighlight());
1310 view.setFollowSelection(av.followSelection);
1311 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1312 if (av.getFeaturesDisplayed() != null)
1314 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1316 String[] renderOrder = ap.getSeqPanel().seqCanvas
1317 .getFeatureRenderer().getRenderOrder()
1318 .toArray(new String[0]);
1320 Vector<String> settingsAdded = new Vector<>();
1321 if (renderOrder != null)
1323 for (String featureType : renderOrder)
1325 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1326 .getFeatureRenderer().getFeatureStyle(featureType);
1327 Setting setting = new Setting();
1328 setting.setType(featureType);
1329 if (!fcol.isSimpleColour())
1331 setting.setColour(fcol.getMaxColour().getRGB());
1332 setting.setMincolour(fcol.getMinColour().getRGB());
1333 setting.setMin(fcol.getMin());
1334 setting.setMax(fcol.getMax());
1335 setting.setColourByLabel(fcol.isColourByLabel());
1336 setting.setAutoScale(fcol.isAutoScaled());
1337 setting.setThreshold(fcol.getThreshold());
1338 // -1 = No threshold, 0 = Below, 1 = Above
1339 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1340 : (fcol.isBelowThreshold() ? 0 : -1));
1344 setting.setColour(fcol.getColour().getRGB());
1348 av.getFeaturesDisplayed().isVisible(featureType));
1349 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1350 .getOrder(featureType);
1353 setting.setOrder(rorder);
1355 fs.addSetting(setting);
1356 settingsAdded.addElement(featureType);
1360 // is groups actually supposed to be a map here ?
1361 Iterator<String> en = ap.getSeqPanel().seqCanvas
1362 .getFeatureRenderer().getFeatureGroups().iterator();
1363 Vector<String> groupsAdded = new Vector<>();
1364 while (en.hasNext())
1366 String grp = en.next();
1367 if (groupsAdded.contains(grp))
1371 Group g = new Group();
1373 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1374 .getFeatureRenderer().checkGroupVisibility(grp, false))
1377 groupsAdded.addElement(grp);
1379 jms.setFeatureSettings(fs);
1382 if (av.hasHiddenColumns())
1384 jalview.datamodel.HiddenColumns hidden = av.getAlignment()
1385 .getHiddenColumns();
1388 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1392 ArrayList<int[]> hiddenRegions = hidden.getHiddenColumnsCopy();
1393 for (int[] region : hiddenRegions)
1395 HiddenColumns hc = new HiddenColumns();
1396 hc.setStart(region[0]);
1397 hc.setEnd(region[1]);
1398 view.addHiddenColumns(hc);
1402 if (calcIdSet.size() > 0)
1404 for (String calcId : calcIdSet)
1406 if (calcId.trim().length() > 0)
1408 CalcIdParam cidp = createCalcIdParam(calcId, av);
1409 // Some calcIds have no parameters.
1412 view.addCalcIdParam(cidp);
1418 jms.addViewport(view);
1420 object.setJalviewModelSequence(jms);
1421 object.getVamsasModel().addSequenceSet(vamsasSet);
1423 if (jout != null && fileName != null)
1425 // We may not want to write the object to disk,
1426 // eg we can copy the alignViewport to a new view object
1427 // using save and then load
1430 System.out.println("Writing jar entry " + fileName);
1431 JarEntry entry = new JarEntry(fileName);
1432 jout.putNextEntry(entry);
1433 PrintWriter pout = new PrintWriter(
1434 new OutputStreamWriter(jout, UTF_8));
1435 Marshaller marshaller = new Marshaller(pout);
1436 marshaller.marshal(object);
1439 } catch (Exception ex)
1441 // TODO: raise error in GUI if marshalling failed.
1442 ex.printStackTrace();
1449 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1450 * for each viewer, with
1452 * <li>viewer geometry (position, size, split pane divider location)</li>
1453 * <li>index of the selected structure in the viewer (currently shows gapped
1455 * <li>the id of the annotation holding RNA secondary structure</li>
1456 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1458 * Varna viewer state is also written out (in native Varna XML) to separate
1459 * project jar entries. A separate entry is written for each RNA structure
1460 * displayed, with the naming convention
1462 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1470 * @param storeDataset
1472 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1473 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1474 boolean storeDataset)
1476 if (Desktop.desktop == null)
1480 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1481 for (int f = frames.length - 1; f > -1; f--)
1483 if (frames[f] instanceof AppVarna)
1485 AppVarna varna = (AppVarna) frames[f];
1487 * link the sequence to every viewer that is showing it and is linked to
1488 * its alignment panel
1490 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1492 String viewId = varna.getViewId();
1493 RnaViewer rna = new RnaViewer();
1494 rna.setViewId(viewId);
1495 rna.setTitle(varna.getTitle());
1496 rna.setXpos(varna.getX());
1497 rna.setYpos(varna.getY());
1498 rna.setWidth(varna.getWidth());
1499 rna.setHeight(varna.getHeight());
1500 rna.setDividerLocation(varna.getDividerLocation());
1501 rna.setSelectedRna(varna.getSelectedIndex());
1502 jseq.addRnaViewer(rna);
1505 * Store each Varna panel's state once in the project per sequence.
1506 * First time through only (storeDataset==false)
1508 // boolean storeSessions = false;
1509 // String sequenceViewId = viewId + seqsToIds.get(jds);
1510 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1512 // viewIds.add(sequenceViewId);
1513 // storeSessions = true;
1515 for (RnaModel model : varna.getModels())
1517 if (model.seq == jds)
1520 * VARNA saves each view (sequence or alignment secondary
1521 * structure, gapped or trimmed) as a separate XML file
1523 String jarEntryName = rnaSessions.get(model);
1524 if (jarEntryName == null)
1527 String varnaStateFile = varna.getStateInfo(model.rna);
1528 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1529 copyFileToJar(jout, varnaStateFile, jarEntryName);
1530 rnaSessions.put(model, jarEntryName);
1532 SecondaryStructure ss = new SecondaryStructure();
1533 String annotationId = varna.getAnnotation(jds).annotationId;
1534 ss.setAnnotationId(annotationId);
1535 ss.setViewerState(jarEntryName);
1536 ss.setGapped(model.gapped);
1537 ss.setTitle(model.title);
1538 rna.addSecondaryStructure(ss);
1547 * Copy the contents of a file to a new entry added to the output jar
1551 * @param jarEntryName
1553 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1554 String jarEntryName)
1556 DataInputStream dis = null;
1559 File file = new File(infilePath);
1560 if (file.exists() && jout != null)
1562 dis = new DataInputStream(new FileInputStream(file));
1563 byte[] data = new byte[(int) file.length()];
1564 dis.readFully(data);
1565 writeJarEntry(jout, jarEntryName, data);
1567 } catch (Exception ex)
1569 ex.printStackTrace();
1577 } catch (IOException e)
1586 * Write the data to a new entry of given name in the output jar file
1589 * @param jarEntryName
1591 * @throws IOException
1593 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1594 byte[] data) throws IOException
1598 System.out.println("Writing jar entry " + jarEntryName);
1599 jout.putNextEntry(new JarEntry(jarEntryName));
1600 DataOutputStream dout = new DataOutputStream(jout);
1601 dout.write(data, 0, data.length);
1608 * Save the state of a structure viewer
1613 * the archive XML element under which to save the state
1616 * @param matchedFile
1620 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1621 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1622 String matchedFile, StructureViewerBase viewFrame)
1624 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1627 * Look for any bindings for this viewer to the PDB file of interest
1628 * (including part matches excluding chain id)
1630 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1632 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1633 final String pdbId = pdbentry.getId();
1634 if (!pdbId.equals(entry.getId())
1635 && !(entry.getId().length() > 4 && entry.getId().toLowerCase()
1636 .startsWith(pdbId.toLowerCase())))
1639 * not interested in a binding to a different PDB entry here
1643 if (matchedFile == null)
1645 matchedFile = pdbentry.getFile();
1647 else if (!matchedFile.equals(pdbentry.getFile()))
1650 "Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1651 + pdbentry.getFile());
1655 // can get at it if the ID
1656 // match is ambiguous (e.g.
1659 for (int smap = 0; smap < viewFrame.getBinding()
1660 .getSequence()[peid].length; smap++)
1662 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1663 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1665 StructureState state = new StructureState();
1666 state.setVisible(true);
1667 state.setXpos(viewFrame.getX());
1668 state.setYpos(viewFrame.getY());
1669 state.setWidth(viewFrame.getWidth());
1670 state.setHeight(viewFrame.getHeight());
1671 final String viewId = viewFrame.getViewId();
1672 state.setViewId(viewId);
1673 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1674 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1675 state.setColourByJmol(viewFrame.isColouredByViewer());
1676 state.setType(viewFrame.getViewerType().toString());
1677 pdb.addStructureState(state);
1685 * Populates the AnnotationColours xml for save. This captures the settings of
1686 * the options in the 'Colour by Annotation' dialog.
1689 * @param userColours
1693 private AnnotationColours constructAnnotationColours(
1694 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1695 JalviewModelSequence jms)
1697 AnnotationColours ac = new AnnotationColours();
1698 ac.setAboveThreshold(acg.getAboveThreshold());
1699 ac.setThreshold(acg.getAnnotationThreshold());
1700 // 2.10.2 save annotationId (unique) not annotation label
1701 ac.setAnnotation(acg.getAnnotation().annotationId);
1702 if (acg.getBaseColour() instanceof UserColourScheme)
1705 setUserColourScheme(acg.getBaseColour(), userColours, jms));
1710 ColourSchemeProperty.getColourName(acg.getBaseColour()));
1713 ac.setMaxColour(acg.getMaxColour().getRGB());
1714 ac.setMinColour(acg.getMinColour().getRGB());
1715 ac.setPerSequence(acg.isSeqAssociated());
1716 ac.setPredefinedColours(acg.isPredefinedColours());
1720 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1721 IdentityHashMap<SequenceGroup, String> groupRefs,
1722 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1723 SequenceSet vamsasSet)
1726 for (int i = 0; i < aa.length; i++)
1728 Annotation an = new Annotation();
1730 AlignmentAnnotation annotation = aa[i];
1731 if (annotation.annotationId != null)
1733 annotationIds.put(annotation.annotationId, annotation);
1736 an.setId(annotation.annotationId);
1738 an.setVisible(annotation.visible);
1740 an.setDescription(annotation.description);
1742 if (annotation.sequenceRef != null)
1744 // 2.9 JAL-1781 xref on sequence id rather than name
1745 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1747 if (annotation.groupRef != null)
1749 String groupIdr = groupRefs.get(annotation.groupRef);
1750 if (groupIdr == null)
1752 // make a locally unique String
1753 groupRefs.put(annotation.groupRef,
1754 groupIdr = ("" + System.currentTimeMillis()
1755 + annotation.groupRef.getName()
1756 + groupRefs.size()));
1758 an.setGroupRef(groupIdr.toString());
1761 // store all visualization attributes for annotation
1762 an.setGraphHeight(annotation.graphHeight);
1763 an.setCentreColLabels(annotation.centreColLabels);
1764 an.setScaleColLabels(annotation.scaleColLabel);
1765 an.setShowAllColLabels(annotation.showAllColLabels);
1766 an.setBelowAlignment(annotation.belowAlignment);
1768 if (annotation.graph > 0)
1771 an.setGraphType(annotation.graph);
1772 an.setGraphGroup(annotation.graphGroup);
1773 if (annotation.getThreshold() != null)
1775 ThresholdLine line = new ThresholdLine();
1776 line.setLabel(annotation.getThreshold().label);
1777 line.setValue(annotation.getThreshold().value);
1778 line.setColour(annotation.getThreshold().colour.getRGB());
1779 an.setThresholdLine(line);
1787 an.setLabel(annotation.label);
1789 if (annotation == av.getAlignmentQualityAnnot()
1790 || annotation == av.getAlignmentConservationAnnotation()
1791 || annotation == av.getAlignmentConsensusAnnotation()
1792 || annotation.autoCalculated)
1794 // new way of indicating autocalculated annotation -
1795 an.setAutoCalculated(annotation.autoCalculated);
1797 if (annotation.hasScore())
1799 an.setScore(annotation.getScore());
1802 if (annotation.getCalcId() != null)
1804 calcIdSet.add(annotation.getCalcId());
1805 an.setCalcId(annotation.getCalcId());
1807 if (annotation.hasProperties())
1809 for (String pr : annotation.getProperties())
1811 Property prop = new Property();
1813 prop.setValue(annotation.getProperty(pr));
1814 an.addProperty(prop);
1818 AnnotationElement ae;
1819 if (annotation.annotations != null)
1821 an.setScoreOnly(false);
1822 for (int a = 0; a < annotation.annotations.length; a++)
1824 if ((annotation == null) || (annotation.annotations[a] == null))
1829 ae = new AnnotationElement();
1830 if (annotation.annotations[a].description != null)
1832 ae.setDescription(annotation.annotations[a].description);
1834 if (annotation.annotations[a].displayCharacter != null)
1836 ae.setDisplayCharacter(
1837 annotation.annotations[a].displayCharacter);
1840 if (!Float.isNaN(annotation.annotations[a].value))
1842 ae.setValue(annotation.annotations[a].value);
1846 if (annotation.annotations[a].secondaryStructure > ' ')
1848 ae.setSecondaryStructure(
1849 annotation.annotations[a].secondaryStructure + "");
1852 if (annotation.annotations[a].colour != null
1853 && annotation.annotations[a].colour != java.awt.Color.black)
1855 ae.setColour(annotation.annotations[a].colour.getRGB());
1858 an.addAnnotationElement(ae);
1859 if (annotation.autoCalculated)
1861 // only write one non-null entry into the annotation row -
1862 // sufficient to get the visualization attributes necessary to
1870 an.setScoreOnly(true);
1872 if (!storeDS || (storeDS && !annotation.autoCalculated))
1874 // skip autocalculated annotation - these are only provided for
1876 vamsasSet.addAnnotation(an);
1882 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1884 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1885 if (settings != null)
1887 CalcIdParam vCalcIdParam = new CalcIdParam();
1888 vCalcIdParam.setCalcId(calcId);
1889 vCalcIdParam.addServiceURL(settings.getServiceURI());
1890 // generic URI allowing a third party to resolve another instance of the
1891 // service used for this calculation
1892 for (String urls : settings.getServiceURLs())
1894 vCalcIdParam.addServiceURL(urls);
1896 vCalcIdParam.setVersion("1.0");
1897 if (settings.getPreset() != null)
1899 WsParamSetI setting = settings.getPreset();
1900 vCalcIdParam.setName(setting.getName());
1901 vCalcIdParam.setDescription(setting.getDescription());
1905 vCalcIdParam.setName("");
1906 vCalcIdParam.setDescription("Last used parameters");
1908 // need to be able to recover 1) settings 2) user-defined presets or
1909 // recreate settings from preset 3) predefined settings provided by
1910 // service - or settings that can be transferred (or discarded)
1911 vCalcIdParam.setParameters(
1912 settings.getWsParamFile().replace("\n", "|\\n|"));
1913 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1914 // todo - decide if updateImmediately is needed for any projects.
1916 return vCalcIdParam;
1921 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1924 if (calcIdParam.getVersion().equals("1.0"))
1926 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1927 .getPreferredServiceFor(calcIdParam.getServiceURL());
1928 if (service != null)
1930 WsParamSetI parmSet = null;
1933 parmSet = service.getParamStore().parseServiceParameterFile(
1934 calcIdParam.getName(), calcIdParam.getDescription(),
1935 calcIdParam.getServiceURL(),
1936 calcIdParam.getParameters().replace("|\\n|", "\n"));
1937 } catch (IOException x)
1939 warn("Couldn't parse parameter data for "
1940 + calcIdParam.getCalcId(), x);
1943 List<ArgumentI> argList = null;
1944 if (calcIdParam.getName().length() > 0)
1946 parmSet = service.getParamStore()
1947 .getPreset(calcIdParam.getName());
1948 if (parmSet != null)
1950 // TODO : check we have a good match with settings in AACon -
1951 // otherwise we'll need to create a new preset
1956 argList = parmSet.getArguments();
1959 AAConSettings settings = new AAConSettings(
1960 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1961 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1962 calcIdParam.isNeedsUpdate());
1967 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1971 throw new Error(MessageManager.formatMessage(
1972 "error.unsupported_version_calcIdparam", new Object[]
1973 { calcIdParam.toString() }));
1977 * External mapping between jalview objects and objects yielding a valid and
1978 * unique object ID string. This is null for normal Jalview project IO, but
1979 * non-null when a jalview project is being read or written as part of a
1982 IdentityHashMap jv2vobj = null;
1985 * Construct a unique ID for jvobj using either existing bindings or if none
1986 * exist, the result of the hashcode call for the object.
1989 * jalview data object
1990 * @return unique ID for referring to jvobj
1992 private String makeHashCode(Object jvobj, String altCode)
1994 if (jv2vobj != null)
1996 Object id = jv2vobj.get(jvobj);
1999 return id.toString();
2001 // check string ID mappings
2002 if (jvids2vobj != null && jvobj instanceof String)
2004 id = jvids2vobj.get(jvobj);
2008 return id.toString();
2010 // give up and warn that something has gone wrong
2011 warn("Cannot find ID for object in external mapping : " + jvobj);
2017 * return local jalview object mapped to ID, if it exists
2021 * @return null or object bound to idcode
2023 private Object retrieveExistingObj(String idcode)
2025 if (idcode != null && vobj2jv != null)
2027 return vobj2jv.get(idcode);
2033 * binding from ID strings from external mapping table to jalview data model
2036 private Hashtable vobj2jv;
2038 private Sequence createVamsasSequence(String id, SequenceI jds)
2040 return createVamsasSequence(true, id, jds, null);
2043 private Sequence createVamsasSequence(boolean recurse, String id,
2044 SequenceI jds, SequenceI parentseq)
2046 Sequence vamsasSeq = new Sequence();
2047 vamsasSeq.setId(id);
2048 vamsasSeq.setName(jds.getName());
2049 vamsasSeq.setSequence(jds.getSequenceAsString());
2050 vamsasSeq.setDescription(jds.getDescription());
2051 jalview.datamodel.DBRefEntry[] dbrefs = null;
2052 if (jds.getDatasetSequence() != null)
2054 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2058 // seqId==dsseqid so we can tell which sequences really are
2059 // dataset sequences only
2060 vamsasSeq.setDsseqid(id);
2061 dbrefs = jds.getDBRefs();
2062 if (parentseq == null)
2069 for (int d = 0; d < dbrefs.length; d++)
2071 DBRef dbref = new DBRef();
2072 dbref.setSource(dbrefs[d].getSource());
2073 dbref.setVersion(dbrefs[d].getVersion());
2074 dbref.setAccessionId(dbrefs[d].getAccessionId());
2075 if (dbrefs[d].hasMap())
2077 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2079 dbref.setMapping(mp);
2081 vamsasSeq.addDBRef(dbref);
2087 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2088 SequenceI parentseq, SequenceI jds, boolean recurse)
2091 if (jmp.getMap() != null)
2095 jalview.util.MapList mlst = jmp.getMap();
2096 List<int[]> r = mlst.getFromRanges();
2097 for (int[] range : r)
2099 MapListFrom mfrom = new MapListFrom();
2100 mfrom.setStart(range[0]);
2101 mfrom.setEnd(range[1]);
2102 mp.addMapListFrom(mfrom);
2104 r = mlst.getToRanges();
2105 for (int[] range : r)
2107 MapListTo mto = new MapListTo();
2108 mto.setStart(range[0]);
2109 mto.setEnd(range[1]);
2110 mp.addMapListTo(mto);
2112 mp.setMapFromUnit(mlst.getFromRatio());
2113 mp.setMapToUnit(mlst.getToRatio());
2114 if (jmp.getTo() != null)
2116 MappingChoice mpc = new MappingChoice();
2118 // check/create ID for the sequence referenced by getTo()
2121 SequenceI ps = null;
2122 if (parentseq != jmp.getTo()
2123 && parentseq.getDatasetSequence() != jmp.getTo())
2125 // chaining dbref rather than a handshaking one
2126 jmpid = seqHash(ps = jmp.getTo());
2130 jmpid = seqHash(ps = parentseq);
2132 mpc.setDseqFor(jmpid);
2133 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2135 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2136 seqRefIds.put(mpc.getDseqFor(), ps);
2140 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2143 mp.setMappingChoice(mpc);
2149 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2150 List<UserColourScheme> userColours, JalviewModelSequence jms)
2153 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2154 boolean newucs = false;
2155 if (!userColours.contains(ucs))
2157 userColours.add(ucs);
2160 id = "ucs" + userColours.indexOf(ucs);
2163 // actually create the scheme's entry in the XML model
2164 java.awt.Color[] colours = ucs.getColours();
2165 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2166 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2168 for (int i = 0; i < colours.length; i++)
2170 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2171 col.setName(ResidueProperties.aa[i]);
2172 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2173 jbucs.addColour(col);
2175 if (ucs.getLowerCaseColours() != null)
2177 colours = ucs.getLowerCaseColours();
2178 for (int i = 0; i < colours.length; i++)
2180 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2181 col.setName(ResidueProperties.aa[i].toLowerCase());
2182 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2183 jbucs.addColour(col);
2188 uc.setUserColourScheme(jbucs);
2189 jms.addUserColours(uc);
2195 jalview.schemes.UserColourScheme getUserColourScheme(
2196 JalviewModelSequence jms, String id)
2198 UserColours[] uc = jms.getUserColours();
2199 UserColours colours = null;
2201 for (int i = 0; i < uc.length; i++)
2203 if (uc[i].getId().equals(id))
2211 java.awt.Color[] newColours = new java.awt.Color[24];
2213 for (int i = 0; i < 24; i++)
2215 newColours[i] = new java.awt.Color(Integer.parseInt(
2216 colours.getUserColourScheme().getColour(i).getRGB(), 16));
2219 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2222 if (colours.getUserColourScheme().getColourCount() > 24)
2224 newColours = new java.awt.Color[23];
2225 for (int i = 0; i < 23; i++)
2227 newColours[i] = new java.awt.Color(Integer.parseInt(
2228 colours.getUserColourScheme().getColour(i + 24).getRGB(),
2231 ucs.setLowerCaseColours(newColours);
2238 * contains last error message (if any) encountered by XML loader.
2240 String errorMessage = null;
2243 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2244 * exceptions are raised during project XML parsing
2246 public boolean attemptversion1parse = true;
2249 * Load a jalview project archive from a jar file
2252 * - HTTP URL or filename
2254 public AlignFrame loadJalviewAlign(final String file)
2257 jalview.gui.AlignFrame af = null;
2261 // create list to store references for any new Jmol viewers created
2262 newStructureViewers = new Vector<>();
2263 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2264 // Workaround is to make sure caller implements the JarInputStreamProvider
2266 // so we can re-open the jar input stream for each entry.
2268 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2269 af = loadJalviewAlign(jprovider);
2270 af.setMenusForViewport();
2272 } catch (MalformedURLException e)
2274 errorMessage = "Invalid URL format for '" + file + "'";
2280 SwingUtilities.invokeAndWait(new Runnable()
2285 setLoadingFinishedForNewStructureViewers();
2288 } catch (Exception x)
2290 System.err.println("Error loading alignment: " + x.getMessage());
2296 private jarInputStreamProvider createjarInputStreamProvider(
2297 final String file) throws MalformedURLException
2300 errorMessage = null;
2301 uniqueSetSuffix = null;
2303 viewportsAdded.clear();
2304 frefedSequence = null;
2306 if (file.startsWith("http://"))
2308 url = new URL(file);
2310 final URL _url = url;
2311 return new jarInputStreamProvider()
2315 public JarInputStream getJarInputStream() throws IOException
2319 return new JarInputStream(_url.openStream());
2323 return new JarInputStream(new FileInputStream(file));
2328 public String getFilename()
2336 * Recover jalview session from a jalview project archive. Caller may
2337 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2338 * themselves. Any null fields will be initialised with default values,
2339 * non-null fields are left alone.
2344 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2346 errorMessage = null;
2347 if (uniqueSetSuffix == null)
2349 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2351 if (seqRefIds == null)
2355 AlignFrame af = null, _af = null;
2356 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<>();
2357 Map<String, AlignFrame> gatherToThisFrame = new HashMap<>();
2358 final String file = jprovider.getFilename();
2361 JarInputStream jin = null;
2362 JarEntry jarentry = null;
2367 jin = jprovider.getJarInputStream();
2368 for (int i = 0; i < entryCount; i++)
2370 jarentry = jin.getNextJarEntry();
2373 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2375 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2376 JalviewModel object = new JalviewModel();
2378 Unmarshaller unmar = new Unmarshaller(object);
2379 unmar.setValidation(false);
2380 object = (JalviewModel) unmar.unmarshal(in);
2381 if (true) // !skipViewport(object))
2383 _af = loadFromObject(object, file, true, jprovider);
2384 if (_af != null && object.getJalviewModelSequence()
2385 .getViewportCount() > 0)
2389 // store a reference to the first view
2392 if (_af.viewport.isGatherViewsHere())
2394 // if this is a gathered view, keep its reference since
2395 // after gathering views, only this frame will remain
2397 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2399 // Save dataset to register mappings once all resolved
2400 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2401 af.viewport.getAlignment().getDataset());
2406 else if (jarentry != null)
2408 // Some other file here.
2411 } while (jarentry != null);
2412 resolveFrefedSequences();
2413 } catch (IOException ex)
2415 ex.printStackTrace();
2416 errorMessage = "Couldn't locate Jalview XML file : " + file;
2418 "Exception whilst loading jalview XML file : " + ex + "\n");
2419 } catch (Exception ex)
2421 System.err.println("Parsing as Jalview Version 2 file failed.");
2422 ex.printStackTrace(System.err);
2423 if (attemptversion1parse)
2425 // Is Version 1 Jar file?
2428 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2429 } catch (Exception ex2)
2431 System.err.println("Exception whilst loading as jalviewXMLV1:");
2432 ex2.printStackTrace();
2436 if (Desktop.instance != null)
2438 Desktop.instance.stopLoading();
2442 System.out.println("Successfully loaded archive file");
2445 ex.printStackTrace();
2448 "Exception whilst loading jalview XML file : " + ex + "\n");
2449 } catch (OutOfMemoryError e)
2451 // Don't use the OOM Window here
2452 errorMessage = "Out of memory loading jalview XML file";
2453 System.err.println("Out of memory whilst loading jalview XML file");
2454 e.printStackTrace();
2458 * Regather multiple views (with the same sequence set id) to the frame (if
2459 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2460 * views instead of separate frames. Note this doesn't restore a state where
2461 * some expanded views in turn have tabbed views - the last "first tab" read
2462 * in will play the role of gatherer for all.
2464 for (AlignFrame fr : gatherToThisFrame.values())
2466 Desktop.instance.gatherViews(fr);
2469 restoreSplitFrames();
2470 for (AlignmentI ds : importedDatasets.keySet())
2472 if (ds.getCodonFrames() != null)
2474 StructureSelectionManager
2475 .getStructureSelectionManager(Desktop.instance)
2476 .registerMappings(ds.getCodonFrames());
2479 if (errorMessage != null)
2484 if (Desktop.instance != null)
2486 Desktop.instance.stopLoading();
2493 * Try to reconstruct and display SplitFrame windows, where each contains
2494 * complementary dna and protein alignments. Done by pairing up AlignFrame
2495 * objects (created earlier) which have complementary viewport ids associated.
2497 protected void restoreSplitFrames()
2499 List<SplitFrame> gatherTo = new ArrayList<>();
2500 List<AlignFrame> addedToSplitFrames = new ArrayList<>();
2501 Map<String, AlignFrame> dna = new HashMap<>();
2504 * Identify the DNA alignments
2506 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2509 AlignFrame af = candidate.getValue();
2510 if (af.getViewport().getAlignment().isNucleotide())
2512 dna.put(candidate.getKey().getId(), af);
2517 * Try to match up the protein complements
2519 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2522 AlignFrame af = candidate.getValue();
2523 if (!af.getViewport().getAlignment().isNucleotide())
2525 String complementId = candidate.getKey().getComplementId();
2526 // only non-null complements should be in the Map
2527 if (complementId != null && dna.containsKey(complementId))
2529 final AlignFrame dnaFrame = dna.get(complementId);
2530 SplitFrame sf = createSplitFrame(dnaFrame, af);
2531 addedToSplitFrames.add(dnaFrame);
2532 addedToSplitFrames.add(af);
2533 dnaFrame.setMenusForViewport();
2534 af.setMenusForViewport();
2535 if (af.viewport.isGatherViewsHere())
2544 * Open any that we failed to pair up (which shouldn't happen!) as
2545 * standalone AlignFrame's.
2547 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2550 AlignFrame af = candidate.getValue();
2551 if (!addedToSplitFrames.contains(af))
2553 Viewport view = candidate.getKey();
2554 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2556 af.setMenusForViewport();
2557 System.err.println("Failed to restore view " + view.getTitle()
2558 + " to split frame");
2563 * Gather back into tabbed views as flagged.
2565 for (SplitFrame sf : gatherTo)
2567 Desktop.instance.gatherViews(sf);
2570 splitFrameCandidates.clear();
2574 * Construct and display one SplitFrame holding DNA and protein alignments.
2577 * @param proteinFrame
2580 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2581 AlignFrame proteinFrame)
2583 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2584 String title = MessageManager.getString("label.linked_view_title");
2585 int width = (int) dnaFrame.getBounds().getWidth();
2586 int height = (int) (dnaFrame.getBounds().getHeight()
2587 + proteinFrame.getBounds().getHeight() + 50);
2590 * SplitFrame location is saved to both enclosed frames
2592 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2593 Desktop.addInternalFrame(splitFrame, title, width, height);
2596 * And compute cDNA consensus (couldn't do earlier with consensus as
2597 * mappings were not yet present)
2599 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2605 * check errorMessage for a valid error message and raise an error box in the
2606 * GUI or write the current errorMessage to stderr and then clear the error
2609 protected void reportErrors()
2611 reportErrors(false);
2614 protected void reportErrors(final boolean saving)
2616 if (errorMessage != null)
2618 final String finalErrorMessage = errorMessage;
2621 javax.swing.SwingUtilities.invokeLater(new Runnable()
2626 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2628 "Error " + (saving ? "saving" : "loading")
2630 JvOptionPane.WARNING_MESSAGE);
2636 System.err.println("Problem loading Jalview file: " + errorMessage);
2639 errorMessage = null;
2642 Map<String, String> alreadyLoadedPDB = new HashMap<>();
2645 * when set, local views will be updated from view stored in JalviewXML
2646 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2647 * sync if this is set to true.
2649 private final boolean updateLocalViews = false;
2652 * Returns the path to a temporary file holding the PDB file for the given PDB
2653 * id. The first time of asking, searches for a file of that name in the
2654 * Jalview project jar, and copies it to a new temporary file. Any repeat
2655 * requests just return the path to the file previously created.
2661 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2664 if (alreadyLoadedPDB.containsKey(pdbId))
2666 return alreadyLoadedPDB.get(pdbId).toString();
2669 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2671 if (tempFile != null)
2673 alreadyLoadedPDB.put(pdbId, tempFile);
2679 * Copies the jar entry of given name to a new temporary file and returns the
2680 * path to the file, or null if the entry is not found.
2683 * @param jarEntryName
2685 * a prefix for the temporary file name, must be at least three
2688 * null or original file - so new file can be given the same suffix
2692 protected String copyJarEntry(jarInputStreamProvider jprovider,
2693 String jarEntryName, String prefix, String origFile)
2695 BufferedReader in = null;
2696 PrintWriter out = null;
2697 String suffix = ".tmp";
2698 if (origFile == null)
2700 origFile = jarEntryName;
2702 int sfpos = origFile.lastIndexOf(".");
2703 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2705 suffix = "." + origFile.substring(sfpos + 1);
2709 JarInputStream jin = jprovider.getJarInputStream();
2711 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2712 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2713 * FileInputStream(jprovider)); }
2716 JarEntry entry = null;
2719 entry = jin.getNextJarEntry();
2720 } while (entry != null && !entry.getName().equals(jarEntryName));
2723 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2724 File outFile = File.createTempFile(prefix, suffix);
2725 outFile.deleteOnExit();
2726 out = new PrintWriter(new FileOutputStream(outFile));
2729 while ((data = in.readLine()) != null)
2734 String t = outFile.getAbsolutePath();
2739 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2741 } catch (Exception ex)
2743 ex.printStackTrace();
2751 } catch (IOException e)
2765 private class JvAnnotRow
2767 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2774 * persisted version of annotation row from which to take vis properties
2776 public jalview.datamodel.AlignmentAnnotation template;
2779 * original position of the annotation row in the alignment
2785 * Load alignment frame from jalview XML DOM object
2790 * filename source string
2791 * @param loadTreesAndStructures
2792 * when false only create Viewport
2794 * data source provider
2795 * @return alignment frame created from view stored in DOM
2797 AlignFrame loadFromObject(JalviewModel object, String file,
2798 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2800 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2801 Sequence[] vamsasSeq = vamsasSet.getSequence();
2803 JalviewModelSequence jms = object.getJalviewModelSequence();
2805 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2808 // ////////////////////////////////
2811 List<SequenceI> hiddenSeqs = null;
2813 List<SequenceI> tmpseqs = new ArrayList<>();
2815 boolean multipleView = false;
2816 SequenceI referenceseqForView = null;
2817 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2818 int vi = 0; // counter in vamsasSeq array
2819 for (int i = 0; i < jseqs.length; i++)
2821 String seqId = jseqs[i].getId();
2823 SequenceI tmpSeq = seqRefIds.get(seqId);
2826 if (!incompleteSeqs.containsKey(seqId))
2828 // may not need this check, but keep it for at least 2.9,1 release
2829 if (tmpSeq.getStart() != jseqs[i].getStart()
2830 || tmpSeq.getEnd() != jseqs[i].getEnd())
2833 "Warning JAL-2154 regression: updating start/end for sequence "
2834 + tmpSeq.toString() + " to " + jseqs[i]);
2839 incompleteSeqs.remove(seqId);
2841 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2843 // most likely we are reading a dataset XML document so
2844 // update from vamsasSeq section of XML for this sequence
2845 tmpSeq.setName(vamsasSeq[vi].getName());
2846 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2847 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2852 // reading multiple views, so vamsasSeq set is a subset of JSeq
2853 multipleView = true;
2855 tmpSeq.setStart(jseqs[i].getStart());
2856 tmpSeq.setEnd(jseqs[i].getEnd());
2857 tmpseqs.add(tmpSeq);
2861 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2862 vamsasSeq[vi].getSequence());
2863 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2864 tmpSeq.setStart(jseqs[i].getStart());
2865 tmpSeq.setEnd(jseqs[i].getEnd());
2866 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2867 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2868 tmpseqs.add(tmpSeq);
2872 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2874 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2877 if (jseqs[i].getHidden())
2879 if (hiddenSeqs == null)
2881 hiddenSeqs = new ArrayList<>();
2884 hiddenSeqs.add(tmpSeq);
2889 // Create the alignment object from the sequence set
2890 // ///////////////////////////////
2891 SequenceI[] orderedSeqs = tmpseqs
2892 .toArray(new SequenceI[tmpseqs.size()]);
2894 AlignmentI al = null;
2895 // so we must create or recover the dataset alignment before going further
2896 // ///////////////////////////////
2897 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2899 // older jalview projects do not have a dataset - so creat alignment and
2901 al = new Alignment(orderedSeqs);
2902 al.setDataset(null);
2906 boolean isdsal = object.getJalviewModelSequence()
2907 .getViewportCount() == 0;
2910 // we are importing a dataset record, so
2911 // recover reference to an alignment already materialsed as dataset
2912 al = getDatasetFor(vamsasSet.getDatasetId());
2916 // materialse the alignment
2917 al = new Alignment(orderedSeqs);
2921 addDatasetRef(vamsasSet.getDatasetId(), al);
2924 // finally, verify all data in vamsasSet is actually present in al
2925 // passing on flag indicating if it is actually a stored dataset
2926 recoverDatasetFor(vamsasSet, al, isdsal);
2929 if (referenceseqForView != null)
2931 al.setSeqrep(referenceseqForView);
2933 // / Add the alignment properties
2934 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2936 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2937 al.setProperty(ssp.getKey(), ssp.getValue());
2940 // ///////////////////////////////
2942 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2945 // load sequence features, database references and any associated PDB
2946 // structures for the alignment
2948 // prior to 2.10, this part would only be executed the first time a
2949 // sequence was encountered, but not afterwards.
2950 // now, for 2.10 projects, this is also done if the xml doc includes
2951 // dataset sequences not actually present in any particular view.
2953 for (int i = 0; i < vamsasSeq.length; i++)
2955 if (jseqs[i].getFeaturesCount() > 0)
2957 Features[] features = jseqs[i].getFeatures();
2958 for (int f = 0; f < features.length; f++)
2960 SequenceFeature sf = new SequenceFeature(features[f].getType(),
2961 features[f].getDescription(), features[f].getBegin(),
2962 features[f].getEnd(), features[f].getScore(),
2963 features[f].getFeatureGroup());
2964 sf.setStatus(features[f].getStatus());
2965 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2967 OtherData keyValue = features[f].getOtherData(od);
2968 if (keyValue.getKey().startsWith("LINK"))
2970 sf.addLink(keyValue.getValue());
2974 sf.setValue(keyValue.getKey(), keyValue.getValue());
2978 // adds feature to datasequence's feature set (since Jalview 2.10)
2979 al.getSequenceAt(i).addSequenceFeature(sf);
2982 if (vamsasSeq[i].getDBRefCount() > 0)
2984 // adds dbrefs to datasequence's set (since Jalview 2.10)
2986 al.getSequenceAt(i).getDatasetSequence() == null
2987 ? al.getSequenceAt(i)
2988 : al.getSequenceAt(i).getDatasetSequence(),
2991 if (jseqs[i].getPdbidsCount() > 0)
2993 Pdbids[] ids = jseqs[i].getPdbids();
2994 for (int p = 0; p < ids.length; p++)
2996 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2997 entry.setId(ids[p].getId());
2998 if (ids[p].getType() != null)
3000 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3002 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3006 entry.setType(PDBEntry.Type.FILE);
3009 // jprovider is null when executing 'New View'
3010 if (ids[p].getFile() != null && jprovider != null)
3012 if (!pdbloaded.containsKey(ids[p].getFile()))
3014 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3019 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3022 if (ids[p].getPdbentryItem() != null)
3024 for (PdbentryItem item : ids[p].getPdbentryItem())
3026 for (Property pr : item.getProperty())
3028 entry.setProperty(pr.getName(), pr.getValue());
3032 StructureSelectionManager
3033 .getStructureSelectionManager(Desktop.instance)
3034 .registerPDBEntry(entry);
3035 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3036 if (al.getSequenceAt(i).getDatasetSequence() != null)
3038 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3042 al.getSequenceAt(i).addPDBId(entry);
3047 } // end !multipleview
3049 // ///////////////////////////////
3050 // LOAD SEQUENCE MAPPINGS
3052 if (vamsasSet.getAlcodonFrameCount() > 0)
3054 // TODO Potentially this should only be done once for all views of an
3056 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3057 for (int i = 0; i < alc.length; i++)
3059 AlignedCodonFrame cf = new AlignedCodonFrame();
3060 if (alc[i].getAlcodMapCount() > 0)
3062 AlcodMap[] maps = alc[i].getAlcodMap();
3063 for (int m = 0; m < maps.length; m++)
3065 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3067 jalview.datamodel.Mapping mapping = null;
3068 // attach to dna sequence reference.
3069 if (maps[m].getMapping() != null)
3071 mapping = addMapping(maps[m].getMapping());
3072 if (dnaseq != null && mapping.getTo() != null)
3074 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3080 newAlcodMapRef(maps[m].getDnasq(), cf, mapping));
3084 al.addCodonFrame(cf);
3089 // ////////////////////////////////
3091 List<JvAnnotRow> autoAlan = new ArrayList<>();
3094 * store any annotations which forward reference a group's ID
3096 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<>();
3098 if (vamsasSet.getAnnotationCount() > 0)
3100 Annotation[] an = vamsasSet.getAnnotation();
3102 for (int i = 0; i < an.length; i++)
3104 Annotation annotation = an[i];
3107 * test if annotation is automatically calculated for this view only
3109 boolean autoForView = false;
3110 if (annotation.getLabel().equals("Quality")
3111 || annotation.getLabel().equals("Conservation")
3112 || annotation.getLabel().equals("Consensus"))
3114 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3116 if (!annotation.hasAutoCalculated())
3118 annotation.setAutoCalculated(true);
3121 if (autoForView || (annotation.hasAutoCalculated()
3122 && annotation.isAutoCalculated()))
3124 // remove ID - we don't recover annotation from other views for
3125 // view-specific annotation
3126 annotation.setId(null);
3129 // set visiblity for other annotation in this view
3130 String annotationId = annotation.getId();
3131 if (annotationId != null && annotationIds.containsKey(annotationId))
3133 AlignmentAnnotation jda = annotationIds.get(annotationId);
3134 // in principle Visible should always be true for annotation displayed
3135 // in multiple views
3136 if (annotation.hasVisible())
3138 jda.visible = annotation.getVisible();
3141 al.addAnnotation(jda);
3145 // Construct new annotation from model.
3146 AnnotationElement[] ae = annotation.getAnnotationElement();
3147 jalview.datamodel.Annotation[] anot = null;
3148 java.awt.Color firstColour = null;
3150 if (!annotation.getScoreOnly())
3152 anot = new jalview.datamodel.Annotation[al.getWidth()];
3153 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3155 anpos = ae[aa].getPosition();
3157 if (anpos >= anot.length)
3162 anot[anpos] = new jalview.datamodel.Annotation(
3164 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3165 (ae[aa].getSecondaryStructure() == null
3166 || ae[aa].getSecondaryStructure().length() == 0)
3168 : ae[aa].getSecondaryStructure()
3173 // JBPNote: Consider verifying dataflow for IO of secondary
3174 // structure annotation read from Stockholm files
3175 // this was added to try to ensure that
3176 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3178 // anot[ae[aa].getPosition()].displayCharacter = "";
3180 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3181 if (firstColour == null)
3183 firstColour = anot[anpos].colour;
3187 jalview.datamodel.AlignmentAnnotation jaa = null;
3189 if (annotation.getGraph())
3191 float llim = 0, hlim = 0;
3192 // if (autoForView || an[i].isAutoCalculated()) {
3195 jaa = new jalview.datamodel.AlignmentAnnotation(
3196 annotation.getLabel(), annotation.getDescription(), anot,
3197 llim, hlim, annotation.getGraphType());
3199 jaa.graphGroup = annotation.getGraphGroup();
3200 jaa._linecolour = firstColour;
3201 if (annotation.getThresholdLine() != null)
3203 jaa.setThreshold(new jalview.datamodel.GraphLine(
3204 annotation.getThresholdLine().getValue(),
3205 annotation.getThresholdLine().getLabel(),
3207 annotation.getThresholdLine().getColour())));
3210 if (autoForView || annotation.isAutoCalculated())
3212 // Hardwire the symbol display line to ensure that labels for
3213 // histograms are displayed
3219 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3220 an[i].getDescription(), anot);
3221 jaa._linecolour = firstColour;
3223 // register new annotation
3224 if (an[i].getId() != null)
3226 annotationIds.put(an[i].getId(), jaa);
3227 jaa.annotationId = an[i].getId();
3229 // recover sequence association
3230 String sequenceRef = an[i].getSequenceRef();
3231 if (sequenceRef != null)
3233 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3234 SequenceI sequence = seqRefIds.get(sequenceRef);
3235 if (sequence == null)
3237 // in pre-2.9 projects sequence ref is to sequence name
3238 sequence = al.findName(sequenceRef);
3240 if (sequence != null)
3242 jaa.createSequenceMapping(sequence, 1, true);
3243 sequence.addAlignmentAnnotation(jaa);
3246 // and make a note of any group association
3247 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3249 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3250 .get(an[i].getGroupRef());
3253 aal = new ArrayList<>();
3254 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3259 if (an[i].hasScore())
3261 jaa.setScore(an[i].getScore());
3263 if (an[i].hasVisible())
3265 jaa.visible = an[i].getVisible();
3268 if (an[i].hasCentreColLabels())
3270 jaa.centreColLabels = an[i].getCentreColLabels();
3273 if (an[i].hasScaleColLabels())
3275 jaa.scaleColLabel = an[i].getScaleColLabels();
3277 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3279 // newer files have an 'autoCalculated' flag and store calculation
3280 // state in viewport properties
3281 jaa.autoCalculated = true; // means annotation will be marked for
3282 // update at end of load.
3284 if (an[i].hasGraphHeight())
3286 jaa.graphHeight = an[i].getGraphHeight();
3288 if (an[i].hasBelowAlignment())
3290 jaa.belowAlignment = an[i].isBelowAlignment();
3292 jaa.setCalcId(an[i].getCalcId());
3293 if (an[i].getPropertyCount() > 0)
3295 for (jalview.schemabinding.version2.Property prop : an[i]
3298 jaa.setProperty(prop.getName(), prop.getValue());
3301 if (jaa.autoCalculated)
3303 autoAlan.add(new JvAnnotRow(i, jaa));
3306 // if (!autoForView)
3308 // add autocalculated group annotation and any user created annotation
3310 al.addAnnotation(jaa);
3314 // ///////////////////////
3316 // Create alignment markup and styles for this view
3317 if (jms.getJGroupCount() > 0)
3319 JGroup[] groups = jms.getJGroup();
3320 boolean addAnnotSchemeGroup = false;
3321 for (int i = 0; i < groups.length; i++)
3323 JGroup jGroup = groups[i];
3324 ColourSchemeI cs = null;
3325 if (jGroup.getColour() != null)
3327 if (jGroup.getColour().startsWith("ucs"))
3329 cs = getUserColourScheme(jms, jGroup.getColour());
3331 else if (jGroup.getColour().equals("AnnotationColourGradient")
3332 && jGroup.getAnnotationColours() != null)
3334 addAnnotSchemeGroup = true;
3338 cs = ColourSchemeProperty.getColourScheme(al,
3339 jGroup.getColour());
3342 int pidThreshold = jGroup.getPidThreshold();
3344 Vector<SequenceI> seqs = new Vector<>();
3346 for (int s = 0; s < jGroup.getSeqCount(); s++)
3348 String seqId = jGroup.getSeq(s) + "";
3349 SequenceI ts = seqRefIds.get(seqId);
3353 seqs.addElement(ts);
3357 if (seqs.size() < 1)
3362 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3363 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3364 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3365 sg.getGroupColourScheme().setThreshold(pidThreshold, true);
3366 sg.getGroupColourScheme()
3367 .setConservationInc(jGroup.getConsThreshold());
3368 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3370 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3371 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3372 sg.setShowNonconserved(
3373 jGroup.hasShowUnconserved() ? jGroup.isShowUnconserved()
3375 sg.thresholdTextColour = jGroup.getTextColThreshold();
3376 if (jGroup.hasShowConsensusHistogram())
3378 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3381 if (jGroup.hasShowSequenceLogo())
3383 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3385 if (jGroup.hasNormaliseSequenceLogo())
3387 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3389 if (jGroup.hasIgnoreGapsinConsensus())
3391 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3393 if (jGroup.getConsThreshold() != 0)
3395 Conservation c = new Conservation("All", sg.getSequences(null), 0,
3398 c.verdict(false, 25);
3399 sg.cs.setConservation(c);
3402 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3404 // re-instate unique group/annotation row reference
3405 List<AlignmentAnnotation> jaal = groupAnnotRefs
3406 .get(jGroup.getId());
3409 for (AlignmentAnnotation jaa : jaal)
3412 if (jaa.autoCalculated)
3414 // match up and try to set group autocalc alignment row for this
3416 if (jaa.label.startsWith("Consensus for "))
3418 sg.setConsensus(jaa);
3420 // match up and try to set group autocalc alignment row for this
3422 if (jaa.label.startsWith("Conservation for "))
3424 sg.setConservationRow(jaa);
3431 if (addAnnotSchemeGroup)
3433 // reconstruct the annotation colourscheme
3434 sg.setColourScheme(constructAnnotationColour(
3435 jGroup.getAnnotationColours(), null, al, jms, false));
3441 // only dataset in this model, so just return.
3444 // ///////////////////////////////
3447 // If we just load in the same jar file again, the sequenceSetId
3448 // will be the same, and we end up with multiple references
3449 // to the same sequenceSet. We must modify this id on load
3450 // so that each load of the file gives a unique id
3451 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3452 String viewId = (view.getId() == null ? null
3453 : view.getId() + uniqueSetSuffix);
3454 AlignFrame af = null;
3455 AlignViewport av = null;
3456 // now check to see if we really need to create a new viewport.
3457 if (multipleView && viewportsAdded.size() == 0)
3459 // We recovered an alignment for which a viewport already exists.
3460 // TODO: fix up any settings necessary for overlaying stored state onto
3461 // state recovered from another document. (may not be necessary).
3462 // we may need a binding from a viewport in memory to one recovered from
3464 // and then recover its containing af to allow the settings to be applied.
3465 // TODO: fix for vamsas demo
3467 "About to recover a viewport for existing alignment: Sequence set ID is "
3469 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3470 if (seqsetobj != null)
3472 if (seqsetobj instanceof String)
3474 uniqueSeqSetId = (String) seqsetobj;
3476 "Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3482 "Warning : Collision between sequence set ID string and existing jalview object mapping.");
3488 * indicate that annotation colours are applied across all groups (pre
3489 * Jalview 2.8.1 behaviour)
3491 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan("2.8.1",
3492 object.getVersion());
3494 AlignmentPanel ap = null;
3495 boolean isnewview = true;
3498 // Check to see if this alignment already has a view id == viewId
3499 jalview.gui.AlignmentPanel views[] = Desktop
3500 .getAlignmentPanels(uniqueSeqSetId);
3501 if (views != null && views.length > 0)
3503 for (int v = 0; v < views.length; v++)
3505 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3507 // recover the existing alignpanel, alignframe, viewport
3508 af = views[v].alignFrame;
3511 // TODO: could even skip resetting view settings if we don't want to
3512 // change the local settings from other jalview processes
3521 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3522 uniqueSeqSetId, viewId, autoAlan);
3528 * Load any trees, PDB structures and viewers
3530 * Not done if flag is false (when this method is used for New View)
3532 if (loadTreesAndStructures)
3534 loadTrees(jms, view, af, av, ap);
3535 loadPDBStructures(jprovider, jseqs, af, ap);
3536 loadRnaViewers(jprovider, jseqs, ap);
3538 // and finally return.
3543 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3544 * panel is restored from separate jar entries, two (gapped and trimmed) per
3545 * sequence and secondary structure.
3547 * Currently each viewer shows just one sequence and structure (gapped and
3548 * trimmed), however this method is designed to support multiple sequences or
3549 * structures in viewers if wanted in future.
3555 private void loadRnaViewers(jarInputStreamProvider jprovider,
3556 JSeq[] jseqs, AlignmentPanel ap)
3559 * scan the sequences for references to viewers; create each one the first
3560 * time it is referenced, add Rna models to existing viewers
3562 for (JSeq jseq : jseqs)
3564 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3566 RnaViewer viewer = jseq.getRnaViewer(i);
3567 AppVarna appVarna = findOrCreateVarnaViewer(viewer, uniqueSetSuffix,
3570 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3572 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3573 SequenceI seq = seqRefIds.get(jseq.getId());
3574 AlignmentAnnotation ann = this.annotationIds
3575 .get(ss.getAnnotationId());
3578 * add the structure to the Varna display (with session state copied
3579 * from the jar to a temporary file)
3581 boolean gapped = ss.isGapped();
3582 String rnaTitle = ss.getTitle();
3583 String sessionState = ss.getViewerState();
3584 String tempStateFile = copyJarEntry(jprovider, sessionState,
3586 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3587 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3589 appVarna.setInitialSelection(viewer.getSelectedRna());
3595 * Locate and return an already instantiated matching AppVarna, or create one
3599 * @param viewIdSuffix
3603 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3604 String viewIdSuffix, AlignmentPanel ap)
3607 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3608 * if load is repeated
3610 String postLoadId = viewer.getViewId() + viewIdSuffix;
3611 for (JInternalFrame frame : getAllFrames())
3613 if (frame instanceof AppVarna)
3615 AppVarna varna = (AppVarna) frame;
3616 if (postLoadId.equals(varna.getViewId()))
3618 // this viewer is already instantiated
3619 // could in future here add ap as another 'parent' of the
3620 // AppVarna window; currently just 1-to-many
3627 * viewer not found - make it
3629 RnaViewerModel model = new RnaViewerModel(postLoadId, viewer.getTitle(),
3630 viewer.getXpos(), viewer.getYpos(), viewer.getWidth(),
3631 viewer.getHeight(), viewer.getDividerLocation());
3632 AppVarna varna = new AppVarna(model, ap);
3638 * Load any saved trees
3646 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3647 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3649 // TODO result of automated refactoring - are all these parameters needed?
3652 for (int t = 0; t < jms.getTreeCount(); t++)
3655 Tree tree = jms.getTree(t);
3657 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3660 tp = af.showNewickTree(
3661 new jalview.io.NewickFile(tree.getNewick()),
3662 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3663 tree.getXpos(), tree.getYpos());
3664 if (tree.getId() != null)
3666 // perhaps bind the tree id to something ?
3671 // update local tree attributes ?
3672 // TODO: should check if tp has been manipulated by user - if so its
3673 // settings shouldn't be modified
3674 tp.setTitle(tree.getTitle());
3675 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(),
3676 tree.getWidth(), tree.getHeight()));
3677 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3680 tp.treeCanvas.av = av; // af.viewport;
3681 tp.treeCanvas.ap = ap; // af.alignPanel;
3686 warn("There was a problem recovering stored Newick tree: \n"
3687 + tree.getNewick());
3691 tp.fitToWindow.setState(tree.getFitToWindow());
3692 tp.fitToWindow_actionPerformed(null);
3694 if (tree.getFontName() != null)
3696 tp.setTreeFont(new java.awt.Font(tree.getFontName(),
3697 tree.getFontStyle(), tree.getFontSize()));
3701 tp.setTreeFont(new java.awt.Font(view.getFontName(),
3702 view.getFontStyle(), tree.getFontSize()));
3705 tp.showPlaceholders(tree.getMarkUnlinked());
3706 tp.showBootstrap(tree.getShowBootstrap());
3707 tp.showDistances(tree.getShowDistances());
3709 tp.treeCanvas.threshold = tree.getThreshold();
3711 if (tree.getCurrentTree())
3713 af.viewport.setCurrentTree(tp.getTree());
3717 } catch (Exception ex)
3719 ex.printStackTrace();
3724 * Load and link any saved structure viewers.
3731 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3732 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3735 * Run through all PDB ids on the alignment, and collect mappings between
3736 * distinct view ids and all sequences referring to that view.
3738 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<>();
3740 for (int i = 0; i < jseqs.length; i++)
3742 if (jseqs[i].getPdbidsCount() > 0)
3744 Pdbids[] ids = jseqs[i].getPdbids();
3745 for (int p = 0; p < ids.length; p++)
3747 final int structureStateCount = ids[p].getStructureStateCount();
3748 for (int s = 0; s < structureStateCount; s++)
3750 // check to see if we haven't already created this structure view
3751 final StructureState structureState = ids[p]
3752 .getStructureState(s);
3753 String sviewid = (structureState.getViewId() == null) ? null
3754 : structureState.getViewId() + uniqueSetSuffix;
3755 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3756 // Originally : ids[p].getFile()
3757 // : TODO: verify external PDB file recovery still works in normal
3758 // jalview project load
3759 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3761 jpdb.setId(ids[p].getId());
3763 int x = structureState.getXpos();
3764 int y = structureState.getYpos();
3765 int width = structureState.getWidth();
3766 int height = structureState.getHeight();
3768 // Probably don't need to do this anymore...
3769 // Desktop.desktop.getComponentAt(x, y);
3770 // TODO: NOW: check that this recovers the PDB file correctly.
3771 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3773 jalview.datamodel.SequenceI seq = seqRefIds
3774 .get(jseqs[i].getId() + "");
3775 if (sviewid == null)
3777 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width + ","
3780 if (!structureViewers.containsKey(sviewid))
3782 structureViewers.put(sviewid,
3783 new StructureViewerModel(x, y, width, height, false,
3784 false, true, structureState.getViewId(),
3785 structureState.getType()));
3786 // Legacy pre-2.7 conversion JAL-823 :
3787 // do not assume any view has to be linked for colour by
3791 // assemble String[] { pdb files }, String[] { id for each
3792 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3793 // seqs_file 2}, boolean[] {
3794 // linkAlignPanel,superposeWithAlignpanel}} from hash
3795 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3796 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3797 | (structureState.hasAlignwithAlignPanel()
3798 ? structureState.getAlignwithAlignPanel()
3802 * Default colour by linked panel to false if not specified (e.g.
3803 * for pre-2.7 projects)
3805 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3806 colourWithAlignPanel |= (structureState
3807 .hasColourwithAlignPanel()
3808 ? structureState.getColourwithAlignPanel()
3810 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3813 * Default colour by viewer to true if not specified (e.g. for
3816 boolean colourByViewer = jmoldat.isColourByViewer();
3817 colourByViewer &= structureState.hasColourByJmol()
3818 ? structureState.getColourByJmol()
3820 jmoldat.setColourByViewer(colourByViewer);
3822 if (jmoldat.getStateData().length() < structureState
3823 .getContent().length())
3826 jmoldat.setStateData(structureState.getContent());
3829 if (ids[p].getFile() != null)
3831 File mapkey = new File(ids[p].getFile());
3832 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3833 if (seqstrmaps == null)
3835 jmoldat.getFileData().put(mapkey,
3836 seqstrmaps = jmoldat.new StructureData(pdbFile,
3839 if (!seqstrmaps.getSeqList().contains(seq))
3841 seqstrmaps.getSeqList().add(seq);
3847 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");
3854 // Instantiate the associated structure views
3855 for (Entry<String, StructureViewerModel> entry : structureViewers
3860 createOrLinkStructureViewer(entry, af, ap, jprovider);
3861 } catch (Exception e)
3864 "Error loading structure viewer: " + e.getMessage());
3865 // failed - try the next one
3877 protected void createOrLinkStructureViewer(
3878 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3879 AlignmentPanel ap, jarInputStreamProvider jprovider)
3881 final StructureViewerModel stateData = viewerData.getValue();
3884 * Search for any viewer windows already open from other alignment views
3885 * that exactly match the stored structure state
3887 StructureViewerBase comp = findMatchingViewer(viewerData);
3891 linkStructureViewer(ap, comp, stateData);
3896 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3897 * "viewer_"+stateData.viewId
3899 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3901 createChimeraViewer(viewerData, af, jprovider);
3906 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3908 createJmolViewer(viewerData, af, jprovider);
3913 * Create a new Chimera viewer.
3919 protected void createChimeraViewer(
3920 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3921 jarInputStreamProvider jprovider)
3923 StructureViewerModel data = viewerData.getValue();
3924 String chimeraSessionFile = data.getStateData();
3927 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3929 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3930 * 'uniquified' sviewid used to reconstruct the viewer here
3932 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3933 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3936 Set<Entry<File, StructureData>> fileData = data.getFileData()
3938 List<PDBEntry> pdbs = new ArrayList<>();
3939 List<SequenceI[]> allseqs = new ArrayList<>();
3940 for (Entry<File, StructureData> pdb : fileData)
3942 String filePath = pdb.getValue().getFilePath();
3943 String pdbId = pdb.getValue().getPdbId();
3944 // pdbs.add(new PDBEntry(filePath, pdbId));
3945 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3946 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3947 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3951 boolean colourByChimera = data.isColourByViewer();
3952 boolean colourBySequence = data.isColourWithAlignPanel();
3954 // TODO use StructureViewer as a factory here, see JAL-1761
3955 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3956 final SequenceI[][] seqsArray = allseqs
3957 .toArray(new SequenceI[allseqs.size()][]);
3958 String newViewId = viewerData.getKey();
3960 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3961 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3962 colourBySequence, newViewId);
3963 cvf.setSize(data.getWidth(), data.getHeight());
3964 cvf.setLocation(data.getX(), data.getY());
3968 * Create a new Jmol window. First parse the Jmol state to translate filenames
3969 * loaded into the view, and record the order in which files are shown in the
3970 * Jmol view, so we can add the sequence mappings in same order.
3976 protected void createJmolViewer(
3977 final Entry<String, StructureViewerModel> viewerData,
3978 AlignFrame af, jarInputStreamProvider jprovider)
3980 final StructureViewerModel svattrib = viewerData.getValue();
3981 String state = svattrib.getStateData();
3984 * Pre-2.9: state element value is the Jmol state string
3986 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3989 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3991 state = readJarEntry(jprovider,
3992 getViewerJarEntryName(svattrib.getViewId()));
3995 List<String> pdbfilenames = new ArrayList<>();
3996 List<SequenceI[]> seqmaps = new ArrayList<>();
3997 List<String> pdbids = new ArrayList<>();
3998 StringBuilder newFileLoc = new StringBuilder(64);
3999 int cp = 0, ncp, ecp;
4000 Map<File, StructureData> oldFiles = svattrib.getFileData();
4001 while ((ncp = state.indexOf("load ", cp)) > -1)
4005 // look for next filename in load statement
4006 newFileLoc.append(state.substring(cp,
4007 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4008 String oldfilenam = state.substring(ncp,
4009 ecp = state.indexOf("\"", ncp));
4010 // recover the new mapping data for this old filename
4011 // have to normalize filename - since Jmol and jalview do
4013 // translation differently.
4014 StructureData filedat = oldFiles.get(new File(oldfilenam));
4015 if (filedat == null)
4017 String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
4018 filedat = oldFiles.get(new File(reformatedOldFilename));
4020 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4021 pdbfilenames.add(filedat.getFilePath());
4022 pdbids.add(filedat.getPdbId());
4023 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4024 newFileLoc.append("\"");
4025 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4026 // look for next file statement.
4027 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4031 // just append rest of state
4032 newFileLoc.append(state.substring(cp));
4036 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4037 newFileLoc = new StringBuilder(state);
4038 newFileLoc.append("; load append ");
4039 for (File id : oldFiles.keySet())
4041 // add this and any other pdb files that should be present in
4043 StructureData filedat = oldFiles.get(id);
4044 newFileLoc.append(filedat.getFilePath());
4045 pdbfilenames.add(filedat.getFilePath());
4046 pdbids.add(filedat.getPdbId());
4047 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4048 newFileLoc.append(" \"");
4049 newFileLoc.append(filedat.getFilePath());
4050 newFileLoc.append("\"");
4053 newFileLoc.append(";");
4056 if (newFileLoc.length() == 0)
4060 int histbug = newFileLoc.indexOf("history = ");
4064 * change "history = [true|false];" to "history = [1|0];"
4067 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4068 String val = (diff == -1) ? null
4069 : newFileLoc.substring(histbug, diff);
4070 if (val != null && val.length() >= 4)
4072 if (val.contains("e")) // eh? what can it be?
4074 if (val.trim().equals("true"))
4082 newFileLoc.replace(histbug, diff, val);
4087 final String[] pdbf = pdbfilenames
4088 .toArray(new String[pdbfilenames.size()]);
4089 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4090 final SequenceI[][] sq = seqmaps
4091 .toArray(new SequenceI[seqmaps.size()][]);
4092 final String fileloc = newFileLoc.toString();
4093 final String sviewid = viewerData.getKey();
4094 final AlignFrame alf = af;
4095 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4096 svattrib.getWidth(), svattrib.getHeight());
4099 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4104 JalviewStructureDisplayI sview = null;
4107 sview = new StructureViewer(
4108 alf.alignPanel.getStructureSelectionManager())
4109 .createView(StructureViewer.ViewerType.JMOL,
4110 pdbf, id, sq, alf.alignPanel, svattrib,
4111 fileloc, rect, sviewid);
4112 addNewStructureViewer(sview);
4113 } catch (OutOfMemoryError ex)
4115 new OOMWarning("restoring structure view for PDB id " + id,
4116 (OutOfMemoryError) ex.getCause());
4117 if (sview != null && sview.isVisible())
4119 sview.closeViewer(false);
4120 sview.setVisible(false);
4126 } catch (InvocationTargetException ex)
4128 warn("Unexpected error when opening Jmol view.", ex);
4130 } catch (InterruptedException e)
4132 // e.printStackTrace();
4138 * Generates a name for the entry in the project jar file to hold state
4139 * information for a structure viewer
4144 protected String getViewerJarEntryName(String viewId)
4146 return VIEWER_PREFIX + viewId;
4150 * Returns any open frame that matches given structure viewer data. The match
4151 * is based on the unique viewId, or (for older project versions) the frame's
4157 protected StructureViewerBase findMatchingViewer(
4158 Entry<String, StructureViewerModel> viewerData)
4160 final String sviewid = viewerData.getKey();
4161 final StructureViewerModel svattrib = viewerData.getValue();
4162 StructureViewerBase comp = null;
4163 JInternalFrame[] frames = getAllFrames();
4164 for (JInternalFrame frame : frames)
4166 if (frame instanceof StructureViewerBase)
4169 * Post jalview 2.4 schema includes structure view id
4171 if (sviewid != null && ((StructureViewerBase) frame).getViewId()
4174 comp = (StructureViewerBase) frame;
4175 break; // break added in 2.9
4178 * Otherwise test for matching position and size of viewer frame
4180 else if (frame.getX() == svattrib.getX()
4181 && frame.getY() == svattrib.getY()
4182 && frame.getHeight() == svattrib.getHeight()
4183 && frame.getWidth() == svattrib.getWidth())
4185 comp = (StructureViewerBase) frame;
4186 // no break in faint hope of an exact match on viewId
4194 * Link an AlignmentPanel to an existing structure viewer.
4199 * @param useinViewerSuperpos
4200 * @param usetoColourbyseq
4201 * @param viewerColouring
4203 protected void linkStructureViewer(AlignmentPanel ap,
4204 StructureViewerBase viewer, StructureViewerModel stateData)
4206 // NOTE: if the jalview project is part of a shared session then
4207 // view synchronization should/could be done here.
4209 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4210 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4211 final boolean viewerColouring = stateData.isColourByViewer();
4212 Map<File, StructureData> oldFiles = stateData.getFileData();
4215 * Add mapping for sequences in this view to an already open viewer
4217 final AAStructureBindingModel binding = viewer.getBinding();
4218 for (File id : oldFiles.keySet())
4220 // add this and any other pdb files that should be present in the
4222 StructureData filedat = oldFiles.get(id);
4223 String pdbFile = filedat.getFilePath();
4224 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4225 binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE,
4227 binding.addSequenceForStructFile(pdbFile, seq);
4229 // and add the AlignmentPanel's reference to the view panel
4230 viewer.addAlignmentPanel(ap);
4231 if (useinViewerSuperpos)
4233 viewer.useAlignmentPanelForSuperposition(ap);
4237 viewer.excludeAlignmentPanelForSuperposition(ap);
4239 if (usetoColourbyseq)
4241 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4245 viewer.excludeAlignmentPanelForColourbyseq(ap);
4250 * Get all frames within the Desktop.
4254 protected JInternalFrame[] getAllFrames()
4256 JInternalFrame[] frames = null;
4257 // TODO is this necessary - is it safe - risk of hanging?
4262 frames = Desktop.desktop.getAllFrames();
4263 } catch (ArrayIndexOutOfBoundsException e)
4265 // occasional No such child exceptions are thrown here...
4269 } catch (InterruptedException f)
4273 } while (frames == null);
4278 * Answers true if 'version' is equal to or later than 'supported', where each
4279 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4280 * changes. Development and test values for 'version' are leniently treated
4284 * - minimum version we are comparing against
4286 * - version of data being processsed
4289 public static boolean isVersionStringLaterThan(String supported,
4292 if (supported == null || version == null
4293 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4294 || version.equalsIgnoreCase("Test")
4295 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4297 System.err.println("Assuming project file with "
4298 + (version == null ? "null" : version)
4299 + " is compatible with Jalview version " + supported);
4304 return StringUtils.compareVersions(version, supported, "b") >= 0;
4308 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4310 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4312 if (newStructureViewers != null)
4314 sview.getBinding().setFinishedLoadingFromArchive(false);
4315 newStructureViewers.add(sview);
4319 protected void setLoadingFinishedForNewStructureViewers()
4321 if (newStructureViewers != null)
4323 for (JalviewStructureDisplayI sview : newStructureViewers)
4325 sview.getBinding().setFinishedLoadingFromArchive(true);
4327 newStructureViewers.clear();
4328 newStructureViewers = null;
4332 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4333 List<SequenceI> hiddenSeqs, AlignmentI al,
4334 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4335 String viewId, List<JvAnnotRow> autoAlan)
4337 AlignFrame af = null;
4338 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4339 uniqueSeqSetId, viewId);
4341 af.setFileName(file, FileFormat.Jalview);
4343 for (int i = 0; i < JSEQ.length; i++)
4345 af.viewport.setSequenceColour(
4346 af.viewport.getAlignment().getSequenceAt(i),
4347 new java.awt.Color(JSEQ[i].getColour()));
4352 af.getViewport().setColourByReferenceSeq(true);
4353 af.getViewport().setDisplayReferenceSeq(true);
4356 af.viewport.setGatherViewsHere(view.getGatheredViews());
4358 if (view.getSequenceSetId() != null)
4360 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4362 af.viewport.setSequenceSetId(uniqueSeqSetId);
4365 // propagate shared settings to this new view
4366 af.viewport.setHistoryList(av.getHistoryList());
4367 af.viewport.setRedoList(av.getRedoList());
4371 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4373 // TODO: check if this method can be called repeatedly without
4374 // side-effects if alignpanel already registered.
4375 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4377 // apply Hidden regions to view.
4378 if (hiddenSeqs != null)
4380 for (int s = 0; s < JSEQ.length; s++)
4382 SequenceGroup hidden = new SequenceGroup();
4383 boolean isRepresentative = false;
4384 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4386 isRepresentative = true;
4387 SequenceI sequenceToHide = al
4388 .getSequenceAt(JSEQ[s].getHiddenSequences(r));
4389 hidden.addSequence(sequenceToHide, false);
4390 // remove from hiddenSeqs list so we don't try to hide it twice
4391 hiddenSeqs.remove(sequenceToHide);
4393 if (isRepresentative)
4395 SequenceI representativeSequence = al.getSequenceAt(s);
4396 hidden.addSequence(representativeSequence, false);
4397 af.viewport.hideRepSequences(representativeSequence, hidden);
4401 SequenceI[] hseqs = hiddenSeqs
4402 .toArray(new SequenceI[hiddenSeqs.size()]);
4403 af.viewport.hideSequence(hseqs);
4406 // recover view properties and display parameters
4408 af.viewport.setShowAnnotation(view.getShowAnnotation());
4409 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4410 af.viewport.setThreshold(view.getPidThreshold());
4412 af.viewport.setColourText(view.getShowColourText());
4414 af.viewport.setConservationSelected(view.getConservationSelected());
4415 af.viewport.setIncrement(view.getConsThreshold());
4416 af.viewport.setShowJVSuffix(view.getShowFullId());
4417 af.viewport.setRightAlignIds(view.getRightAlignIds());
4418 af.viewport.setFont(new java.awt.Font(view.getFontName(),
4419 view.getFontStyle(), view.getFontSize()), true);
4420 ViewStyleI vs = af.viewport.getViewStyle();
4421 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4422 af.viewport.setViewStyle(vs);
4423 // TODO: allow custom charWidth/Heights to be restored by updating them
4424 // after setting font - which means set above to false
4425 af.viewport.setRenderGaps(view.getRenderGaps());
4426 af.viewport.setWrapAlignment(view.getWrapAlignment());
4427 af.viewport.setShowAnnotation(view.getShowAnnotation());
4429 af.viewport.setShowBoxes(view.getShowBoxes());
4431 af.viewport.setShowText(view.getShowText());
4433 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4434 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4435 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4436 af.viewport.setShowUnconserved(
4437 view.hasShowUnconserved() ? view.isShowUnconserved() : false);
4438 af.viewport.getRanges().setStartRes(view.getStartRes());
4440 if (view.getViewName() != null)
4442 af.viewport.viewName = view.getViewName();
4443 af.setInitialTabVisible();
4445 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4447 // startSeq set in af.alignPanel.updateLayout below
4448 af.alignPanel.updateLayout();
4449 ColourSchemeI cs = null;
4450 // apply colourschemes
4451 if (view.getBgColour() != null)
4453 if (view.getBgColour().startsWith("ucs"))
4455 cs = getUserColourScheme(jms, view.getBgColour());
4457 else if (view.getBgColour().startsWith("Annotation"))
4459 AnnotationColours viewAnnColour = view.getAnnotationColours();
4460 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4467 cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour());
4471 af.viewport.setGlobalColourScheme(cs);
4472 af.viewport.getResidueShading().setThreshold(view.getPidThreshold(),
4473 view.getIgnoreGapsinConsensus());
4474 af.viewport.getResidueShading()
4475 .setConsensus(af.viewport.getSequenceConsensusHash());
4476 af.viewport.setColourAppliesToAllGroups(false);
4478 if (view.getConservationSelected() && cs != null)
4480 af.viewport.getResidueShading()
4481 .setConservationInc(view.getConsThreshold());
4484 af.changeColour(cs);
4486 af.viewport.setColourAppliesToAllGroups(true);
4488 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4490 if (view.hasCentreColumnLabels())
4492 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4494 if (view.hasIgnoreGapsinConsensus())
4496 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4499 if (view.hasFollowHighlight())
4501 af.viewport.setFollowHighlight(view.getFollowHighlight());
4503 if (view.hasFollowSelection())
4505 af.viewport.followSelection = view.getFollowSelection();
4507 if (view.hasShowConsensusHistogram())
4510 .setShowConsensusHistogram(view.getShowConsensusHistogram());
4514 af.viewport.setShowConsensusHistogram(true);
4516 if (view.hasShowSequenceLogo())
4518 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4522 af.viewport.setShowSequenceLogo(false);
4524 if (view.hasNormaliseSequenceLogo())
4526 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4528 if (view.hasShowDbRefTooltip())
4530 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4532 if (view.hasShowNPfeatureTooltip())
4534 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4536 if (view.hasShowGroupConsensus())
4538 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4542 af.viewport.setShowGroupConsensus(false);
4544 if (view.hasShowGroupConservation())
4546 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4550 af.viewport.setShowGroupConservation(false);
4553 // recover featre settings
4554 if (jms.getFeatureSettings() != null)
4556 FeaturesDisplayed fdi;
4557 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4558 String[] renderOrder = new String[jms.getFeatureSettings()
4559 .getSettingCount()];
4560 Map<String, FeatureColourI> featureColours = new Hashtable<>();
4561 Map<String, Float> featureOrder = new Hashtable<>();
4563 for (int fs = 0; fs < jms.getFeatureSettings()
4564 .getSettingCount(); fs++)
4566 Setting setting = jms.getFeatureSettings().getSetting(fs);
4567 if (setting.hasMincolour())
4569 FeatureColourI gc = setting.hasMin()
4570 ? new FeatureColour(new Color(setting.getMincolour()),
4571 new Color(setting.getColour()), setting.getMin(),
4573 : new FeatureColour(new Color(setting.getMincolour()),
4574 new Color(setting.getColour()), 0, 1);
4575 if (setting.hasThreshold())
4577 gc.setThreshold(setting.getThreshold());
4578 int threshstate = setting.getThreshstate();
4579 // -1 = None, 0 = Below, 1 = Above threshold
4580 if (threshstate == 0)
4582 gc.setBelowThreshold(true);
4584 else if (threshstate == 1)
4586 gc.setAboveThreshold(true);
4589 gc.setAutoScaled(true); // default
4590 if (setting.hasAutoScale())
4592 gc.setAutoScaled(setting.getAutoScale());
4594 if (setting.hasColourByLabel())
4596 gc.setColourByLabel(setting.getColourByLabel());
4598 // and put in the feature colour table.
4599 featureColours.put(setting.getType(), gc);
4603 featureColours.put(setting.getType(),
4604 new FeatureColour(new Color(setting.getColour())));
4606 renderOrder[fs] = setting.getType();
4607 if (setting.hasOrder())
4609 featureOrder.put(setting.getType(), setting.getOrder());
4613 featureOrder.put(setting.getType(), new Float(
4614 fs / jms.getFeatureSettings().getSettingCount()));
4616 if (setting.getDisplay())
4618 fdi.setVisible(setting.getType());
4621 Map<String, Boolean> fgtable = new Hashtable<>();
4622 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4624 Group grp = jms.getFeatureSettings().getGroup(gs);
4625 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4627 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4628 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4629 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4630 FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4631 fgtable, featureColours, 1.0f, featureOrder);
4632 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4633 .transferSettings(frs);
4637 if (view.getHiddenColumnsCount() > 0)
4639 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4641 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(),
4642 view.getHiddenColumns(c).getEnd() // +1
4646 if (view.getCalcIdParam() != null)
4648 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4650 if (calcIdParam != null)
4652 if (recoverCalcIdParam(calcIdParam, af.viewport))
4657 warn("Couldn't recover parameters for "
4658 + calcIdParam.getCalcId());
4663 af.setMenusFromViewport(af.viewport);
4664 af.setTitle(view.getTitle());
4665 // TODO: we don't need to do this if the viewport is aready visible.
4667 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4668 * has a 'cdna/protein complement' view, in which case save it in order to
4669 * populate a SplitFrame once all views have been read in.
4671 String complementaryViewId = view.getComplementId();
4672 if (complementaryViewId == null)
4674 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4676 // recompute any autoannotation
4677 af.alignPanel.updateAnnotation(false, true);
4678 reorderAutoannotation(af, al, autoAlan);
4679 af.alignPanel.alignmentChanged();
4683 splitFrameCandidates.put(view, af);
4689 * Reads saved data to restore Colour by Annotation settings
4691 * @param viewAnnColour
4695 * @param checkGroupAnnColour
4698 private ColourSchemeI constructAnnotationColour(
4699 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4700 JalviewModelSequence jms, boolean checkGroupAnnColour)
4702 boolean propagateAnnColour = false;
4703 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4704 if (checkGroupAnnColour && al.getGroups() != null
4705 && al.getGroups().size() > 0)
4707 // pre 2.8.1 behaviour
4708 // check to see if we should transfer annotation colours
4709 propagateAnnColour = true;
4710 for (SequenceGroup sg : al.getGroups())
4712 if (sg.getColourScheme() instanceof AnnotationColourGradient)
4714 propagateAnnColour = false;
4720 * 2.10.2- : saved annotationId is AlignmentAnnotation.annotationId
4722 String annotationId = viewAnnColour.getAnnotation();
4723 AlignmentAnnotation matchedAnnotation = annotationIds.get(annotationId);
4726 * pre 2.10.2: saved annotationId is AlignmentAnnotation.label
4728 if (matchedAnnotation == null
4729 && annAlignment.getAlignmentAnnotation() != null)
4731 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4734 .equals(annAlignment.getAlignmentAnnotation()[i].label))
4736 matchedAnnotation = annAlignment.getAlignmentAnnotation()[i];
4741 if (matchedAnnotation == null)
4743 System.err.println("Failed to match annotation colour scheme for "
4747 if (matchedAnnotation.getThreshold() == null)
4749 matchedAnnotation.setThreshold(new GraphLine(
4750 viewAnnColour.getThreshold(), "Threshold", Color.black));
4753 AnnotationColourGradient cs = null;
4754 if (viewAnnColour.getColourScheme().equals("None"))
4756 cs = new AnnotationColourGradient(matchedAnnotation,
4757 new Color(viewAnnColour.getMinColour()),
4758 new Color(viewAnnColour.getMaxColour()),
4759 viewAnnColour.getAboveThreshold());
4761 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4763 cs = new AnnotationColourGradient(matchedAnnotation,
4764 getUserColourScheme(jms, viewAnnColour.getColourScheme()),
4765 viewAnnColour.getAboveThreshold());
4769 cs = new AnnotationColourGradient(matchedAnnotation,
4770 ColourSchemeProperty.getColourScheme(al,
4771 viewAnnColour.getColourScheme()),
4772 viewAnnColour.getAboveThreshold());
4775 boolean perSequenceOnly = viewAnnColour.isPerSequence();
4776 boolean useOriginalColours = viewAnnColour.isPredefinedColours();
4777 cs.setSeqAssociated(perSequenceOnly);
4778 cs.setPredefinedColours(useOriginalColours);
4780 if (propagateAnnColour && al.getGroups() != null)
4782 // Also use these settings for all the groups
4783 for (int g = 0; g < al.getGroups().size(); g++)
4785 SequenceGroup sg = al.getGroups().get(g);
4786 if (sg.getGroupColourScheme() == null)
4791 AnnotationColourGradient groupScheme = new AnnotationColourGradient(
4792 matchedAnnotation, sg.getColourScheme(),
4793 viewAnnColour.getAboveThreshold());
4794 sg.setColourScheme(groupScheme);
4795 groupScheme.setSeqAssociated(perSequenceOnly);
4796 groupScheme.setPredefinedColours(useOriginalColours);
4802 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4803 List<JvAnnotRow> autoAlan)
4805 // copy over visualization settings for autocalculated annotation in the
4807 if (al.getAlignmentAnnotation() != null)
4810 * Kludge for magic autoannotation names (see JAL-811)
4812 String[] magicNames = new String[] { "Consensus", "Quality",
4814 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4815 Hashtable<String, JvAnnotRow> visan = new Hashtable<>();
4816 for (String nm : magicNames)
4818 visan.put(nm, nullAnnot);
4820 for (JvAnnotRow auan : autoAlan)
4822 visan.put(auan.template.label
4823 + (auan.template.getCalcId() == null ? ""
4824 : "\t" + auan.template.getCalcId()),
4827 int hSize = al.getAlignmentAnnotation().length;
4828 List<JvAnnotRow> reorder = new ArrayList<>();
4829 // work through any autoCalculated annotation already on the view
4830 // removing it if it should be placed in a different location on the
4831 // annotation panel.
4832 List<String> remains = new ArrayList<>(visan.keySet());
4833 for (int h = 0; h < hSize; h++)
4835 jalview.datamodel.AlignmentAnnotation jalan = al
4836 .getAlignmentAnnotation()[h];
4837 if (jalan.autoCalculated)
4840 JvAnnotRow valan = visan.get(k = jalan.label);
4841 if (jalan.getCalcId() != null)
4843 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4848 // delete the auto calculated row from the alignment
4849 al.deleteAnnotation(jalan, false);
4853 if (valan != nullAnnot)
4855 if (jalan != valan.template)
4857 // newly created autoannotation row instance
4858 // so keep a reference to the visible annotation row
4859 // and copy over all relevant attributes
4860 if (valan.template.graphHeight >= 0)
4863 jalan.graphHeight = valan.template.graphHeight;
4865 jalan.visible = valan.template.visible;
4867 reorder.add(new JvAnnotRow(valan.order, jalan));
4872 // Add any (possibly stale) autocalculated rows that were not appended to
4873 // the view during construction
4874 for (String other : remains)
4876 JvAnnotRow othera = visan.get(other);
4877 if (othera != nullAnnot && othera.template.getCalcId() != null
4878 && othera.template.getCalcId().length() > 0)
4880 reorder.add(othera);
4883 // now put the automatic annotation in its correct place
4884 int s = 0, srt[] = new int[reorder.size()];
4885 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4886 for (JvAnnotRow jvar : reorder)
4889 srt[s++] = jvar.order;
4892 jalview.util.QuickSort.sort(srt, rws);
4893 // and re-insert the annotation at its correct position
4894 for (JvAnnotRow jvar : rws)
4896 al.addAnnotation(jvar.template, jvar.order);
4898 af.alignPanel.adjustAnnotationHeight();
4902 Hashtable skipList = null;
4905 * TODO remove this method
4908 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4909 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4910 * throw new Error("Implementation Error. No skipList defined for this
4911 * Jalview2XML instance."); } return (AlignFrame)
4912 * skipList.get(view.getSequenceSetId()); }
4916 * Check if the Jalview view contained in object should be skipped or not.
4919 * @return true if view's sequenceSetId is a key in skipList
4921 private boolean skipViewport(JalviewModel object)
4923 if (skipList == null)
4928 if (skipList.containsKey(
4929 id = object.getJalviewModelSequence().getViewport()[0]
4930 .getSequenceSetId()))
4932 if (Cache.log != null && Cache.log.isDebugEnabled())
4934 Cache.log.debug("Skipping seuqence set id " + id);
4941 public void addToSkipList(AlignFrame af)
4943 if (skipList == null)
4945 skipList = new Hashtable();
4947 skipList.put(af.getViewport().getSequenceSetId(), af);
4950 public void clearSkipList()
4952 if (skipList != null)
4959 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4960 boolean ignoreUnrefed)
4962 jalview.datamodel.AlignmentI ds = getDatasetFor(
4963 vamsasSet.getDatasetId());
4964 Vector dseqs = null;
4967 // create a list of new dataset sequences
4968 dseqs = new Vector();
4970 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4972 Sequence vamsasSeq = vamsasSet.getSequence(i);
4973 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4975 // create a new dataset
4978 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4979 dseqs.copyInto(dsseqs);
4980 ds = new jalview.datamodel.Alignment(dsseqs);
4981 debug("Created new dataset " + vamsasSet.getDatasetId()
4982 + " for alignment " + System.identityHashCode(al));
4983 addDatasetRef(vamsasSet.getDatasetId(), ds);
4985 // set the dataset for the newly imported alignment.
4986 if (al.getDataset() == null && !ignoreUnrefed)
4995 * sequence definition to create/merge dataset sequence for
4999 * vector to add new dataset sequence to
5000 * @param ignoreUnrefed
5001 * - when true, don't create new sequences from vamsasSeq if it's id
5002 * doesn't already have an asssociated Jalview sequence.
5004 * - used to reorder the sequence in the alignment according to the
5005 * vamsasSeq array ordering, to preserve ordering of dataset
5007 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5008 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5010 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5012 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5013 boolean reorder = false;
5014 SequenceI dsq = null;
5015 if (sq != null && sq.getDatasetSequence() != null)
5017 dsq = sq.getDatasetSequence();
5023 if (sq == null && ignoreUnrefed)
5027 String sqid = vamsasSeq.getDsseqid();
5030 // need to create or add a new dataset sequence reference to this sequence
5033 dsq = seqRefIds.get(sqid);
5038 // make a new dataset sequence
5039 dsq = sq.createDatasetSequence();
5042 // make up a new dataset reference for this sequence
5043 sqid = seqHash(dsq);
5045 dsq.setVamsasId(uniqueSetSuffix + sqid);
5046 seqRefIds.put(sqid, dsq);
5051 dseqs.addElement(dsq);
5056 ds.addSequence(dsq);
5062 { // make this dataset sequence sq's dataset sequence
5063 sq.setDatasetSequence(dsq);
5064 // and update the current dataset alignment
5069 if (!dseqs.contains(dsq))
5076 if (ds.findIndex(dsq) < 0)
5078 ds.addSequence(dsq);
5085 // TODO: refactor this as a merge dataset sequence function
5086 // now check that sq (the dataset sequence) sequence really is the union of
5087 // all references to it
5088 // boolean pre = sq.getStart() < dsq.getStart();
5089 // boolean post = sq.getEnd() > dsq.getEnd();
5093 // StringBuffer sb = new StringBuffer();
5094 String newres = jalview.analysis.AlignSeq.extractGaps(
5095 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5096 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5097 && newres.length() > dsq.getLength())
5099 // Update with the longer sequence.
5103 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5104 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5105 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5106 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5108 dsq.setSequence(newres);
5110 // TODO: merges will never happen if we 'know' we have the real dataset
5111 // sequence - this should be detected when id==dssid
5113 "DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5114 // + (pre ? "prepended" : "") + " "
5115 // + (post ? "appended" : ""));
5120 // sequence refs are identical. We may need to update the existing dataset
5121 // alignment with this one, though.
5122 if (ds != null && dseqs == null)
5124 int opos = ds.findIndex(dsq);
5125 SequenceI tseq = null;
5126 if (opos != -1 && vseqpos != opos)
5128 // remove from old position
5129 ds.deleteSequence(dsq);
5131 if (vseqpos < ds.getHeight())
5133 if (vseqpos != opos)
5135 // save sequence at destination position
5136 tseq = ds.getSequenceAt(vseqpos);
5137 ds.replaceSequenceAt(vseqpos, dsq);
5138 ds.addSequence(tseq);
5143 ds.addSequence(dsq);
5150 * TODO use AlignmentI here and in related methods - needs
5151 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5153 Hashtable<String, AlignmentI> datasetIds = null;
5155 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5157 private AlignmentI getDatasetFor(String datasetId)
5159 if (datasetIds == null)
5161 datasetIds = new Hashtable<>();
5164 if (datasetIds.containsKey(datasetId))
5166 return datasetIds.get(datasetId);
5171 private void addDatasetRef(String datasetId, AlignmentI dataset)
5173 if (datasetIds == null)
5175 datasetIds = new Hashtable<>();
5177 datasetIds.put(datasetId, dataset);
5181 * make a new dataset ID for this jalview dataset alignment
5186 private String getDatasetIdRef(AlignmentI dataset)
5188 if (dataset.getDataset() != null)
5190 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5192 String datasetId = makeHashCode(dataset, null);
5193 if (datasetId == null)
5195 // make a new datasetId and record it
5196 if (dataset2Ids == null)
5198 dataset2Ids = new IdentityHashMap<>();
5202 datasetId = dataset2Ids.get(dataset);
5204 if (datasetId == null)
5206 datasetId = "ds" + dataset2Ids.size() + 1;
5207 dataset2Ids.put(dataset, datasetId);
5213 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5215 for (int d = 0; d < sequence.getDBRefCount(); d++)
5217 DBRef dr = sequence.getDBRef(d);
5218 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5219 sequence.getDBRef(d).getSource(),
5220 sequence.getDBRef(d).getVersion(),
5221 sequence.getDBRef(d).getAccessionId());
5222 if (dr.getMapping() != null)
5224 entry.setMap(addMapping(dr.getMapping()));
5226 datasetSequence.addDBRef(entry);
5230 private jalview.datamodel.Mapping addMapping(Mapping m)
5232 SequenceI dsto = null;
5233 // Mapping m = dr.getMapping();
5234 int fr[] = new int[m.getMapListFromCount() * 2];
5235 Enumeration f = m.enumerateMapListFrom();
5236 for (int _i = 0; f.hasMoreElements(); _i += 2)
5238 MapListFrom mf = (MapListFrom) f.nextElement();
5239 fr[_i] = mf.getStart();
5240 fr[_i + 1] = mf.getEnd();
5242 int fto[] = new int[m.getMapListToCount() * 2];
5243 f = m.enumerateMapListTo();
5244 for (int _i = 0; f.hasMoreElements(); _i += 2)
5246 MapListTo mf = (MapListTo) f.nextElement();
5247 fto[_i] = mf.getStart();
5248 fto[_i + 1] = mf.getEnd();
5250 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto, fr,
5251 fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5252 if (m.getMappingChoice() != null)
5254 MappingChoice mc = m.getMappingChoice();
5255 if (mc.getDseqFor() != null)
5257 String dsfor = "" + mc.getDseqFor();
5258 if (seqRefIds.containsKey(dsfor))
5263 jmap.setTo(seqRefIds.get(dsfor));
5267 frefedSequence.add(newMappingRef(dsfor, jmap));
5273 * local sequence definition
5275 Sequence ms = mc.getSequence();
5276 SequenceI djs = null;
5277 String sqid = ms.getDsseqid();
5278 if (sqid != null && sqid.length() > 0)
5281 * recover dataset sequence
5283 djs = seqRefIds.get(sqid);
5288 "Warning - making up dataset sequence id for DbRef sequence map reference");
5289 sqid = ((Object) ms).toString(); // make up a new hascode for
5290 // undefined dataset sequence hash
5291 // (unlikely to happen)
5297 * make a new dataset sequence and add it to refIds hash
5299 djs = new jalview.datamodel.Sequence(ms.getName(),
5301 djs.setStart(jmap.getMap().getToLowest());
5302 djs.setEnd(jmap.getMap().getToHighest());
5303 djs.setVamsasId(uniqueSetSuffix + sqid);
5305 incompleteSeqs.put(sqid, djs);
5306 seqRefIds.put(sqid, djs);
5309 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5319 * Provides a 'copy' of an alignment view (on action New View) by 'saving' the
5320 * view as XML (but not to file), and then reloading it
5325 public AlignmentPanel copyAlignPanel(AlignmentPanel ap)
5328 JalviewModel jm = saveState(ap, null, null, null);
5330 uniqueSetSuffix = "";
5331 jm.getJalviewModelSequence().getViewport(0).setId(null);
5332 // we don't overwrite the view we just copied
5334 if (this.frefedSequence == null)
5336 frefedSequence = new Vector<SeqFref>();
5339 viewportsAdded.clear();
5341 AlignFrame af = loadFromObject(jm, null, false, null);
5342 af.alignPanels.clear();
5343 af.closeMenuItem_actionPerformed(true);
5346 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5347 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5348 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5349 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5350 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5353 return af.alignPanel;
5356 private Hashtable jvids2vobj;
5358 private void warn(String msg)
5363 private void warn(String msg, Exception e)
5365 if (Cache.log != null)
5369 Cache.log.warn(msg, e);
5373 Cache.log.warn(msg);
5378 System.err.println("Warning: " + msg);
5381 e.printStackTrace();
5386 private void debug(String string)
5388 debug(string, null);
5391 private void debug(String msg, Exception e)
5393 if (Cache.log != null)
5397 Cache.log.debug(msg, e);
5401 Cache.log.debug(msg);
5406 System.err.println("Warning: " + msg);
5409 e.printStackTrace();
5415 * set the object to ID mapping tables used to write/recover objects and XML
5416 * ID strings for the jalview project. If external tables are provided then
5417 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5418 * object goes out of scope. - also populates the datasetIds hashtable with
5419 * alignment objects containing dataset sequences
5422 * Map from ID strings to jalview datamodel
5424 * Map from jalview datamodel to ID strings
5428 public void setObjectMappingTables(Hashtable vobj2jv,
5429 IdentityHashMap jv2vobj)
5431 this.jv2vobj = jv2vobj;
5432 this.vobj2jv = vobj2jv;
5433 Iterator ds = jv2vobj.keySet().iterator();
5435 while (ds.hasNext())
5437 Object jvobj = ds.next();
5438 id = jv2vobj.get(jvobj).toString();
5439 if (jvobj instanceof jalview.datamodel.Alignment)
5441 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5443 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5446 else if (jvobj instanceof jalview.datamodel.Sequence)
5448 // register sequence object so the XML parser can recover it.
5449 if (seqRefIds == null)
5451 seqRefIds = new HashMap<>();
5453 if (seqsToIds == null)
5455 seqsToIds = new IdentityHashMap<>();
5457 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5458 seqsToIds.put((SequenceI) jvobj, id);
5460 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5463 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5464 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5465 if (jvann.annotationId == null)
5467 jvann.annotationId = anid;
5469 if (!jvann.annotationId.equals(anid))
5471 // TODO verify that this is the correct behaviour
5472 this.warn("Overriding Annotation ID for " + anid
5473 + " from different id : " + jvann.annotationId);
5474 jvann.annotationId = anid;
5477 else if (jvobj instanceof String)
5479 if (jvids2vobj == null)
5481 jvids2vobj = new Hashtable();
5482 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5487 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5493 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5494 * objects created from the project archive. If string is null (default for
5495 * construction) then suffix will be set automatically.
5499 public void setUniqueSetSuffix(String string)
5501 uniqueSetSuffix = string;
5506 * uses skipList2 as the skipList for skipping views on sequence sets
5507 * associated with keys in the skipList
5511 public void setSkipList(Hashtable skipList2)
5513 skipList = skipList2;
5517 * Reads the jar entry of given name and returns its contents, or null if the
5518 * entry is not found.
5521 * @param jarEntryName
5524 protected String readJarEntry(jarInputStreamProvider jprovider,
5525 String jarEntryName)
5527 String result = null;
5528 BufferedReader in = null;
5533 * Reopen the jar input stream and traverse its entries to find a matching
5536 JarInputStream jin = jprovider.getJarInputStream();
5537 JarEntry entry = null;
5540 entry = jin.getNextJarEntry();
5541 } while (entry != null && !entry.getName().equals(jarEntryName));
5545 StringBuilder out = new StringBuilder(256);
5546 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5549 while ((data = in.readLine()) != null)
5553 result = out.toString();
5557 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5559 } catch (Exception ex)
5561 ex.printStackTrace();
5569 } catch (IOException e)
5580 * Returns an incrementing counter (0, 1, 2...)
5584 private synchronized int nextCounter()