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 Iterator<int[]> hiddenRegions = hidden.iterator();
1393 while (hiddenRegions.hasNext())
1395 int[] region = hiddenRegions.next();
1396 HiddenColumns hc = new HiddenColumns();
1397 hc.setStart(region[0]);
1398 hc.setEnd(region[1]);
1399 view.addHiddenColumns(hc);
1403 if (calcIdSet.size() > 0)
1405 for (String calcId : calcIdSet)
1407 if (calcId.trim().length() > 0)
1409 CalcIdParam cidp = createCalcIdParam(calcId, av);
1410 // Some calcIds have no parameters.
1413 view.addCalcIdParam(cidp);
1419 jms.addViewport(view);
1421 object.setJalviewModelSequence(jms);
1422 object.getVamsasModel().addSequenceSet(vamsasSet);
1424 if (jout != null && fileName != null)
1426 // We may not want to write the object to disk,
1427 // eg we can copy the alignViewport to a new view object
1428 // using save and then load
1431 System.out.println("Writing jar entry " + fileName);
1432 JarEntry entry = new JarEntry(fileName);
1433 jout.putNextEntry(entry);
1434 PrintWriter pout = new PrintWriter(
1435 new OutputStreamWriter(jout, UTF_8));
1436 Marshaller marshaller = new Marshaller(pout);
1437 marshaller.marshal(object);
1440 } catch (Exception ex)
1442 // TODO: raise error in GUI if marshalling failed.
1443 ex.printStackTrace();
1450 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1451 * for each viewer, with
1453 * <li>viewer geometry (position, size, split pane divider location)</li>
1454 * <li>index of the selected structure in the viewer (currently shows gapped
1456 * <li>the id of the annotation holding RNA secondary structure</li>
1457 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1459 * Varna viewer state is also written out (in native Varna XML) to separate
1460 * project jar entries. A separate entry is written for each RNA structure
1461 * displayed, with the naming convention
1463 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1471 * @param storeDataset
1473 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1474 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1475 boolean storeDataset)
1477 if (Desktop.desktop == null)
1481 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1482 for (int f = frames.length - 1; f > -1; f--)
1484 if (frames[f] instanceof AppVarna)
1486 AppVarna varna = (AppVarna) frames[f];
1488 * link the sequence to every viewer that is showing it and is linked to
1489 * its alignment panel
1491 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1493 String viewId = varna.getViewId();
1494 RnaViewer rna = new RnaViewer();
1495 rna.setViewId(viewId);
1496 rna.setTitle(varna.getTitle());
1497 rna.setXpos(varna.getX());
1498 rna.setYpos(varna.getY());
1499 rna.setWidth(varna.getWidth());
1500 rna.setHeight(varna.getHeight());
1501 rna.setDividerLocation(varna.getDividerLocation());
1502 rna.setSelectedRna(varna.getSelectedIndex());
1503 jseq.addRnaViewer(rna);
1506 * Store each Varna panel's state once in the project per sequence.
1507 * First time through only (storeDataset==false)
1509 // boolean storeSessions = false;
1510 // String sequenceViewId = viewId + seqsToIds.get(jds);
1511 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1513 // viewIds.add(sequenceViewId);
1514 // storeSessions = true;
1516 for (RnaModel model : varna.getModels())
1518 if (model.seq == jds)
1521 * VARNA saves each view (sequence or alignment secondary
1522 * structure, gapped or trimmed) as a separate XML file
1524 String jarEntryName = rnaSessions.get(model);
1525 if (jarEntryName == null)
1528 String varnaStateFile = varna.getStateInfo(model.rna);
1529 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1530 copyFileToJar(jout, varnaStateFile, jarEntryName);
1531 rnaSessions.put(model, jarEntryName);
1533 SecondaryStructure ss = new SecondaryStructure();
1534 String annotationId = varna.getAnnotation(jds).annotationId;
1535 ss.setAnnotationId(annotationId);
1536 ss.setViewerState(jarEntryName);
1537 ss.setGapped(model.gapped);
1538 ss.setTitle(model.title);
1539 rna.addSecondaryStructure(ss);
1548 * Copy the contents of a file to a new entry added to the output jar
1552 * @param jarEntryName
1554 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1555 String jarEntryName)
1557 DataInputStream dis = null;
1560 File file = new File(infilePath);
1561 if (file.exists() && jout != null)
1563 dis = new DataInputStream(new FileInputStream(file));
1564 byte[] data = new byte[(int) file.length()];
1565 dis.readFully(data);
1566 writeJarEntry(jout, jarEntryName, data);
1568 } catch (Exception ex)
1570 ex.printStackTrace();
1578 } catch (IOException e)
1587 * Write the data to a new entry of given name in the output jar file
1590 * @param jarEntryName
1592 * @throws IOException
1594 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1595 byte[] data) throws IOException
1599 System.out.println("Writing jar entry " + jarEntryName);
1600 jout.putNextEntry(new JarEntry(jarEntryName));
1601 DataOutputStream dout = new DataOutputStream(jout);
1602 dout.write(data, 0, data.length);
1609 * Save the state of a structure viewer
1614 * the archive XML element under which to save the state
1617 * @param matchedFile
1621 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1622 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1623 String matchedFile, StructureViewerBase viewFrame)
1625 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1628 * Look for any bindings for this viewer to the PDB file of interest
1629 * (including part matches excluding chain id)
1631 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1633 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1634 final String pdbId = pdbentry.getId();
1635 if (!pdbId.equals(entry.getId())
1636 && !(entry.getId().length() > 4 && entry.getId().toLowerCase()
1637 .startsWith(pdbId.toLowerCase())))
1640 * not interested in a binding to a different PDB entry here
1644 if (matchedFile == null)
1646 matchedFile = pdbentry.getFile();
1648 else if (!matchedFile.equals(pdbentry.getFile()))
1651 "Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1652 + pdbentry.getFile());
1656 // can get at it if the ID
1657 // match is ambiguous (e.g.
1660 for (int smap = 0; smap < viewFrame.getBinding()
1661 .getSequence()[peid].length; smap++)
1663 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1664 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1666 StructureState state = new StructureState();
1667 state.setVisible(true);
1668 state.setXpos(viewFrame.getX());
1669 state.setYpos(viewFrame.getY());
1670 state.setWidth(viewFrame.getWidth());
1671 state.setHeight(viewFrame.getHeight());
1672 final String viewId = viewFrame.getViewId();
1673 state.setViewId(viewId);
1674 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1675 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1676 state.setColourByJmol(viewFrame.isColouredByViewer());
1677 state.setType(viewFrame.getViewerType().toString());
1678 pdb.addStructureState(state);
1686 * Populates the AnnotationColours xml for save. This captures the settings of
1687 * the options in the 'Colour by Annotation' dialog.
1690 * @param userColours
1694 private AnnotationColours constructAnnotationColours(
1695 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1696 JalviewModelSequence jms)
1698 AnnotationColours ac = new AnnotationColours();
1699 ac.setAboveThreshold(acg.getAboveThreshold());
1700 ac.setThreshold(acg.getAnnotationThreshold());
1701 // 2.10.2 save annotationId (unique) not annotation label
1702 ac.setAnnotation(acg.getAnnotation().annotationId);
1703 if (acg.getBaseColour() instanceof UserColourScheme)
1706 setUserColourScheme(acg.getBaseColour(), userColours, jms));
1711 ColourSchemeProperty.getColourName(acg.getBaseColour()));
1714 ac.setMaxColour(acg.getMaxColour().getRGB());
1715 ac.setMinColour(acg.getMinColour().getRGB());
1716 ac.setPerSequence(acg.isSeqAssociated());
1717 ac.setPredefinedColours(acg.isPredefinedColours());
1721 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1722 IdentityHashMap<SequenceGroup, String> groupRefs,
1723 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1724 SequenceSet vamsasSet)
1727 for (int i = 0; i < aa.length; i++)
1729 Annotation an = new Annotation();
1731 AlignmentAnnotation annotation = aa[i];
1732 if (annotation.annotationId != null)
1734 annotationIds.put(annotation.annotationId, annotation);
1737 an.setId(annotation.annotationId);
1739 an.setVisible(annotation.visible);
1741 an.setDescription(annotation.description);
1743 if (annotation.sequenceRef != null)
1745 // 2.9 JAL-1781 xref on sequence id rather than name
1746 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1748 if (annotation.groupRef != null)
1750 String groupIdr = groupRefs.get(annotation.groupRef);
1751 if (groupIdr == null)
1753 // make a locally unique String
1754 groupRefs.put(annotation.groupRef,
1755 groupIdr = ("" + System.currentTimeMillis()
1756 + annotation.groupRef.getName()
1757 + groupRefs.size()));
1759 an.setGroupRef(groupIdr.toString());
1762 // store all visualization attributes for annotation
1763 an.setGraphHeight(annotation.graphHeight);
1764 an.setCentreColLabels(annotation.centreColLabels);
1765 an.setScaleColLabels(annotation.scaleColLabel);
1766 an.setShowAllColLabels(annotation.showAllColLabels);
1767 an.setBelowAlignment(annotation.belowAlignment);
1769 if (annotation.graph > 0)
1772 an.setGraphType(annotation.graph);
1773 an.setGraphGroup(annotation.graphGroup);
1774 if (annotation.getThreshold() != null)
1776 ThresholdLine line = new ThresholdLine();
1777 line.setLabel(annotation.getThreshold().label);
1778 line.setValue(annotation.getThreshold().value);
1779 line.setColour(annotation.getThreshold().colour.getRGB());
1780 an.setThresholdLine(line);
1788 an.setLabel(annotation.label);
1790 if (annotation == av.getAlignmentQualityAnnot()
1791 || annotation == av.getAlignmentConservationAnnotation()
1792 || annotation == av.getAlignmentConsensusAnnotation()
1793 || annotation.autoCalculated)
1795 // new way of indicating autocalculated annotation -
1796 an.setAutoCalculated(annotation.autoCalculated);
1798 if (annotation.hasScore())
1800 an.setScore(annotation.getScore());
1803 if (annotation.getCalcId() != null)
1805 calcIdSet.add(annotation.getCalcId());
1806 an.setCalcId(annotation.getCalcId());
1808 if (annotation.hasProperties())
1810 for (String pr : annotation.getProperties())
1812 Property prop = new Property();
1814 prop.setValue(annotation.getProperty(pr));
1815 an.addProperty(prop);
1819 AnnotationElement ae;
1820 if (annotation.annotations != null)
1822 an.setScoreOnly(false);
1823 for (int a = 0; a < annotation.annotations.length; a++)
1825 if ((annotation == null) || (annotation.annotations[a] == null))
1830 ae = new AnnotationElement();
1831 if (annotation.annotations[a].description != null)
1833 ae.setDescription(annotation.annotations[a].description);
1835 if (annotation.annotations[a].displayCharacter != null)
1837 ae.setDisplayCharacter(
1838 annotation.annotations[a].displayCharacter);
1841 if (!Float.isNaN(annotation.annotations[a].value))
1843 ae.setValue(annotation.annotations[a].value);
1847 if (annotation.annotations[a].secondaryStructure > ' ')
1849 ae.setSecondaryStructure(
1850 annotation.annotations[a].secondaryStructure + "");
1853 if (annotation.annotations[a].colour != null
1854 && annotation.annotations[a].colour != java.awt.Color.black)
1856 ae.setColour(annotation.annotations[a].colour.getRGB());
1859 an.addAnnotationElement(ae);
1860 if (annotation.autoCalculated)
1862 // only write one non-null entry into the annotation row -
1863 // sufficient to get the visualization attributes necessary to
1871 an.setScoreOnly(true);
1873 if (!storeDS || (storeDS && !annotation.autoCalculated))
1875 // skip autocalculated annotation - these are only provided for
1877 vamsasSet.addAnnotation(an);
1883 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1885 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1886 if (settings != null)
1888 CalcIdParam vCalcIdParam = new CalcIdParam();
1889 vCalcIdParam.setCalcId(calcId);
1890 vCalcIdParam.addServiceURL(settings.getServiceURI());
1891 // generic URI allowing a third party to resolve another instance of the
1892 // service used for this calculation
1893 for (String urls : settings.getServiceURLs())
1895 vCalcIdParam.addServiceURL(urls);
1897 vCalcIdParam.setVersion("1.0");
1898 if (settings.getPreset() != null)
1900 WsParamSetI setting = settings.getPreset();
1901 vCalcIdParam.setName(setting.getName());
1902 vCalcIdParam.setDescription(setting.getDescription());
1906 vCalcIdParam.setName("");
1907 vCalcIdParam.setDescription("Last used parameters");
1909 // need to be able to recover 1) settings 2) user-defined presets or
1910 // recreate settings from preset 3) predefined settings provided by
1911 // service - or settings that can be transferred (or discarded)
1912 vCalcIdParam.setParameters(
1913 settings.getWsParamFile().replace("\n", "|\\n|"));
1914 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1915 // todo - decide if updateImmediately is needed for any projects.
1917 return vCalcIdParam;
1922 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1925 if (calcIdParam.getVersion().equals("1.0"))
1927 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1928 .getPreferredServiceFor(calcIdParam.getServiceURL());
1929 if (service != null)
1931 WsParamSetI parmSet = null;
1934 parmSet = service.getParamStore().parseServiceParameterFile(
1935 calcIdParam.getName(), calcIdParam.getDescription(),
1936 calcIdParam.getServiceURL(),
1937 calcIdParam.getParameters().replace("|\\n|", "\n"));
1938 } catch (IOException x)
1940 warn("Couldn't parse parameter data for "
1941 + calcIdParam.getCalcId(), x);
1944 List<ArgumentI> argList = null;
1945 if (calcIdParam.getName().length() > 0)
1947 parmSet = service.getParamStore()
1948 .getPreset(calcIdParam.getName());
1949 if (parmSet != null)
1951 // TODO : check we have a good match with settings in AACon -
1952 // otherwise we'll need to create a new preset
1957 argList = parmSet.getArguments();
1960 AAConSettings settings = new AAConSettings(
1961 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1962 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1963 calcIdParam.isNeedsUpdate());
1968 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1972 throw new Error(MessageManager.formatMessage(
1973 "error.unsupported_version_calcIdparam", new Object[]
1974 { calcIdParam.toString() }));
1978 * External mapping between jalview objects and objects yielding a valid and
1979 * unique object ID string. This is null for normal Jalview project IO, but
1980 * non-null when a jalview project is being read or written as part of a
1983 IdentityHashMap jv2vobj = null;
1986 * Construct a unique ID for jvobj using either existing bindings or if none
1987 * exist, the result of the hashcode call for the object.
1990 * jalview data object
1991 * @return unique ID for referring to jvobj
1993 private String makeHashCode(Object jvobj, String altCode)
1995 if (jv2vobj != null)
1997 Object id = jv2vobj.get(jvobj);
2000 return id.toString();
2002 // check string ID mappings
2003 if (jvids2vobj != null && jvobj instanceof String)
2005 id = jvids2vobj.get(jvobj);
2009 return id.toString();
2011 // give up and warn that something has gone wrong
2012 warn("Cannot find ID for object in external mapping : " + jvobj);
2018 * return local jalview object mapped to ID, if it exists
2022 * @return null or object bound to idcode
2024 private Object retrieveExistingObj(String idcode)
2026 if (idcode != null && vobj2jv != null)
2028 return vobj2jv.get(idcode);
2034 * binding from ID strings from external mapping table to jalview data model
2037 private Hashtable vobj2jv;
2039 private Sequence createVamsasSequence(String id, SequenceI jds)
2041 return createVamsasSequence(true, id, jds, null);
2044 private Sequence createVamsasSequence(boolean recurse, String id,
2045 SequenceI jds, SequenceI parentseq)
2047 Sequence vamsasSeq = new Sequence();
2048 vamsasSeq.setId(id);
2049 vamsasSeq.setName(jds.getName());
2050 vamsasSeq.setSequence(jds.getSequenceAsString());
2051 vamsasSeq.setDescription(jds.getDescription());
2052 jalview.datamodel.DBRefEntry[] dbrefs = null;
2053 if (jds.getDatasetSequence() != null)
2055 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2059 // seqId==dsseqid so we can tell which sequences really are
2060 // dataset sequences only
2061 vamsasSeq.setDsseqid(id);
2062 dbrefs = jds.getDBRefs();
2063 if (parentseq == null)
2070 for (int d = 0; d < dbrefs.length; d++)
2072 DBRef dbref = new DBRef();
2073 dbref.setSource(dbrefs[d].getSource());
2074 dbref.setVersion(dbrefs[d].getVersion());
2075 dbref.setAccessionId(dbrefs[d].getAccessionId());
2076 if (dbrefs[d].hasMap())
2078 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2080 dbref.setMapping(mp);
2082 vamsasSeq.addDBRef(dbref);
2088 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2089 SequenceI parentseq, SequenceI jds, boolean recurse)
2092 if (jmp.getMap() != null)
2096 jalview.util.MapList mlst = jmp.getMap();
2097 List<int[]> r = mlst.getFromRanges();
2098 for (int[] range : r)
2100 MapListFrom mfrom = new MapListFrom();
2101 mfrom.setStart(range[0]);
2102 mfrom.setEnd(range[1]);
2103 mp.addMapListFrom(mfrom);
2105 r = mlst.getToRanges();
2106 for (int[] range : r)
2108 MapListTo mto = new MapListTo();
2109 mto.setStart(range[0]);
2110 mto.setEnd(range[1]);
2111 mp.addMapListTo(mto);
2113 mp.setMapFromUnit(mlst.getFromRatio());
2114 mp.setMapToUnit(mlst.getToRatio());
2115 if (jmp.getTo() != null)
2117 MappingChoice mpc = new MappingChoice();
2119 // check/create ID for the sequence referenced by getTo()
2122 SequenceI ps = null;
2123 if (parentseq != jmp.getTo()
2124 && parentseq.getDatasetSequence() != jmp.getTo())
2126 // chaining dbref rather than a handshaking one
2127 jmpid = seqHash(ps = jmp.getTo());
2131 jmpid = seqHash(ps = parentseq);
2133 mpc.setDseqFor(jmpid);
2134 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2136 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2137 seqRefIds.put(mpc.getDseqFor(), ps);
2141 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2144 mp.setMappingChoice(mpc);
2150 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2151 List<UserColourScheme> userColours, JalviewModelSequence jms)
2154 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2155 boolean newucs = false;
2156 if (!userColours.contains(ucs))
2158 userColours.add(ucs);
2161 id = "ucs" + userColours.indexOf(ucs);
2164 // actually create the scheme's entry in the XML model
2165 java.awt.Color[] colours = ucs.getColours();
2166 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2167 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2169 for (int i = 0; i < colours.length; i++)
2171 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2172 col.setName(ResidueProperties.aa[i]);
2173 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2174 jbucs.addColour(col);
2176 if (ucs.getLowerCaseColours() != null)
2178 colours = ucs.getLowerCaseColours();
2179 for (int i = 0; i < colours.length; i++)
2181 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2182 col.setName(ResidueProperties.aa[i].toLowerCase());
2183 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2184 jbucs.addColour(col);
2189 uc.setUserColourScheme(jbucs);
2190 jms.addUserColours(uc);
2196 jalview.schemes.UserColourScheme getUserColourScheme(
2197 JalviewModelSequence jms, String id)
2199 UserColours[] uc = jms.getUserColours();
2200 UserColours colours = null;
2202 for (int i = 0; i < uc.length; i++)
2204 if (uc[i].getId().equals(id))
2212 java.awt.Color[] newColours = new java.awt.Color[24];
2214 for (int i = 0; i < 24; i++)
2216 newColours[i] = new java.awt.Color(Integer.parseInt(
2217 colours.getUserColourScheme().getColour(i).getRGB(), 16));
2220 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2223 if (colours.getUserColourScheme().getColourCount() > 24)
2225 newColours = new java.awt.Color[23];
2226 for (int i = 0; i < 23; i++)
2228 newColours[i] = new java.awt.Color(Integer.parseInt(
2229 colours.getUserColourScheme().getColour(i + 24).getRGB(),
2232 ucs.setLowerCaseColours(newColours);
2239 * contains last error message (if any) encountered by XML loader.
2241 String errorMessage = null;
2244 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2245 * exceptions are raised during project XML parsing
2247 public boolean attemptversion1parse = true;
2250 * Load a jalview project archive from a jar file
2253 * - HTTP URL or filename
2255 public AlignFrame loadJalviewAlign(final String file)
2258 jalview.gui.AlignFrame af = null;
2262 // create list to store references for any new Jmol viewers created
2263 newStructureViewers = new Vector<>();
2264 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2265 // Workaround is to make sure caller implements the JarInputStreamProvider
2267 // so we can re-open the jar input stream for each entry.
2269 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2270 af = loadJalviewAlign(jprovider);
2271 af.setMenusForViewport();
2273 } catch (MalformedURLException e)
2275 errorMessage = "Invalid URL format for '" + file + "'";
2281 SwingUtilities.invokeAndWait(new Runnable()
2286 setLoadingFinishedForNewStructureViewers();
2289 } catch (Exception x)
2291 System.err.println("Error loading alignment: " + x.getMessage());
2297 private jarInputStreamProvider createjarInputStreamProvider(
2298 final String file) throws MalformedURLException
2301 errorMessage = null;
2302 uniqueSetSuffix = null;
2304 viewportsAdded.clear();
2305 frefedSequence = null;
2307 if (file.startsWith("http://"))
2309 url = new URL(file);
2311 final URL _url = url;
2312 return new jarInputStreamProvider()
2316 public JarInputStream getJarInputStream() throws IOException
2320 return new JarInputStream(_url.openStream());
2324 return new JarInputStream(new FileInputStream(file));
2329 public String getFilename()
2337 * Recover jalview session from a jalview project archive. Caller may
2338 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2339 * themselves. Any null fields will be initialised with default values,
2340 * non-null fields are left alone.
2345 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2347 errorMessage = null;
2348 if (uniqueSetSuffix == null)
2350 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2352 if (seqRefIds == null)
2356 AlignFrame af = null, _af = null;
2357 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<>();
2358 Map<String, AlignFrame> gatherToThisFrame = new HashMap<>();
2359 final String file = jprovider.getFilename();
2362 JarInputStream jin = null;
2363 JarEntry jarentry = null;
2368 jin = jprovider.getJarInputStream();
2369 for (int i = 0; i < entryCount; i++)
2371 jarentry = jin.getNextJarEntry();
2374 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2376 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2377 JalviewModel object = new JalviewModel();
2379 Unmarshaller unmar = new Unmarshaller(object);
2380 unmar.setValidation(false);
2381 object = (JalviewModel) unmar.unmarshal(in);
2382 if (true) // !skipViewport(object))
2384 _af = loadFromObject(object, file, true, jprovider);
2385 if (_af != null && object.getJalviewModelSequence()
2386 .getViewportCount() > 0)
2390 // store a reference to the first view
2393 if (_af.viewport.isGatherViewsHere())
2395 // if this is a gathered view, keep its reference since
2396 // after gathering views, only this frame will remain
2398 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2400 // Save dataset to register mappings once all resolved
2401 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2402 af.viewport.getAlignment().getDataset());
2407 else if (jarentry != null)
2409 // Some other file here.
2412 } while (jarentry != null);
2413 resolveFrefedSequences();
2414 } catch (IOException ex)
2416 ex.printStackTrace();
2417 errorMessage = "Couldn't locate Jalview XML file : " + file;
2419 "Exception whilst loading jalview XML file : " + ex + "\n");
2420 } catch (Exception ex)
2422 System.err.println("Parsing as Jalview Version 2 file failed.");
2423 ex.printStackTrace(System.err);
2424 if (attemptversion1parse)
2426 // Is Version 1 Jar file?
2429 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2430 } catch (Exception ex2)
2432 System.err.println("Exception whilst loading as jalviewXMLV1:");
2433 ex2.printStackTrace();
2437 if (Desktop.instance != null)
2439 Desktop.instance.stopLoading();
2443 System.out.println("Successfully loaded archive file");
2446 ex.printStackTrace();
2449 "Exception whilst loading jalview XML file : " + ex + "\n");
2450 } catch (OutOfMemoryError e)
2452 // Don't use the OOM Window here
2453 errorMessage = "Out of memory loading jalview XML file";
2454 System.err.println("Out of memory whilst loading jalview XML file");
2455 e.printStackTrace();
2459 * Regather multiple views (with the same sequence set id) to the frame (if
2460 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2461 * views instead of separate frames. Note this doesn't restore a state where
2462 * some expanded views in turn have tabbed views - the last "first tab" read
2463 * in will play the role of gatherer for all.
2465 for (AlignFrame fr : gatherToThisFrame.values())
2467 Desktop.instance.gatherViews(fr);
2470 restoreSplitFrames();
2471 for (AlignmentI ds : importedDatasets.keySet())
2473 if (ds.getCodonFrames() != null)
2475 StructureSelectionManager
2476 .getStructureSelectionManager(Desktop.instance)
2477 .registerMappings(ds.getCodonFrames());
2480 if (errorMessage != null)
2485 if (Desktop.instance != null)
2487 Desktop.instance.stopLoading();
2494 * Try to reconstruct and display SplitFrame windows, where each contains
2495 * complementary dna and protein alignments. Done by pairing up AlignFrame
2496 * objects (created earlier) which have complementary viewport ids associated.
2498 protected void restoreSplitFrames()
2500 List<SplitFrame> gatherTo = new ArrayList<>();
2501 List<AlignFrame> addedToSplitFrames = new ArrayList<>();
2502 Map<String, AlignFrame> dna = new HashMap<>();
2505 * Identify the DNA alignments
2507 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2510 AlignFrame af = candidate.getValue();
2511 if (af.getViewport().getAlignment().isNucleotide())
2513 dna.put(candidate.getKey().getId(), af);
2518 * Try to match up the protein complements
2520 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2523 AlignFrame af = candidate.getValue();
2524 if (!af.getViewport().getAlignment().isNucleotide())
2526 String complementId = candidate.getKey().getComplementId();
2527 // only non-null complements should be in the Map
2528 if (complementId != null && dna.containsKey(complementId))
2530 final AlignFrame dnaFrame = dna.get(complementId);
2531 SplitFrame sf = createSplitFrame(dnaFrame, af);
2532 addedToSplitFrames.add(dnaFrame);
2533 addedToSplitFrames.add(af);
2534 dnaFrame.setMenusForViewport();
2535 af.setMenusForViewport();
2536 if (af.viewport.isGatherViewsHere())
2545 * Open any that we failed to pair up (which shouldn't happen!) as
2546 * standalone AlignFrame's.
2548 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2551 AlignFrame af = candidate.getValue();
2552 if (!addedToSplitFrames.contains(af))
2554 Viewport view = candidate.getKey();
2555 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2557 af.setMenusForViewport();
2558 System.err.println("Failed to restore view " + view.getTitle()
2559 + " to split frame");
2564 * Gather back into tabbed views as flagged.
2566 for (SplitFrame sf : gatherTo)
2568 Desktop.instance.gatherViews(sf);
2571 splitFrameCandidates.clear();
2575 * Construct and display one SplitFrame holding DNA and protein alignments.
2578 * @param proteinFrame
2581 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2582 AlignFrame proteinFrame)
2584 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2585 String title = MessageManager.getString("label.linked_view_title");
2586 int width = (int) dnaFrame.getBounds().getWidth();
2587 int height = (int) (dnaFrame.getBounds().getHeight()
2588 + proteinFrame.getBounds().getHeight() + 50);
2591 * SplitFrame location is saved to both enclosed frames
2593 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2594 Desktop.addInternalFrame(splitFrame, title, width, height);
2597 * And compute cDNA consensus (couldn't do earlier with consensus as
2598 * mappings were not yet present)
2600 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2606 * check errorMessage for a valid error message and raise an error box in the
2607 * GUI or write the current errorMessage to stderr and then clear the error
2610 protected void reportErrors()
2612 reportErrors(false);
2615 protected void reportErrors(final boolean saving)
2617 if (errorMessage != null)
2619 final String finalErrorMessage = errorMessage;
2622 javax.swing.SwingUtilities.invokeLater(new Runnable()
2627 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2629 "Error " + (saving ? "saving" : "loading")
2631 JvOptionPane.WARNING_MESSAGE);
2637 System.err.println("Problem loading Jalview file: " + errorMessage);
2640 errorMessage = null;
2643 Map<String, String> alreadyLoadedPDB = new HashMap<>();
2646 * when set, local views will be updated from view stored in JalviewXML
2647 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2648 * sync if this is set to true.
2650 private final boolean updateLocalViews = false;
2653 * Returns the path to a temporary file holding the PDB file for the given PDB
2654 * id. The first time of asking, searches for a file of that name in the
2655 * Jalview project jar, and copies it to a new temporary file. Any repeat
2656 * requests just return the path to the file previously created.
2662 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2665 if (alreadyLoadedPDB.containsKey(pdbId))
2667 return alreadyLoadedPDB.get(pdbId).toString();
2670 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2672 if (tempFile != null)
2674 alreadyLoadedPDB.put(pdbId, tempFile);
2680 * Copies the jar entry of given name to a new temporary file and returns the
2681 * path to the file, or null if the entry is not found.
2684 * @param jarEntryName
2686 * a prefix for the temporary file name, must be at least three
2689 * null or original file - so new file can be given the same suffix
2693 protected String copyJarEntry(jarInputStreamProvider jprovider,
2694 String jarEntryName, String prefix, String origFile)
2696 BufferedReader in = null;
2697 PrintWriter out = null;
2698 String suffix = ".tmp";
2699 if (origFile == null)
2701 origFile = jarEntryName;
2703 int sfpos = origFile.lastIndexOf(".");
2704 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2706 suffix = "." + origFile.substring(sfpos + 1);
2710 JarInputStream jin = jprovider.getJarInputStream();
2712 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2713 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2714 * FileInputStream(jprovider)); }
2717 JarEntry entry = null;
2720 entry = jin.getNextJarEntry();
2721 } while (entry != null && !entry.getName().equals(jarEntryName));
2724 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2725 File outFile = File.createTempFile(prefix, suffix);
2726 outFile.deleteOnExit();
2727 out = new PrintWriter(new FileOutputStream(outFile));
2730 while ((data = in.readLine()) != null)
2735 String t = outFile.getAbsolutePath();
2740 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2742 } catch (Exception ex)
2744 ex.printStackTrace();
2752 } catch (IOException e)
2766 private class JvAnnotRow
2768 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2775 * persisted version of annotation row from which to take vis properties
2777 public jalview.datamodel.AlignmentAnnotation template;
2780 * original position of the annotation row in the alignment
2786 * Load alignment frame from jalview XML DOM object
2791 * filename source string
2792 * @param loadTreesAndStructures
2793 * when false only create Viewport
2795 * data source provider
2796 * @return alignment frame created from view stored in DOM
2798 AlignFrame loadFromObject(JalviewModel object, String file,
2799 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2801 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2802 Sequence[] vamsasSeq = vamsasSet.getSequence();
2804 JalviewModelSequence jms = object.getJalviewModelSequence();
2806 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2809 // ////////////////////////////////
2812 List<SequenceI> hiddenSeqs = null;
2814 List<SequenceI> tmpseqs = new ArrayList<>();
2816 boolean multipleView = false;
2817 SequenceI referenceseqForView = null;
2818 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2819 int vi = 0; // counter in vamsasSeq array
2820 for (int i = 0; i < jseqs.length; i++)
2822 String seqId = jseqs[i].getId();
2824 SequenceI tmpSeq = seqRefIds.get(seqId);
2827 if (!incompleteSeqs.containsKey(seqId))
2829 // may not need this check, but keep it for at least 2.9,1 release
2830 if (tmpSeq.getStart() != jseqs[i].getStart()
2831 || tmpSeq.getEnd() != jseqs[i].getEnd())
2834 "Warning JAL-2154 regression: updating start/end for sequence "
2835 + tmpSeq.toString() + " to " + jseqs[i]);
2840 incompleteSeqs.remove(seqId);
2842 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2844 // most likely we are reading a dataset XML document so
2845 // update from vamsasSeq section of XML for this sequence
2846 tmpSeq.setName(vamsasSeq[vi].getName());
2847 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2848 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2853 // reading multiple views, so vamsasSeq set is a subset of JSeq
2854 multipleView = true;
2856 tmpSeq.setStart(jseqs[i].getStart());
2857 tmpSeq.setEnd(jseqs[i].getEnd());
2858 tmpseqs.add(tmpSeq);
2862 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2863 vamsasSeq[vi].getSequence());
2864 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2865 tmpSeq.setStart(jseqs[i].getStart());
2866 tmpSeq.setEnd(jseqs[i].getEnd());
2867 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2868 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2869 tmpseqs.add(tmpSeq);
2873 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2875 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2878 if (jseqs[i].getHidden())
2880 if (hiddenSeqs == null)
2882 hiddenSeqs = new ArrayList<>();
2885 hiddenSeqs.add(tmpSeq);
2890 // Create the alignment object from the sequence set
2891 // ///////////////////////////////
2892 SequenceI[] orderedSeqs = tmpseqs
2893 .toArray(new SequenceI[tmpseqs.size()]);
2895 AlignmentI al = null;
2896 // so we must create or recover the dataset alignment before going further
2897 // ///////////////////////////////
2898 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2900 // older jalview projects do not have a dataset - so creat alignment and
2902 al = new Alignment(orderedSeqs);
2903 al.setDataset(null);
2907 boolean isdsal = object.getJalviewModelSequence()
2908 .getViewportCount() == 0;
2911 // we are importing a dataset record, so
2912 // recover reference to an alignment already materialsed as dataset
2913 al = getDatasetFor(vamsasSet.getDatasetId());
2917 // materialse the alignment
2918 al = new Alignment(orderedSeqs);
2922 addDatasetRef(vamsasSet.getDatasetId(), al);
2925 // finally, verify all data in vamsasSet is actually present in al
2926 // passing on flag indicating if it is actually a stored dataset
2927 recoverDatasetFor(vamsasSet, al, isdsal);
2930 if (referenceseqForView != null)
2932 al.setSeqrep(referenceseqForView);
2934 // / Add the alignment properties
2935 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2937 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2938 al.setProperty(ssp.getKey(), ssp.getValue());
2941 // ///////////////////////////////
2943 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2946 // load sequence features, database references and any associated PDB
2947 // structures for the alignment
2949 // prior to 2.10, this part would only be executed the first time a
2950 // sequence was encountered, but not afterwards.
2951 // now, for 2.10 projects, this is also done if the xml doc includes
2952 // dataset sequences not actually present in any particular view.
2954 for (int i = 0; i < vamsasSeq.length; i++)
2956 if (jseqs[i].getFeaturesCount() > 0)
2958 Features[] features = jseqs[i].getFeatures();
2959 for (int f = 0; f < features.length; f++)
2961 SequenceFeature sf = new SequenceFeature(features[f].getType(),
2962 features[f].getDescription(), features[f].getBegin(),
2963 features[f].getEnd(), features[f].getScore(),
2964 features[f].getFeatureGroup());
2965 sf.setStatus(features[f].getStatus());
2966 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2968 OtherData keyValue = features[f].getOtherData(od);
2969 if (keyValue.getKey().startsWith("LINK"))
2971 sf.addLink(keyValue.getValue());
2975 sf.setValue(keyValue.getKey(), keyValue.getValue());
2979 // adds feature to datasequence's feature set (since Jalview 2.10)
2980 al.getSequenceAt(i).addSequenceFeature(sf);
2983 if (vamsasSeq[i].getDBRefCount() > 0)
2985 // adds dbrefs to datasequence's set (since Jalview 2.10)
2987 al.getSequenceAt(i).getDatasetSequence() == null
2988 ? al.getSequenceAt(i)
2989 : al.getSequenceAt(i).getDatasetSequence(),
2992 if (jseqs[i].getPdbidsCount() > 0)
2994 Pdbids[] ids = jseqs[i].getPdbids();
2995 for (int p = 0; p < ids.length; p++)
2997 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2998 entry.setId(ids[p].getId());
2999 if (ids[p].getType() != null)
3001 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3003 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3007 entry.setType(PDBEntry.Type.FILE);
3010 // jprovider is null when executing 'New View'
3011 if (ids[p].getFile() != null && jprovider != null)
3013 if (!pdbloaded.containsKey(ids[p].getFile()))
3015 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3020 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3023 if (ids[p].getPdbentryItem() != null)
3025 for (PdbentryItem item : ids[p].getPdbentryItem())
3027 for (Property pr : item.getProperty())
3029 entry.setProperty(pr.getName(), pr.getValue());
3033 StructureSelectionManager
3034 .getStructureSelectionManager(Desktop.instance)
3035 .registerPDBEntry(entry);
3036 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3037 if (al.getSequenceAt(i).getDatasetSequence() != null)
3039 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3043 al.getSequenceAt(i).addPDBId(entry);
3048 } // end !multipleview
3050 // ///////////////////////////////
3051 // LOAD SEQUENCE MAPPINGS
3053 if (vamsasSet.getAlcodonFrameCount() > 0)
3055 // TODO Potentially this should only be done once for all views of an
3057 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3058 for (int i = 0; i < alc.length; i++)
3060 AlignedCodonFrame cf = new AlignedCodonFrame();
3061 if (alc[i].getAlcodMapCount() > 0)
3063 AlcodMap[] maps = alc[i].getAlcodMap();
3064 for (int m = 0; m < maps.length; m++)
3066 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3068 jalview.datamodel.Mapping mapping = null;
3069 // attach to dna sequence reference.
3070 if (maps[m].getMapping() != null)
3072 mapping = addMapping(maps[m].getMapping());
3073 if (dnaseq != null && mapping.getTo() != null)
3075 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3081 newAlcodMapRef(maps[m].getDnasq(), cf, mapping));
3085 al.addCodonFrame(cf);
3090 // ////////////////////////////////
3092 List<JvAnnotRow> autoAlan = new ArrayList<>();
3095 * store any annotations which forward reference a group's ID
3097 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<>();
3099 if (vamsasSet.getAnnotationCount() > 0)
3101 Annotation[] an = vamsasSet.getAnnotation();
3103 for (int i = 0; i < an.length; i++)
3105 Annotation annotation = an[i];
3108 * test if annotation is automatically calculated for this view only
3110 boolean autoForView = false;
3111 if (annotation.getLabel().equals("Quality")
3112 || annotation.getLabel().equals("Conservation")
3113 || annotation.getLabel().equals("Consensus"))
3115 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3117 if (!annotation.hasAutoCalculated())
3119 annotation.setAutoCalculated(true);
3122 if (autoForView || (annotation.hasAutoCalculated()
3123 && annotation.isAutoCalculated()))
3125 // remove ID - we don't recover annotation from other views for
3126 // view-specific annotation
3127 annotation.setId(null);
3130 // set visiblity for other annotation in this view
3131 String annotationId = annotation.getId();
3132 if (annotationId != null && annotationIds.containsKey(annotationId))
3134 AlignmentAnnotation jda = annotationIds.get(annotationId);
3135 // in principle Visible should always be true for annotation displayed
3136 // in multiple views
3137 if (annotation.hasVisible())
3139 jda.visible = annotation.getVisible();
3142 al.addAnnotation(jda);
3146 // Construct new annotation from model.
3147 AnnotationElement[] ae = annotation.getAnnotationElement();
3148 jalview.datamodel.Annotation[] anot = null;
3149 java.awt.Color firstColour = null;
3151 if (!annotation.getScoreOnly())
3153 anot = new jalview.datamodel.Annotation[al.getWidth()];
3154 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3156 anpos = ae[aa].getPosition();
3158 if (anpos >= anot.length)
3163 anot[anpos] = new jalview.datamodel.Annotation(
3165 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3166 (ae[aa].getSecondaryStructure() == null
3167 || ae[aa].getSecondaryStructure().length() == 0)
3169 : ae[aa].getSecondaryStructure()
3174 // JBPNote: Consider verifying dataflow for IO of secondary
3175 // structure annotation read from Stockholm files
3176 // this was added to try to ensure that
3177 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3179 // anot[ae[aa].getPosition()].displayCharacter = "";
3181 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3182 if (firstColour == null)
3184 firstColour = anot[anpos].colour;
3188 jalview.datamodel.AlignmentAnnotation jaa = null;
3190 if (annotation.getGraph())
3192 float llim = 0, hlim = 0;
3193 // if (autoForView || an[i].isAutoCalculated()) {
3196 jaa = new jalview.datamodel.AlignmentAnnotation(
3197 annotation.getLabel(), annotation.getDescription(), anot,
3198 llim, hlim, annotation.getGraphType());
3200 jaa.graphGroup = annotation.getGraphGroup();
3201 jaa._linecolour = firstColour;
3202 if (annotation.getThresholdLine() != null)
3204 jaa.setThreshold(new jalview.datamodel.GraphLine(
3205 annotation.getThresholdLine().getValue(),
3206 annotation.getThresholdLine().getLabel(),
3208 annotation.getThresholdLine().getColour())));
3211 if (autoForView || annotation.isAutoCalculated())
3213 // Hardwire the symbol display line to ensure that labels for
3214 // histograms are displayed
3220 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3221 an[i].getDescription(), anot);
3222 jaa._linecolour = firstColour;
3224 // register new annotation
3225 if (an[i].getId() != null)
3227 annotationIds.put(an[i].getId(), jaa);
3228 jaa.annotationId = an[i].getId();
3230 // recover sequence association
3231 String sequenceRef = an[i].getSequenceRef();
3232 if (sequenceRef != null)
3234 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3235 SequenceI sequence = seqRefIds.get(sequenceRef);
3236 if (sequence == null)
3238 // in pre-2.9 projects sequence ref is to sequence name
3239 sequence = al.findName(sequenceRef);
3241 if (sequence != null)
3243 jaa.createSequenceMapping(sequence, 1, true);
3244 sequence.addAlignmentAnnotation(jaa);
3247 // and make a note of any group association
3248 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3250 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3251 .get(an[i].getGroupRef());
3254 aal = new ArrayList<>();
3255 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3260 if (an[i].hasScore())
3262 jaa.setScore(an[i].getScore());
3264 if (an[i].hasVisible())
3266 jaa.visible = an[i].getVisible();
3269 if (an[i].hasCentreColLabels())
3271 jaa.centreColLabels = an[i].getCentreColLabels();
3274 if (an[i].hasScaleColLabels())
3276 jaa.scaleColLabel = an[i].getScaleColLabels();
3278 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3280 // newer files have an 'autoCalculated' flag and store calculation
3281 // state in viewport properties
3282 jaa.autoCalculated = true; // means annotation will be marked for
3283 // update at end of load.
3285 if (an[i].hasGraphHeight())
3287 jaa.graphHeight = an[i].getGraphHeight();
3289 if (an[i].hasBelowAlignment())
3291 jaa.belowAlignment = an[i].isBelowAlignment();
3293 jaa.setCalcId(an[i].getCalcId());
3294 if (an[i].getPropertyCount() > 0)
3296 for (jalview.schemabinding.version2.Property prop : an[i]
3299 jaa.setProperty(prop.getName(), prop.getValue());
3302 if (jaa.autoCalculated)
3304 autoAlan.add(new JvAnnotRow(i, jaa));
3307 // if (!autoForView)
3309 // add autocalculated group annotation and any user created annotation
3311 al.addAnnotation(jaa);
3315 // ///////////////////////
3317 // Create alignment markup and styles for this view
3318 if (jms.getJGroupCount() > 0)
3320 JGroup[] groups = jms.getJGroup();
3321 boolean addAnnotSchemeGroup = false;
3322 for (int i = 0; i < groups.length; i++)
3324 JGroup jGroup = groups[i];
3325 ColourSchemeI cs = null;
3326 if (jGroup.getColour() != null)
3328 if (jGroup.getColour().startsWith("ucs"))
3330 cs = getUserColourScheme(jms, jGroup.getColour());
3332 else if (jGroup.getColour().equals("AnnotationColourGradient")
3333 && jGroup.getAnnotationColours() != null)
3335 addAnnotSchemeGroup = true;
3339 cs = ColourSchemeProperty.getColourScheme(al,
3340 jGroup.getColour());
3343 int pidThreshold = jGroup.getPidThreshold();
3345 Vector<SequenceI> seqs = new Vector<>();
3347 for (int s = 0; s < jGroup.getSeqCount(); s++)
3349 String seqId = jGroup.getSeq(s) + "";
3350 SequenceI ts = seqRefIds.get(seqId);
3354 seqs.addElement(ts);
3358 if (seqs.size() < 1)
3363 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3364 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3365 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3366 sg.getGroupColourScheme().setThreshold(pidThreshold, true);
3367 sg.getGroupColourScheme()
3368 .setConservationInc(jGroup.getConsThreshold());
3369 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3371 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3372 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3373 sg.setShowNonconserved(
3374 jGroup.hasShowUnconserved() ? jGroup.isShowUnconserved()
3376 sg.thresholdTextColour = jGroup.getTextColThreshold();
3377 if (jGroup.hasShowConsensusHistogram())
3379 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3382 if (jGroup.hasShowSequenceLogo())
3384 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3386 if (jGroup.hasNormaliseSequenceLogo())
3388 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3390 if (jGroup.hasIgnoreGapsinConsensus())
3392 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3394 if (jGroup.getConsThreshold() != 0)
3396 Conservation c = new Conservation("All", sg.getSequences(null), 0,
3399 c.verdict(false, 25);
3400 sg.cs.setConservation(c);
3403 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3405 // re-instate unique group/annotation row reference
3406 List<AlignmentAnnotation> jaal = groupAnnotRefs
3407 .get(jGroup.getId());
3410 for (AlignmentAnnotation jaa : jaal)
3413 if (jaa.autoCalculated)
3415 // match up and try to set group autocalc alignment row for this
3417 if (jaa.label.startsWith("Consensus for "))
3419 sg.setConsensus(jaa);
3421 // match up and try to set group autocalc alignment row for this
3423 if (jaa.label.startsWith("Conservation for "))
3425 sg.setConservationRow(jaa);
3432 if (addAnnotSchemeGroup)
3434 // reconstruct the annotation colourscheme
3435 sg.setColourScheme(constructAnnotationColour(
3436 jGroup.getAnnotationColours(), null, al, jms, false));
3442 // only dataset in this model, so just return.
3445 // ///////////////////////////////
3448 // If we just load in the same jar file again, the sequenceSetId
3449 // will be the same, and we end up with multiple references
3450 // to the same sequenceSet. We must modify this id on load
3451 // so that each load of the file gives a unique id
3452 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3453 String viewId = (view.getId() == null ? null
3454 : view.getId() + uniqueSetSuffix);
3455 AlignFrame af = null;
3456 AlignViewport av = null;
3457 // now check to see if we really need to create a new viewport.
3458 if (multipleView && viewportsAdded.size() == 0)
3460 // We recovered an alignment for which a viewport already exists.
3461 // TODO: fix up any settings necessary for overlaying stored state onto
3462 // state recovered from another document. (may not be necessary).
3463 // we may need a binding from a viewport in memory to one recovered from
3465 // and then recover its containing af to allow the settings to be applied.
3466 // TODO: fix for vamsas demo
3468 "About to recover a viewport for existing alignment: Sequence set ID is "
3470 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3471 if (seqsetobj != null)
3473 if (seqsetobj instanceof String)
3475 uniqueSeqSetId = (String) seqsetobj;
3477 "Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3483 "Warning : Collision between sequence set ID string and existing jalview object mapping.");
3489 * indicate that annotation colours are applied across all groups (pre
3490 * Jalview 2.8.1 behaviour)
3492 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan("2.8.1",
3493 object.getVersion());
3495 AlignmentPanel ap = null;
3496 boolean isnewview = true;
3499 // Check to see if this alignment already has a view id == viewId
3500 jalview.gui.AlignmentPanel views[] = Desktop
3501 .getAlignmentPanels(uniqueSeqSetId);
3502 if (views != null && views.length > 0)
3504 for (int v = 0; v < views.length; v++)
3506 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3508 // recover the existing alignpanel, alignframe, viewport
3509 af = views[v].alignFrame;
3512 // TODO: could even skip resetting view settings if we don't want to
3513 // change the local settings from other jalview processes
3522 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3523 uniqueSeqSetId, viewId, autoAlan);
3529 * Load any trees, PDB structures and viewers
3531 * Not done if flag is false (when this method is used for New View)
3533 if (loadTreesAndStructures)
3535 loadTrees(jms, view, af, av, ap);
3536 loadPDBStructures(jprovider, jseqs, af, ap);
3537 loadRnaViewers(jprovider, jseqs, ap);
3539 // and finally return.
3544 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3545 * panel is restored from separate jar entries, two (gapped and trimmed) per
3546 * sequence and secondary structure.
3548 * Currently each viewer shows just one sequence and structure (gapped and
3549 * trimmed), however this method is designed to support multiple sequences or
3550 * structures in viewers if wanted in future.
3556 private void loadRnaViewers(jarInputStreamProvider jprovider,
3557 JSeq[] jseqs, AlignmentPanel ap)
3560 * scan the sequences for references to viewers; create each one the first
3561 * time it is referenced, add Rna models to existing viewers
3563 for (JSeq jseq : jseqs)
3565 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3567 RnaViewer viewer = jseq.getRnaViewer(i);
3568 AppVarna appVarna = findOrCreateVarnaViewer(viewer, uniqueSetSuffix,
3571 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3573 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3574 SequenceI seq = seqRefIds.get(jseq.getId());
3575 AlignmentAnnotation ann = this.annotationIds
3576 .get(ss.getAnnotationId());
3579 * add the structure to the Varna display (with session state copied
3580 * from the jar to a temporary file)
3582 boolean gapped = ss.isGapped();
3583 String rnaTitle = ss.getTitle();
3584 String sessionState = ss.getViewerState();
3585 String tempStateFile = copyJarEntry(jprovider, sessionState,
3587 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3588 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3590 appVarna.setInitialSelection(viewer.getSelectedRna());
3596 * Locate and return an already instantiated matching AppVarna, or create one
3600 * @param viewIdSuffix
3604 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3605 String viewIdSuffix, AlignmentPanel ap)
3608 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3609 * if load is repeated
3611 String postLoadId = viewer.getViewId() + viewIdSuffix;
3612 for (JInternalFrame frame : getAllFrames())
3614 if (frame instanceof AppVarna)
3616 AppVarna varna = (AppVarna) frame;
3617 if (postLoadId.equals(varna.getViewId()))
3619 // this viewer is already instantiated
3620 // could in future here add ap as another 'parent' of the
3621 // AppVarna window; currently just 1-to-many
3628 * viewer not found - make it
3630 RnaViewerModel model = new RnaViewerModel(postLoadId, viewer.getTitle(),
3631 viewer.getXpos(), viewer.getYpos(), viewer.getWidth(),
3632 viewer.getHeight(), viewer.getDividerLocation());
3633 AppVarna varna = new AppVarna(model, ap);
3639 * Load any saved trees
3647 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3648 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3650 // TODO result of automated refactoring - are all these parameters needed?
3653 for (int t = 0; t < jms.getTreeCount(); t++)
3656 Tree tree = jms.getTree(t);
3658 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3661 tp = af.showNewickTree(
3662 new jalview.io.NewickFile(tree.getNewick()),
3663 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3664 tree.getXpos(), tree.getYpos());
3665 if (tree.getId() != null)
3667 // perhaps bind the tree id to something ?
3672 // update local tree attributes ?
3673 // TODO: should check if tp has been manipulated by user - if so its
3674 // settings shouldn't be modified
3675 tp.setTitle(tree.getTitle());
3676 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(),
3677 tree.getWidth(), tree.getHeight()));
3678 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3681 tp.treeCanvas.av = av; // af.viewport;
3682 tp.treeCanvas.ap = ap; // af.alignPanel;
3687 warn("There was a problem recovering stored Newick tree: \n"
3688 + tree.getNewick());
3692 tp.fitToWindow.setState(tree.getFitToWindow());
3693 tp.fitToWindow_actionPerformed(null);
3695 if (tree.getFontName() != null)
3697 tp.setTreeFont(new java.awt.Font(tree.getFontName(),
3698 tree.getFontStyle(), tree.getFontSize()));
3702 tp.setTreeFont(new java.awt.Font(view.getFontName(),
3703 view.getFontStyle(), tree.getFontSize()));
3706 tp.showPlaceholders(tree.getMarkUnlinked());
3707 tp.showBootstrap(tree.getShowBootstrap());
3708 tp.showDistances(tree.getShowDistances());
3710 tp.treeCanvas.threshold = tree.getThreshold();
3712 if (tree.getCurrentTree())
3714 af.viewport.setCurrentTree(tp.getTree());
3718 } catch (Exception ex)
3720 ex.printStackTrace();
3725 * Load and link any saved structure viewers.
3732 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3733 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3736 * Run through all PDB ids on the alignment, and collect mappings between
3737 * distinct view ids and all sequences referring to that view.
3739 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<>();
3741 for (int i = 0; i < jseqs.length; i++)
3743 if (jseqs[i].getPdbidsCount() > 0)
3745 Pdbids[] ids = jseqs[i].getPdbids();
3746 for (int p = 0; p < ids.length; p++)
3748 final int structureStateCount = ids[p].getStructureStateCount();
3749 for (int s = 0; s < structureStateCount; s++)
3751 // check to see if we haven't already created this structure view
3752 final StructureState structureState = ids[p]
3753 .getStructureState(s);
3754 String sviewid = (structureState.getViewId() == null) ? null
3755 : structureState.getViewId() + uniqueSetSuffix;
3756 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3757 // Originally : ids[p].getFile()
3758 // : TODO: verify external PDB file recovery still works in normal
3759 // jalview project load
3760 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3762 jpdb.setId(ids[p].getId());
3764 int x = structureState.getXpos();
3765 int y = structureState.getYpos();
3766 int width = structureState.getWidth();
3767 int height = structureState.getHeight();
3769 // Probably don't need to do this anymore...
3770 // Desktop.desktop.getComponentAt(x, y);
3771 // TODO: NOW: check that this recovers the PDB file correctly.
3772 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3774 jalview.datamodel.SequenceI seq = seqRefIds
3775 .get(jseqs[i].getId() + "");
3776 if (sviewid == null)
3778 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width + ","
3781 if (!structureViewers.containsKey(sviewid))
3783 structureViewers.put(sviewid,
3784 new StructureViewerModel(x, y, width, height, false,
3785 false, true, structureState.getViewId(),
3786 structureState.getType()));
3787 // Legacy pre-2.7 conversion JAL-823 :
3788 // do not assume any view has to be linked for colour by
3792 // assemble String[] { pdb files }, String[] { id for each
3793 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3794 // seqs_file 2}, boolean[] {
3795 // linkAlignPanel,superposeWithAlignpanel}} from hash
3796 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3797 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3798 | (structureState.hasAlignwithAlignPanel()
3799 ? structureState.getAlignwithAlignPanel()
3803 * Default colour by linked panel to false if not specified (e.g.
3804 * for pre-2.7 projects)
3806 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3807 colourWithAlignPanel |= (structureState
3808 .hasColourwithAlignPanel()
3809 ? structureState.getColourwithAlignPanel()
3811 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3814 * Default colour by viewer to true if not specified (e.g. for
3817 boolean colourByViewer = jmoldat.isColourByViewer();
3818 colourByViewer &= structureState.hasColourByJmol()
3819 ? structureState.getColourByJmol()
3821 jmoldat.setColourByViewer(colourByViewer);
3823 if (jmoldat.getStateData().length() < structureState
3824 .getContent().length())
3827 jmoldat.setStateData(structureState.getContent());
3830 if (ids[p].getFile() != null)
3832 File mapkey = new File(ids[p].getFile());
3833 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3834 if (seqstrmaps == null)
3836 jmoldat.getFileData().put(mapkey,
3837 seqstrmaps = jmoldat.new StructureData(pdbFile,
3840 if (!seqstrmaps.getSeqList().contains(seq))
3842 seqstrmaps.getSeqList().add(seq);
3848 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");
3855 // Instantiate the associated structure views
3856 for (Entry<String, StructureViewerModel> entry : structureViewers
3861 createOrLinkStructureViewer(entry, af, ap, jprovider);
3862 } catch (Exception e)
3865 "Error loading structure viewer: " + e.getMessage());
3866 // failed - try the next one
3878 protected void createOrLinkStructureViewer(
3879 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3880 AlignmentPanel ap, jarInputStreamProvider jprovider)
3882 final StructureViewerModel stateData = viewerData.getValue();
3885 * Search for any viewer windows already open from other alignment views
3886 * that exactly match the stored structure state
3888 StructureViewerBase comp = findMatchingViewer(viewerData);
3892 linkStructureViewer(ap, comp, stateData);
3897 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3898 * "viewer_"+stateData.viewId
3900 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3902 createChimeraViewer(viewerData, af, jprovider);
3907 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3909 createJmolViewer(viewerData, af, jprovider);
3914 * Create a new Chimera viewer.
3920 protected void createChimeraViewer(
3921 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3922 jarInputStreamProvider jprovider)
3924 StructureViewerModel data = viewerData.getValue();
3925 String chimeraSessionFile = data.getStateData();
3928 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3930 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3931 * 'uniquified' sviewid used to reconstruct the viewer here
3933 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3934 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3937 Set<Entry<File, StructureData>> fileData = data.getFileData()
3939 List<PDBEntry> pdbs = new ArrayList<>();
3940 List<SequenceI[]> allseqs = new ArrayList<>();
3941 for (Entry<File, StructureData> pdb : fileData)
3943 String filePath = pdb.getValue().getFilePath();
3944 String pdbId = pdb.getValue().getPdbId();
3945 // pdbs.add(new PDBEntry(filePath, pdbId));
3946 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3947 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3948 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3952 boolean colourByChimera = data.isColourByViewer();
3953 boolean colourBySequence = data.isColourWithAlignPanel();
3955 // TODO use StructureViewer as a factory here, see JAL-1761
3956 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3957 final SequenceI[][] seqsArray = allseqs
3958 .toArray(new SequenceI[allseqs.size()][]);
3959 String newViewId = viewerData.getKey();
3961 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3962 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3963 colourBySequence, newViewId);
3964 cvf.setSize(data.getWidth(), data.getHeight());
3965 cvf.setLocation(data.getX(), data.getY());
3969 * Create a new Jmol window. First parse the Jmol state to translate filenames
3970 * loaded into the view, and record the order in which files are shown in the
3971 * Jmol view, so we can add the sequence mappings in same order.
3977 protected void createJmolViewer(
3978 final Entry<String, StructureViewerModel> viewerData,
3979 AlignFrame af, jarInputStreamProvider jprovider)
3981 final StructureViewerModel svattrib = viewerData.getValue();
3982 String state = svattrib.getStateData();
3985 * Pre-2.9: state element value is the Jmol state string
3987 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3990 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3992 state = readJarEntry(jprovider,
3993 getViewerJarEntryName(svattrib.getViewId()));
3996 List<String> pdbfilenames = new ArrayList<>();
3997 List<SequenceI[]> seqmaps = new ArrayList<>();
3998 List<String> pdbids = new ArrayList<>();
3999 StringBuilder newFileLoc = new StringBuilder(64);
4000 int cp = 0, ncp, ecp;
4001 Map<File, StructureData> oldFiles = svattrib.getFileData();
4002 while ((ncp = state.indexOf("load ", cp)) > -1)
4006 // look for next filename in load statement
4007 newFileLoc.append(state.substring(cp,
4008 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4009 String oldfilenam = state.substring(ncp,
4010 ecp = state.indexOf("\"", ncp));
4011 // recover the new mapping data for this old filename
4012 // have to normalize filename - since Jmol and jalview do
4014 // translation differently.
4015 StructureData filedat = oldFiles.get(new File(oldfilenam));
4016 if (filedat == null)
4018 String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
4019 filedat = oldFiles.get(new File(reformatedOldFilename));
4021 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4022 pdbfilenames.add(filedat.getFilePath());
4023 pdbids.add(filedat.getPdbId());
4024 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4025 newFileLoc.append("\"");
4026 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4027 // look for next file statement.
4028 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4032 // just append rest of state
4033 newFileLoc.append(state.substring(cp));
4037 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4038 newFileLoc = new StringBuilder(state);
4039 newFileLoc.append("; load append ");
4040 for (File id : oldFiles.keySet())
4042 // add this and any other pdb files that should be present in
4044 StructureData filedat = oldFiles.get(id);
4045 newFileLoc.append(filedat.getFilePath());
4046 pdbfilenames.add(filedat.getFilePath());
4047 pdbids.add(filedat.getPdbId());
4048 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4049 newFileLoc.append(" \"");
4050 newFileLoc.append(filedat.getFilePath());
4051 newFileLoc.append("\"");
4054 newFileLoc.append(";");
4057 if (newFileLoc.length() == 0)
4061 int histbug = newFileLoc.indexOf("history = ");
4065 * change "history = [true|false];" to "history = [1|0];"
4068 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4069 String val = (diff == -1) ? null
4070 : newFileLoc.substring(histbug, diff);
4071 if (val != null && val.length() >= 4)
4073 if (val.contains("e")) // eh? what can it be?
4075 if (val.trim().equals("true"))
4083 newFileLoc.replace(histbug, diff, val);
4088 final String[] pdbf = pdbfilenames
4089 .toArray(new String[pdbfilenames.size()]);
4090 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4091 final SequenceI[][] sq = seqmaps
4092 .toArray(new SequenceI[seqmaps.size()][]);
4093 final String fileloc = newFileLoc.toString();
4094 final String sviewid = viewerData.getKey();
4095 final AlignFrame alf = af;
4096 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4097 svattrib.getWidth(), svattrib.getHeight());
4100 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4105 JalviewStructureDisplayI sview = null;
4108 sview = new StructureViewer(
4109 alf.alignPanel.getStructureSelectionManager())
4110 .createView(StructureViewer.ViewerType.JMOL,
4111 pdbf, id, sq, alf.alignPanel, svattrib,
4112 fileloc, rect, sviewid);
4113 addNewStructureViewer(sview);
4114 } catch (OutOfMemoryError ex)
4116 new OOMWarning("restoring structure view for PDB id " + id,
4117 (OutOfMemoryError) ex.getCause());
4118 if (sview != null && sview.isVisible())
4120 sview.closeViewer(false);
4121 sview.setVisible(false);
4127 } catch (InvocationTargetException ex)
4129 warn("Unexpected error when opening Jmol view.", ex);
4131 } catch (InterruptedException e)
4133 // e.printStackTrace();
4139 * Generates a name for the entry in the project jar file to hold state
4140 * information for a structure viewer
4145 protected String getViewerJarEntryName(String viewId)
4147 return VIEWER_PREFIX + viewId;
4151 * Returns any open frame that matches given structure viewer data. The match
4152 * is based on the unique viewId, or (for older project versions) the frame's
4158 protected StructureViewerBase findMatchingViewer(
4159 Entry<String, StructureViewerModel> viewerData)
4161 final String sviewid = viewerData.getKey();
4162 final StructureViewerModel svattrib = viewerData.getValue();
4163 StructureViewerBase comp = null;
4164 JInternalFrame[] frames = getAllFrames();
4165 for (JInternalFrame frame : frames)
4167 if (frame instanceof StructureViewerBase)
4170 * Post jalview 2.4 schema includes structure view id
4172 if (sviewid != null && ((StructureViewerBase) frame).getViewId()
4175 comp = (StructureViewerBase) frame;
4176 break; // break added in 2.9
4179 * Otherwise test for matching position and size of viewer frame
4181 else if (frame.getX() == svattrib.getX()
4182 && frame.getY() == svattrib.getY()
4183 && frame.getHeight() == svattrib.getHeight()
4184 && frame.getWidth() == svattrib.getWidth())
4186 comp = (StructureViewerBase) frame;
4187 // no break in faint hope of an exact match on viewId
4195 * Link an AlignmentPanel to an existing structure viewer.
4200 * @param useinViewerSuperpos
4201 * @param usetoColourbyseq
4202 * @param viewerColouring
4204 protected void linkStructureViewer(AlignmentPanel ap,
4205 StructureViewerBase viewer, StructureViewerModel stateData)
4207 // NOTE: if the jalview project is part of a shared session then
4208 // view synchronization should/could be done here.
4210 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4211 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4212 final boolean viewerColouring = stateData.isColourByViewer();
4213 Map<File, StructureData> oldFiles = stateData.getFileData();
4216 * Add mapping for sequences in this view to an already open viewer
4218 final AAStructureBindingModel binding = viewer.getBinding();
4219 for (File id : oldFiles.keySet())
4221 // add this and any other pdb files that should be present in the
4223 StructureData filedat = oldFiles.get(id);
4224 String pdbFile = filedat.getFilePath();
4225 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4226 binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE,
4228 binding.addSequenceForStructFile(pdbFile, seq);
4230 // and add the AlignmentPanel's reference to the view panel
4231 viewer.addAlignmentPanel(ap);
4232 if (useinViewerSuperpos)
4234 viewer.useAlignmentPanelForSuperposition(ap);
4238 viewer.excludeAlignmentPanelForSuperposition(ap);
4240 if (usetoColourbyseq)
4242 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4246 viewer.excludeAlignmentPanelForColourbyseq(ap);
4251 * Get all frames within the Desktop.
4255 protected JInternalFrame[] getAllFrames()
4257 JInternalFrame[] frames = null;
4258 // TODO is this necessary - is it safe - risk of hanging?
4263 frames = Desktop.desktop.getAllFrames();
4264 } catch (ArrayIndexOutOfBoundsException e)
4266 // occasional No such child exceptions are thrown here...
4270 } catch (InterruptedException f)
4274 } while (frames == null);
4279 * Answers true if 'version' is equal to or later than 'supported', where each
4280 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4281 * changes. Development and test values for 'version' are leniently treated
4285 * - minimum version we are comparing against
4287 * - version of data being processsed
4290 public static boolean isVersionStringLaterThan(String supported,
4293 if (supported == null || version == null
4294 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4295 || version.equalsIgnoreCase("Test")
4296 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4298 System.err.println("Assuming project file with "
4299 + (version == null ? "null" : version)
4300 + " is compatible with Jalview version " + supported);
4305 return StringUtils.compareVersions(version, supported, "b") >= 0;
4309 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4311 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4313 if (newStructureViewers != null)
4315 sview.getBinding().setFinishedLoadingFromArchive(false);
4316 newStructureViewers.add(sview);
4320 protected void setLoadingFinishedForNewStructureViewers()
4322 if (newStructureViewers != null)
4324 for (JalviewStructureDisplayI sview : newStructureViewers)
4326 sview.getBinding().setFinishedLoadingFromArchive(true);
4328 newStructureViewers.clear();
4329 newStructureViewers = null;
4333 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4334 List<SequenceI> hiddenSeqs, AlignmentI al,
4335 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4336 String viewId, List<JvAnnotRow> autoAlan)
4338 AlignFrame af = null;
4339 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4340 uniqueSeqSetId, viewId);
4342 af.setFileName(file, FileFormat.Jalview);
4344 for (int i = 0; i < JSEQ.length; i++)
4346 af.viewport.setSequenceColour(
4347 af.viewport.getAlignment().getSequenceAt(i),
4348 new java.awt.Color(JSEQ[i].getColour()));
4353 af.getViewport().setColourByReferenceSeq(true);
4354 af.getViewport().setDisplayReferenceSeq(true);
4357 af.viewport.setGatherViewsHere(view.getGatheredViews());
4359 if (view.getSequenceSetId() != null)
4361 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4363 af.viewport.setSequenceSetId(uniqueSeqSetId);
4366 // propagate shared settings to this new view
4367 af.viewport.setHistoryList(av.getHistoryList());
4368 af.viewport.setRedoList(av.getRedoList());
4372 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4374 // TODO: check if this method can be called repeatedly without
4375 // side-effects if alignpanel already registered.
4376 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4378 // apply Hidden regions to view.
4379 if (hiddenSeqs != null)
4381 for (int s = 0; s < JSEQ.length; s++)
4383 SequenceGroup hidden = new SequenceGroup();
4384 boolean isRepresentative = false;
4385 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4387 isRepresentative = true;
4388 SequenceI sequenceToHide = al
4389 .getSequenceAt(JSEQ[s].getHiddenSequences(r));
4390 hidden.addSequence(sequenceToHide, false);
4391 // remove from hiddenSeqs list so we don't try to hide it twice
4392 hiddenSeqs.remove(sequenceToHide);
4394 if (isRepresentative)
4396 SequenceI representativeSequence = al.getSequenceAt(s);
4397 hidden.addSequence(representativeSequence, false);
4398 af.viewport.hideRepSequences(representativeSequence, hidden);
4402 SequenceI[] hseqs = hiddenSeqs
4403 .toArray(new SequenceI[hiddenSeqs.size()]);
4404 af.viewport.hideSequence(hseqs);
4407 // recover view properties and display parameters
4409 af.viewport.setShowAnnotation(view.getShowAnnotation());
4410 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4411 af.viewport.setThreshold(view.getPidThreshold());
4413 af.viewport.setColourText(view.getShowColourText());
4415 af.viewport.setConservationSelected(view.getConservationSelected());
4416 af.viewport.setIncrement(view.getConsThreshold());
4417 af.viewport.setShowJVSuffix(view.getShowFullId());
4418 af.viewport.setRightAlignIds(view.getRightAlignIds());
4419 af.viewport.setFont(new java.awt.Font(view.getFontName(),
4420 view.getFontStyle(), view.getFontSize()), true);
4421 ViewStyleI vs = af.viewport.getViewStyle();
4422 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4423 af.viewport.setViewStyle(vs);
4424 // TODO: allow custom charWidth/Heights to be restored by updating them
4425 // after setting font - which means set above to false
4426 af.viewport.setRenderGaps(view.getRenderGaps());
4427 af.viewport.setWrapAlignment(view.getWrapAlignment());
4428 af.viewport.setShowAnnotation(view.getShowAnnotation());
4430 af.viewport.setShowBoxes(view.getShowBoxes());
4432 af.viewport.setShowText(view.getShowText());
4434 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4435 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4436 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4437 af.viewport.setShowUnconserved(
4438 view.hasShowUnconserved() ? view.isShowUnconserved() : false);
4439 af.viewport.getRanges().setStartRes(view.getStartRes());
4441 if (view.getViewName() != null)
4443 af.viewport.viewName = view.getViewName();
4444 af.setInitialTabVisible();
4446 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4448 // startSeq set in af.alignPanel.updateLayout below
4449 af.alignPanel.updateLayout();
4450 ColourSchemeI cs = null;
4451 // apply colourschemes
4452 if (view.getBgColour() != null)
4454 if (view.getBgColour().startsWith("ucs"))
4456 cs = getUserColourScheme(jms, view.getBgColour());
4458 else if (view.getBgColour().startsWith("Annotation"))
4460 AnnotationColours viewAnnColour = view.getAnnotationColours();
4461 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4468 cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour());
4472 af.viewport.setGlobalColourScheme(cs);
4473 af.viewport.getResidueShading().setThreshold(view.getPidThreshold(),
4474 view.getIgnoreGapsinConsensus());
4475 af.viewport.getResidueShading()
4476 .setConsensus(af.viewport.getSequenceConsensusHash());
4477 af.viewport.setColourAppliesToAllGroups(false);
4479 if (view.getConservationSelected() && cs != null)
4481 af.viewport.getResidueShading()
4482 .setConservationInc(view.getConsThreshold());
4485 af.changeColour(cs);
4487 af.viewport.setColourAppliesToAllGroups(true);
4489 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4491 if (view.hasCentreColumnLabels())
4493 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4495 if (view.hasIgnoreGapsinConsensus())
4497 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4500 if (view.hasFollowHighlight())
4502 af.viewport.setFollowHighlight(view.getFollowHighlight());
4504 if (view.hasFollowSelection())
4506 af.viewport.followSelection = view.getFollowSelection();
4508 if (view.hasShowConsensusHistogram())
4511 .setShowConsensusHistogram(view.getShowConsensusHistogram());
4515 af.viewport.setShowConsensusHistogram(true);
4517 if (view.hasShowSequenceLogo())
4519 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4523 af.viewport.setShowSequenceLogo(false);
4525 if (view.hasNormaliseSequenceLogo())
4527 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4529 if (view.hasShowDbRefTooltip())
4531 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4533 if (view.hasShowNPfeatureTooltip())
4535 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4537 if (view.hasShowGroupConsensus())
4539 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4543 af.viewport.setShowGroupConsensus(false);
4545 if (view.hasShowGroupConservation())
4547 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4551 af.viewport.setShowGroupConservation(false);
4554 // recover featre settings
4555 if (jms.getFeatureSettings() != null)
4557 FeaturesDisplayed fdi;
4558 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4559 String[] renderOrder = new String[jms.getFeatureSettings()
4560 .getSettingCount()];
4561 Map<String, FeatureColourI> featureColours = new Hashtable<>();
4562 Map<String, Float> featureOrder = new Hashtable<>();
4564 for (int fs = 0; fs < jms.getFeatureSettings()
4565 .getSettingCount(); fs++)
4567 Setting setting = jms.getFeatureSettings().getSetting(fs);
4568 if (setting.hasMincolour())
4570 FeatureColourI gc = setting.hasMin()
4571 ? new FeatureColour(new Color(setting.getMincolour()),
4572 new Color(setting.getColour()), setting.getMin(),
4574 : new FeatureColour(new Color(setting.getMincolour()),
4575 new Color(setting.getColour()), 0, 1);
4576 if (setting.hasThreshold())
4578 gc.setThreshold(setting.getThreshold());
4579 int threshstate = setting.getThreshstate();
4580 // -1 = None, 0 = Below, 1 = Above threshold
4581 if (threshstate == 0)
4583 gc.setBelowThreshold(true);
4585 else if (threshstate == 1)
4587 gc.setAboveThreshold(true);
4590 gc.setAutoScaled(true); // default
4591 if (setting.hasAutoScale())
4593 gc.setAutoScaled(setting.getAutoScale());
4595 if (setting.hasColourByLabel())
4597 gc.setColourByLabel(setting.getColourByLabel());
4599 // and put in the feature colour table.
4600 featureColours.put(setting.getType(), gc);
4604 featureColours.put(setting.getType(),
4605 new FeatureColour(new Color(setting.getColour())));
4607 renderOrder[fs] = setting.getType();
4608 if (setting.hasOrder())
4610 featureOrder.put(setting.getType(), setting.getOrder());
4614 featureOrder.put(setting.getType(), new Float(
4615 fs / jms.getFeatureSettings().getSettingCount()));
4617 if (setting.getDisplay())
4619 fdi.setVisible(setting.getType());
4622 Map<String, Boolean> fgtable = new Hashtable<>();
4623 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4625 Group grp = jms.getFeatureSettings().getGroup(gs);
4626 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4628 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4629 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4630 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4631 FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4632 fgtable, featureColours, 1.0f, featureOrder);
4633 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4634 .transferSettings(frs);
4638 if (view.getHiddenColumnsCount() > 0)
4640 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4642 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(),
4643 view.getHiddenColumns(c).getEnd() // +1
4647 if (view.getCalcIdParam() != null)
4649 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4651 if (calcIdParam != null)
4653 if (recoverCalcIdParam(calcIdParam, af.viewport))
4658 warn("Couldn't recover parameters for "
4659 + calcIdParam.getCalcId());
4664 af.setMenusFromViewport(af.viewport);
4665 af.setTitle(view.getTitle());
4666 // TODO: we don't need to do this if the viewport is aready visible.
4668 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4669 * has a 'cdna/protein complement' view, in which case save it in order to
4670 * populate a SplitFrame once all views have been read in.
4672 String complementaryViewId = view.getComplementId();
4673 if (complementaryViewId == null)
4675 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4677 // recompute any autoannotation
4678 af.alignPanel.updateAnnotation(false, true);
4679 reorderAutoannotation(af, al, autoAlan);
4680 af.alignPanel.alignmentChanged();
4684 splitFrameCandidates.put(view, af);
4690 * Reads saved data to restore Colour by Annotation settings
4692 * @param viewAnnColour
4696 * @param checkGroupAnnColour
4699 private ColourSchemeI constructAnnotationColour(
4700 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4701 JalviewModelSequence jms, boolean checkGroupAnnColour)
4703 boolean propagateAnnColour = false;
4704 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4705 if (checkGroupAnnColour && al.getGroups() != null
4706 && al.getGroups().size() > 0)
4708 // pre 2.8.1 behaviour
4709 // check to see if we should transfer annotation colours
4710 propagateAnnColour = true;
4711 for (SequenceGroup sg : al.getGroups())
4713 if (sg.getColourScheme() instanceof AnnotationColourGradient)
4715 propagateAnnColour = false;
4721 * 2.10.2- : saved annotationId is AlignmentAnnotation.annotationId
4723 String annotationId = viewAnnColour.getAnnotation();
4724 AlignmentAnnotation matchedAnnotation = annotationIds.get(annotationId);
4727 * pre 2.10.2: saved annotationId is AlignmentAnnotation.label
4729 if (matchedAnnotation == null
4730 && annAlignment.getAlignmentAnnotation() != null)
4732 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4735 .equals(annAlignment.getAlignmentAnnotation()[i].label))
4737 matchedAnnotation = annAlignment.getAlignmentAnnotation()[i];
4742 if (matchedAnnotation == null)
4744 System.err.println("Failed to match annotation colour scheme for "
4748 if (matchedAnnotation.getThreshold() == null)
4750 matchedAnnotation.setThreshold(new GraphLine(
4751 viewAnnColour.getThreshold(), "Threshold", Color.black));
4754 AnnotationColourGradient cs = null;
4755 if (viewAnnColour.getColourScheme().equals("None"))
4757 cs = new AnnotationColourGradient(matchedAnnotation,
4758 new Color(viewAnnColour.getMinColour()),
4759 new Color(viewAnnColour.getMaxColour()),
4760 viewAnnColour.getAboveThreshold());
4762 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4764 cs = new AnnotationColourGradient(matchedAnnotation,
4765 getUserColourScheme(jms, viewAnnColour.getColourScheme()),
4766 viewAnnColour.getAboveThreshold());
4770 cs = new AnnotationColourGradient(matchedAnnotation,
4771 ColourSchemeProperty.getColourScheme(al,
4772 viewAnnColour.getColourScheme()),
4773 viewAnnColour.getAboveThreshold());
4776 boolean perSequenceOnly = viewAnnColour.isPerSequence();
4777 boolean useOriginalColours = viewAnnColour.isPredefinedColours();
4778 cs.setSeqAssociated(perSequenceOnly);
4779 cs.setPredefinedColours(useOriginalColours);
4781 if (propagateAnnColour && al.getGroups() != null)
4783 // Also use these settings for all the groups
4784 for (int g = 0; g < al.getGroups().size(); g++)
4786 SequenceGroup sg = al.getGroups().get(g);
4787 if (sg.getGroupColourScheme() == null)
4792 AnnotationColourGradient groupScheme = new AnnotationColourGradient(
4793 matchedAnnotation, sg.getColourScheme(),
4794 viewAnnColour.getAboveThreshold());
4795 sg.setColourScheme(groupScheme);
4796 groupScheme.setSeqAssociated(perSequenceOnly);
4797 groupScheme.setPredefinedColours(useOriginalColours);
4803 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4804 List<JvAnnotRow> autoAlan)
4806 // copy over visualization settings for autocalculated annotation in the
4808 if (al.getAlignmentAnnotation() != null)
4811 * Kludge for magic autoannotation names (see JAL-811)
4813 String[] magicNames = new String[] { "Consensus", "Quality",
4815 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4816 Hashtable<String, JvAnnotRow> visan = new Hashtable<>();
4817 for (String nm : magicNames)
4819 visan.put(nm, nullAnnot);
4821 for (JvAnnotRow auan : autoAlan)
4823 visan.put(auan.template.label
4824 + (auan.template.getCalcId() == null ? ""
4825 : "\t" + auan.template.getCalcId()),
4828 int hSize = al.getAlignmentAnnotation().length;
4829 List<JvAnnotRow> reorder = new ArrayList<>();
4830 // work through any autoCalculated annotation already on the view
4831 // removing it if it should be placed in a different location on the
4832 // annotation panel.
4833 List<String> remains = new ArrayList<>(visan.keySet());
4834 for (int h = 0; h < hSize; h++)
4836 jalview.datamodel.AlignmentAnnotation jalan = al
4837 .getAlignmentAnnotation()[h];
4838 if (jalan.autoCalculated)
4841 JvAnnotRow valan = visan.get(k = jalan.label);
4842 if (jalan.getCalcId() != null)
4844 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4849 // delete the auto calculated row from the alignment
4850 al.deleteAnnotation(jalan, false);
4854 if (valan != nullAnnot)
4856 if (jalan != valan.template)
4858 // newly created autoannotation row instance
4859 // so keep a reference to the visible annotation row
4860 // and copy over all relevant attributes
4861 if (valan.template.graphHeight >= 0)
4864 jalan.graphHeight = valan.template.graphHeight;
4866 jalan.visible = valan.template.visible;
4868 reorder.add(new JvAnnotRow(valan.order, jalan));
4873 // Add any (possibly stale) autocalculated rows that were not appended to
4874 // the view during construction
4875 for (String other : remains)
4877 JvAnnotRow othera = visan.get(other);
4878 if (othera != nullAnnot && othera.template.getCalcId() != null
4879 && othera.template.getCalcId().length() > 0)
4881 reorder.add(othera);
4884 // now put the automatic annotation in its correct place
4885 int s = 0, srt[] = new int[reorder.size()];
4886 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4887 for (JvAnnotRow jvar : reorder)
4890 srt[s++] = jvar.order;
4893 jalview.util.QuickSort.sort(srt, rws);
4894 // and re-insert the annotation at its correct position
4895 for (JvAnnotRow jvar : rws)
4897 al.addAnnotation(jvar.template, jvar.order);
4899 af.alignPanel.adjustAnnotationHeight();
4903 Hashtable skipList = null;
4906 * TODO remove this method
4909 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4910 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4911 * throw new Error("Implementation Error. No skipList defined for this
4912 * Jalview2XML instance."); } return (AlignFrame)
4913 * skipList.get(view.getSequenceSetId()); }
4917 * Check if the Jalview view contained in object should be skipped or not.
4920 * @return true if view's sequenceSetId is a key in skipList
4922 private boolean skipViewport(JalviewModel object)
4924 if (skipList == null)
4929 if (skipList.containsKey(
4930 id = object.getJalviewModelSequence().getViewport()[0]
4931 .getSequenceSetId()))
4933 if (Cache.log != null && Cache.log.isDebugEnabled())
4935 Cache.log.debug("Skipping seuqence set id " + id);
4942 public void addToSkipList(AlignFrame af)
4944 if (skipList == null)
4946 skipList = new Hashtable();
4948 skipList.put(af.getViewport().getSequenceSetId(), af);
4951 public void clearSkipList()
4953 if (skipList != null)
4960 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4961 boolean ignoreUnrefed)
4963 jalview.datamodel.AlignmentI ds = getDatasetFor(
4964 vamsasSet.getDatasetId());
4965 Vector dseqs = null;
4968 // create a list of new dataset sequences
4969 dseqs = new Vector();
4971 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4973 Sequence vamsasSeq = vamsasSet.getSequence(i);
4974 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4976 // create a new dataset
4979 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4980 dseqs.copyInto(dsseqs);
4981 ds = new jalview.datamodel.Alignment(dsseqs);
4982 debug("Created new dataset " + vamsasSet.getDatasetId()
4983 + " for alignment " + System.identityHashCode(al));
4984 addDatasetRef(vamsasSet.getDatasetId(), ds);
4986 // set the dataset for the newly imported alignment.
4987 if (al.getDataset() == null && !ignoreUnrefed)
4996 * sequence definition to create/merge dataset sequence for
5000 * vector to add new dataset sequence to
5001 * @param ignoreUnrefed
5002 * - when true, don't create new sequences from vamsasSeq if it's id
5003 * doesn't already have an asssociated Jalview sequence.
5005 * - used to reorder the sequence in the alignment according to the
5006 * vamsasSeq array ordering, to preserve ordering of dataset
5008 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5009 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5011 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5013 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5014 boolean reorder = false;
5015 SequenceI dsq = null;
5016 if (sq != null && sq.getDatasetSequence() != null)
5018 dsq = sq.getDatasetSequence();
5024 if (sq == null && ignoreUnrefed)
5028 String sqid = vamsasSeq.getDsseqid();
5031 // need to create or add a new dataset sequence reference to this sequence
5034 dsq = seqRefIds.get(sqid);
5039 // make a new dataset sequence
5040 dsq = sq.createDatasetSequence();
5043 // make up a new dataset reference for this sequence
5044 sqid = seqHash(dsq);
5046 dsq.setVamsasId(uniqueSetSuffix + sqid);
5047 seqRefIds.put(sqid, dsq);
5052 dseqs.addElement(dsq);
5057 ds.addSequence(dsq);
5063 { // make this dataset sequence sq's dataset sequence
5064 sq.setDatasetSequence(dsq);
5065 // and update the current dataset alignment
5070 if (!dseqs.contains(dsq))
5077 if (ds.findIndex(dsq) < 0)
5079 ds.addSequence(dsq);
5086 // TODO: refactor this as a merge dataset sequence function
5087 // now check that sq (the dataset sequence) sequence really is the union of
5088 // all references to it
5089 // boolean pre = sq.getStart() < dsq.getStart();
5090 // boolean post = sq.getEnd() > dsq.getEnd();
5094 // StringBuffer sb = new StringBuffer();
5095 String newres = jalview.analysis.AlignSeq.extractGaps(
5096 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5097 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5098 && newres.length() > dsq.getLength())
5100 // Update with the longer sequence.
5104 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5105 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5106 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5107 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5109 dsq.setSequence(newres);
5111 // TODO: merges will never happen if we 'know' we have the real dataset
5112 // sequence - this should be detected when id==dssid
5114 "DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5115 // + (pre ? "prepended" : "") + " "
5116 // + (post ? "appended" : ""));
5121 // sequence refs are identical. We may need to update the existing dataset
5122 // alignment with this one, though.
5123 if (ds != null && dseqs == null)
5125 int opos = ds.findIndex(dsq);
5126 SequenceI tseq = null;
5127 if (opos != -1 && vseqpos != opos)
5129 // remove from old position
5130 ds.deleteSequence(dsq);
5132 if (vseqpos < ds.getHeight())
5134 if (vseqpos != opos)
5136 // save sequence at destination position
5137 tseq = ds.getSequenceAt(vseqpos);
5138 ds.replaceSequenceAt(vseqpos, dsq);
5139 ds.addSequence(tseq);
5144 ds.addSequence(dsq);
5151 * TODO use AlignmentI here and in related methods - needs
5152 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5154 Hashtable<String, AlignmentI> datasetIds = null;
5156 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5158 private AlignmentI getDatasetFor(String datasetId)
5160 if (datasetIds == null)
5162 datasetIds = new Hashtable<>();
5165 if (datasetIds.containsKey(datasetId))
5167 return datasetIds.get(datasetId);
5172 private void addDatasetRef(String datasetId, AlignmentI dataset)
5174 if (datasetIds == null)
5176 datasetIds = new Hashtable<>();
5178 datasetIds.put(datasetId, dataset);
5182 * make a new dataset ID for this jalview dataset alignment
5187 private String getDatasetIdRef(AlignmentI dataset)
5189 if (dataset.getDataset() != null)
5191 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5193 String datasetId = makeHashCode(dataset, null);
5194 if (datasetId == null)
5196 // make a new datasetId and record it
5197 if (dataset2Ids == null)
5199 dataset2Ids = new IdentityHashMap<>();
5203 datasetId = dataset2Ids.get(dataset);
5205 if (datasetId == null)
5207 datasetId = "ds" + dataset2Ids.size() + 1;
5208 dataset2Ids.put(dataset, datasetId);
5214 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5216 for (int d = 0; d < sequence.getDBRefCount(); d++)
5218 DBRef dr = sequence.getDBRef(d);
5219 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5220 sequence.getDBRef(d).getSource(),
5221 sequence.getDBRef(d).getVersion(),
5222 sequence.getDBRef(d).getAccessionId());
5223 if (dr.getMapping() != null)
5225 entry.setMap(addMapping(dr.getMapping()));
5227 datasetSequence.addDBRef(entry);
5231 private jalview.datamodel.Mapping addMapping(Mapping m)
5233 SequenceI dsto = null;
5234 // Mapping m = dr.getMapping();
5235 int fr[] = new int[m.getMapListFromCount() * 2];
5236 Enumeration f = m.enumerateMapListFrom();
5237 for (int _i = 0; f.hasMoreElements(); _i += 2)
5239 MapListFrom mf = (MapListFrom) f.nextElement();
5240 fr[_i] = mf.getStart();
5241 fr[_i + 1] = mf.getEnd();
5243 int fto[] = new int[m.getMapListToCount() * 2];
5244 f = m.enumerateMapListTo();
5245 for (int _i = 0; f.hasMoreElements(); _i += 2)
5247 MapListTo mf = (MapListTo) f.nextElement();
5248 fto[_i] = mf.getStart();
5249 fto[_i + 1] = mf.getEnd();
5251 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto, fr,
5252 fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5253 if (m.getMappingChoice() != null)
5255 MappingChoice mc = m.getMappingChoice();
5256 if (mc.getDseqFor() != null)
5258 String dsfor = "" + mc.getDseqFor();
5259 if (seqRefIds.containsKey(dsfor))
5264 jmap.setTo(seqRefIds.get(dsfor));
5268 frefedSequence.add(newMappingRef(dsfor, jmap));
5274 * local sequence definition
5276 Sequence ms = mc.getSequence();
5277 SequenceI djs = null;
5278 String sqid = ms.getDsseqid();
5279 if (sqid != null && sqid.length() > 0)
5282 * recover dataset sequence
5284 djs = seqRefIds.get(sqid);
5289 "Warning - making up dataset sequence id for DbRef sequence map reference");
5290 sqid = ((Object) ms).toString(); // make up a new hascode for
5291 // undefined dataset sequence hash
5292 // (unlikely to happen)
5298 * make a new dataset sequence and add it to refIds hash
5300 djs = new jalview.datamodel.Sequence(ms.getName(),
5302 djs.setStart(jmap.getMap().getToLowest());
5303 djs.setEnd(jmap.getMap().getToHighest());
5304 djs.setVamsasId(uniqueSetSuffix + sqid);
5306 incompleteSeqs.put(sqid, djs);
5307 seqRefIds.put(sqid, djs);
5310 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5320 * Provides a 'copy' of an alignment view (on action New View) by 'saving' the
5321 * view as XML (but not to file), and then reloading it
5326 public AlignmentPanel copyAlignPanel(AlignmentPanel ap)
5329 JalviewModel jm = saveState(ap, null, null, null);
5331 uniqueSetSuffix = "";
5332 jm.getJalviewModelSequence().getViewport(0).setId(null);
5333 // we don't overwrite the view we just copied
5335 if (this.frefedSequence == null)
5337 frefedSequence = new Vector<SeqFref>();
5340 viewportsAdded.clear();
5342 AlignFrame af = loadFromObject(jm, null, false, null);
5343 af.alignPanels.clear();
5344 af.closeMenuItem_actionPerformed(true);
5347 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5348 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5349 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5350 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5351 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5354 return af.alignPanel;
5357 private Hashtable jvids2vobj;
5359 private void warn(String msg)
5364 private void warn(String msg, Exception e)
5366 if (Cache.log != null)
5370 Cache.log.warn(msg, e);
5374 Cache.log.warn(msg);
5379 System.err.println("Warning: " + msg);
5382 e.printStackTrace();
5387 private void debug(String string)
5389 debug(string, null);
5392 private void debug(String msg, Exception e)
5394 if (Cache.log != null)
5398 Cache.log.debug(msg, e);
5402 Cache.log.debug(msg);
5407 System.err.println("Warning: " + msg);
5410 e.printStackTrace();
5416 * set the object to ID mapping tables used to write/recover objects and XML
5417 * ID strings for the jalview project. If external tables are provided then
5418 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5419 * object goes out of scope. - also populates the datasetIds hashtable with
5420 * alignment objects containing dataset sequences
5423 * Map from ID strings to jalview datamodel
5425 * Map from jalview datamodel to ID strings
5429 public void setObjectMappingTables(Hashtable vobj2jv,
5430 IdentityHashMap jv2vobj)
5432 this.jv2vobj = jv2vobj;
5433 this.vobj2jv = vobj2jv;
5434 Iterator ds = jv2vobj.keySet().iterator();
5436 while (ds.hasNext())
5438 Object jvobj = ds.next();
5439 id = jv2vobj.get(jvobj).toString();
5440 if (jvobj instanceof jalview.datamodel.Alignment)
5442 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5444 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5447 else if (jvobj instanceof jalview.datamodel.Sequence)
5449 // register sequence object so the XML parser can recover it.
5450 if (seqRefIds == null)
5452 seqRefIds = new HashMap<>();
5454 if (seqsToIds == null)
5456 seqsToIds = new IdentityHashMap<>();
5458 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5459 seqsToIds.put((SequenceI) jvobj, id);
5461 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5464 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5465 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5466 if (jvann.annotationId == null)
5468 jvann.annotationId = anid;
5470 if (!jvann.annotationId.equals(anid))
5472 // TODO verify that this is the correct behaviour
5473 this.warn("Overriding Annotation ID for " + anid
5474 + " from different id : " + jvann.annotationId);
5475 jvann.annotationId = anid;
5478 else if (jvobj instanceof String)
5480 if (jvids2vobj == null)
5482 jvids2vobj = new Hashtable();
5483 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5488 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5494 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5495 * objects created from the project archive. If string is null (default for
5496 * construction) then suffix will be set automatically.
5500 public void setUniqueSetSuffix(String string)
5502 uniqueSetSuffix = string;
5507 * uses skipList2 as the skipList for skipping views on sequence sets
5508 * associated with keys in the skipList
5512 public void setSkipList(Hashtable skipList2)
5514 skipList = skipList2;
5518 * Reads the jar entry of given name and returns its contents, or null if the
5519 * entry is not found.
5522 * @param jarEntryName
5525 protected String readJarEntry(jarInputStreamProvider jprovider,
5526 String jarEntryName)
5528 String result = null;
5529 BufferedReader in = null;
5534 * Reopen the jar input stream and traverse its entries to find a matching
5537 JarInputStream jin = jprovider.getJarInputStream();
5538 JarEntry entry = null;
5541 entry = jin.getNextJarEntry();
5542 } while (entry != null && !entry.getName().equals(jarEntryName));
5546 StringBuilder out = new StringBuilder(256);
5547 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5550 while ((data = in.readLine()) != null)
5554 result = out.toString();
5558 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5560 } catch (Exception ex)
5562 ex.printStackTrace();
5570 } catch (IOException e)
5581 * Returns an incrementing counter (0, 1, 2...)
5585 private synchronized int nextCounter()