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.SequenceGroup;
36 import jalview.datamodel.SequenceI;
37 import jalview.datamodel.StructureViewerModel;
38 import jalview.datamodel.StructureViewerModel.StructureData;
39 import jalview.ext.varna.RnaModel;
40 import jalview.gui.StructureViewer.ViewerType;
41 import jalview.io.DataSourceType;
42 import jalview.io.FileFormat;
43 import jalview.renderer.ResidueShaderI;
44 import jalview.schemabinding.version2.AlcodMap;
45 import jalview.schemabinding.version2.AlcodonFrame;
46 import jalview.schemabinding.version2.Annotation;
47 import jalview.schemabinding.version2.AnnotationColours;
48 import jalview.schemabinding.version2.AnnotationElement;
49 import jalview.schemabinding.version2.CalcIdParam;
50 import jalview.schemabinding.version2.DBRef;
51 import jalview.schemabinding.version2.Features;
52 import jalview.schemabinding.version2.Group;
53 import jalview.schemabinding.version2.HiddenColumns;
54 import jalview.schemabinding.version2.JGroup;
55 import jalview.schemabinding.version2.JSeq;
56 import jalview.schemabinding.version2.JalviewModel;
57 import jalview.schemabinding.version2.JalviewModelSequence;
58 import jalview.schemabinding.version2.MapListFrom;
59 import jalview.schemabinding.version2.MapListTo;
60 import jalview.schemabinding.version2.Mapping;
61 import jalview.schemabinding.version2.MappingChoice;
62 import jalview.schemabinding.version2.OtherData;
63 import jalview.schemabinding.version2.PdbentryItem;
64 import jalview.schemabinding.version2.Pdbids;
65 import jalview.schemabinding.version2.Property;
66 import jalview.schemabinding.version2.RnaViewer;
67 import jalview.schemabinding.version2.SecondaryStructure;
68 import jalview.schemabinding.version2.Sequence;
69 import jalview.schemabinding.version2.SequenceSet;
70 import jalview.schemabinding.version2.SequenceSetProperties;
71 import jalview.schemabinding.version2.Setting;
72 import jalview.schemabinding.version2.StructureState;
73 import jalview.schemabinding.version2.ThresholdLine;
74 import jalview.schemabinding.version2.Tree;
75 import jalview.schemabinding.version2.UserColours;
76 import jalview.schemabinding.version2.Viewport;
77 import jalview.schemes.AnnotationColourGradient;
78 import jalview.schemes.ColourSchemeI;
79 import jalview.schemes.ColourSchemeProperty;
80 import jalview.schemes.FeatureColour;
81 import jalview.schemes.ResidueProperties;
82 import jalview.schemes.UserColourScheme;
83 import jalview.structure.StructureSelectionManager;
84 import jalview.structures.models.AAStructureBindingModel;
85 import jalview.util.MessageManager;
86 import jalview.util.Platform;
87 import jalview.util.StringUtils;
88 import jalview.util.jarInputStreamProvider;
89 import jalview.viewmodel.AlignmentViewport;
90 import jalview.viewmodel.ViewportRanges;
91 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
92 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
93 import jalview.ws.jws2.Jws2Discoverer;
94 import jalview.ws.jws2.dm.AAConSettings;
95 import jalview.ws.jws2.jabaws2.Jws2Instance;
96 import jalview.ws.params.ArgumentI;
97 import jalview.ws.params.AutoCalcSetting;
98 import jalview.ws.params.WsParamSetI;
100 import java.awt.Color;
101 import java.awt.Rectangle;
102 import java.io.BufferedReader;
103 import java.io.DataInputStream;
104 import java.io.DataOutputStream;
106 import java.io.FileInputStream;
107 import java.io.FileOutputStream;
108 import java.io.IOException;
109 import java.io.InputStreamReader;
110 import java.io.OutputStreamWriter;
111 import java.io.PrintWriter;
112 import java.lang.reflect.InvocationTargetException;
113 import java.net.MalformedURLException;
115 import java.util.ArrayList;
116 import java.util.Arrays;
117 import java.util.Enumeration;
118 import java.util.HashMap;
119 import java.util.HashSet;
120 import java.util.Hashtable;
121 import java.util.IdentityHashMap;
122 import java.util.Iterator;
123 import java.util.LinkedHashMap;
124 import java.util.List;
125 import java.util.Map;
126 import java.util.Map.Entry;
127 import java.util.Set;
128 import java.util.Vector;
129 import java.util.jar.JarEntry;
130 import java.util.jar.JarInputStream;
131 import java.util.jar.JarOutputStream;
133 import javax.swing.JInternalFrame;
134 import javax.swing.SwingUtilities;
136 import org.exolab.castor.xml.Marshaller;
137 import org.exolab.castor.xml.Unmarshaller;
140 * Write out the current jalview desktop state as a Jalview XML stream.
142 * Note: the vamsas objects referred to here are primitive versions of the
143 * VAMSAS project schema elements - they are not the same and most likely never
147 * @version $Revision: 1.134 $
149 public class Jalview2XML
151 private static final String VIEWER_PREFIX = "viewer_";
153 private static final String RNA_PREFIX = "rna_";
155 private static final String UTF_8 = "UTF-8";
157 // use this with nextCounter() to make unique names for entities
158 private int counter = 0;
161 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
162 * of sequence objects are created.
164 IdentityHashMap<SequenceI, String> seqsToIds = null;
167 * jalview XML Sequence ID to jalview sequence object reference (both dataset
168 * and alignment sequences. Populated as XML reps of sequence objects are
171 Map<String, SequenceI> seqRefIds = null;
173 Map<String, SequenceI> incompleteSeqs = null;
175 List<SeqFref> frefedSequence = null;
177 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
180 * Map of reconstructed AlignFrame objects that appear to have come from
181 * SplitFrame objects (have a dna/protein complement view).
183 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<>();
186 * Map from displayed rna structure models to their saved session state jar
189 private Map<RnaModel, String> rnaSessions = new HashMap<>();
192 * create/return unique hash string for sq
195 * @return new or existing unique string for sq
197 String seqHash(SequenceI sq)
199 if (seqsToIds == null)
203 if (seqsToIds.containsKey(sq))
205 return seqsToIds.get(sq);
209 // create sequential key
210 String key = "sq" + (seqsToIds.size() + 1);
211 key = makeHashCode(sq, key); // check we don't have an external reference
213 seqsToIds.put(sq, key);
222 if (seqRefIds != null)
226 if (seqsToIds != null)
230 if (incompleteSeqs != null)
232 incompleteSeqs.clear();
240 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
241 // seqRefIds = new Hashtable();
242 // seqsToIds = new IdentityHashMap();
248 if (seqsToIds == null)
250 seqsToIds = new IdentityHashMap<>();
252 if (seqRefIds == null)
254 seqRefIds = new HashMap<>();
256 if (incompleteSeqs == null)
258 incompleteSeqs = new HashMap<>();
260 if (frefedSequence == null)
262 frefedSequence = new ArrayList<>();
270 public Jalview2XML(boolean raiseGUI)
272 this.raiseGUI = raiseGUI;
276 * base class for resolving forward references to sequences by their ID
281 abstract class SeqFref
287 public SeqFref(String _sref, String type)
293 public String getSref()
298 public SequenceI getSrefSeq()
300 return seqRefIds.get(sref);
303 public boolean isResolvable()
305 return seqRefIds.get(sref) != null;
308 public SequenceI getSrefDatasetSeq()
310 SequenceI sq = seqRefIds.get(sref);
313 while (sq.getDatasetSequence() != null)
315 sq = sq.getDatasetSequence();
322 * @return true if the forward reference was fully resolved
324 abstract boolean resolve();
327 public String toString()
329 return type + " reference to " + sref;
334 * create forward reference for a mapping
340 public SeqFref newMappingRef(final String sref,
341 final jalview.datamodel.Mapping _jmap)
343 SeqFref fref = new SeqFref(sref, "Mapping")
345 public jalview.datamodel.Mapping jmap = _jmap;
350 SequenceI seq = getSrefDatasetSeq();
362 public SeqFref newAlcodMapRef(final String sref,
363 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
366 SeqFref fref = new SeqFref(sref, "Codon Frame")
368 AlignedCodonFrame cf = _cf;
370 public jalview.datamodel.Mapping mp = _jmap;
373 public boolean isResolvable()
375 return super.isResolvable() && mp.getTo() != null;
381 SequenceI seq = getSrefDatasetSeq();
386 cf.addMap(seq, mp.getTo(), mp.getMap());
393 public void resolveFrefedSequences()
395 Iterator<SeqFref> nextFref = frefedSequence.iterator();
396 int toresolve = frefedSequence.size();
397 int unresolved = 0, failedtoresolve = 0;
398 while (nextFref.hasNext())
400 SeqFref ref = nextFref.next();
401 if (ref.isResolvable())
413 } catch (Exception x)
416 .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
429 System.err.println("Jalview Project Import: There were " + unresolved
430 + " forward references left unresolved on the stack.");
432 if (failedtoresolve > 0)
434 System.err.println("SERIOUS! " + failedtoresolve
435 + " resolvable forward references failed to resolve.");
437 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
439 System.err.println("Jalview Project Import: There are "
440 + incompleteSeqs.size()
441 + " sequences which may have incomplete metadata.");
442 if (incompleteSeqs.size() < 10)
444 for (SequenceI s : incompleteSeqs.values())
446 System.err.println(s.toString());
452 .println("Too many to report. Skipping output of incomplete sequences.");
458 * This maintains a map of viewports, the key being the seqSetId. Important to
459 * set historyItem and redoList for multiple views
461 Map<String, AlignViewport> viewportsAdded = new HashMap<>();
463 Map<String, AlignmentAnnotation> annotationIds = new HashMap<>();
465 String uniqueSetSuffix = "";
468 * List of pdbfiles added to Jar
470 List<String> pdbfiles = null;
472 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
473 public void saveState(File statefile)
475 FileOutputStream fos = null;
478 fos = new FileOutputStream(statefile);
479 JarOutputStream jout = new JarOutputStream(fos);
482 } catch (Exception e)
484 // TODO: inform user of the problem - they need to know if their data was
486 if (errorMessage == null)
488 errorMessage = "Couldn't write Jalview Archive to output file '"
489 + statefile + "' - See console error log for details";
493 errorMessage += "(output file was '" + statefile + "')";
503 } catch (IOException e)
513 * Writes a jalview project archive to the given Jar output stream.
517 public void saveState(JarOutputStream jout)
519 AlignFrame[] frames = Desktop.getAlignFrames();
525 saveAllFrames(Arrays.asList(frames), jout);
529 * core method for storing state for a set of AlignFrames.
532 * - frames involving all data to be exported (including containing
535 * - project output stream
537 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
539 Hashtable<String, AlignFrame> dsses = new Hashtable<>();
542 * ensure cached data is clear before starting
544 // todo tidy up seqRefIds, seqsToIds initialisation / reset
546 splitFrameCandidates.clear();
551 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
552 // //////////////////////////////////////////////////
554 List<String> shortNames = new ArrayList<>();
555 List<String> viewIds = new ArrayList<>();
558 for (int i = frames.size() - 1; i > -1; i--)
560 AlignFrame af = frames.get(i);
564 .containsKey(af.getViewport().getSequenceSetId()))
569 String shortName = makeFilename(af, shortNames);
571 int ap, apSize = af.alignPanels.size();
573 for (ap = 0; ap < apSize; ap++)
575 AlignmentPanel apanel = af.alignPanels.get(ap);
576 String fileName = apSize == 1 ? shortName : ap + shortName;
577 if (!fileName.endsWith(".xml"))
579 fileName = fileName + ".xml";
582 saveState(apanel, fileName, jout, viewIds);
584 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
586 if (!dsses.containsKey(dssid))
588 dsses.put(dssid, af);
593 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
599 } catch (Exception foo)
604 } catch (Exception ex)
606 // TODO: inform user of the problem - they need to know if their data was
608 if (errorMessage == null)
610 errorMessage = "Couldn't write Jalview Archive - see error output for details";
612 ex.printStackTrace();
617 * Generates a distinct file name, based on the title of the AlignFrame, by
618 * appending _n for increasing n until an unused name is generated. The new
619 * name (without its extension) is added to the list.
623 * @return the generated name, with .xml extension
625 protected String makeFilename(AlignFrame af, List<String> namesUsed)
627 String shortName = af.getTitle();
629 if (shortName.indexOf(File.separatorChar) > -1)
631 shortName = shortName.substring(shortName
632 .lastIndexOf(File.separatorChar) + 1);
637 while (namesUsed.contains(shortName))
639 if (shortName.endsWith("_" + (count - 1)))
641 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
644 shortName = shortName.concat("_" + count);
648 namesUsed.add(shortName);
650 if (!shortName.endsWith(".xml"))
652 shortName = shortName + ".xml";
657 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
658 public boolean saveAlignment(AlignFrame af, String jarFile,
663 FileOutputStream fos = new FileOutputStream(jarFile);
664 JarOutputStream jout = new JarOutputStream(fos);
665 List<AlignFrame> frames = new ArrayList<>();
667 // resolve splitframes
668 if (af.getViewport().getCodingComplement() != null)
670 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
676 saveAllFrames(frames, jout);
680 } catch (Exception foo)
686 } catch (Exception ex)
688 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
689 ex.printStackTrace();
694 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
695 String fileName, JarOutputStream jout)
698 for (String dssids : dsses.keySet())
700 AlignFrame _af = dsses.get(dssids);
701 String jfileName = fileName + " Dataset for " + _af.getTitle();
702 if (!jfileName.endsWith(".xml"))
704 jfileName = jfileName + ".xml";
706 saveState(_af.alignPanel, jfileName, true, jout, null);
711 * create a JalviewModel from an alignment view and marshall it to a
715 * panel to create jalview model for
717 * name of alignment panel written to output stream
724 public JalviewModel saveState(AlignmentPanel ap, String fileName,
725 JarOutputStream jout, List<String> viewIds)
727 return saveState(ap, fileName, false, jout, viewIds);
731 * create a JalviewModel from an alignment view and marshall it to a
735 * panel to create jalview model for
737 * name of alignment panel written to output stream
739 * when true, only write the dataset for the alignment, not the data
740 * associated with the view.
746 public JalviewModel saveState(AlignmentPanel ap, String fileName,
747 boolean storeDS, JarOutputStream jout, List<String> viewIds)
751 viewIds = new ArrayList<>();
756 List<UserColourScheme> userColours = new ArrayList<>();
758 AlignViewport av = ap.av;
759 ViewportRanges vpRanges = av.getRanges();
761 JalviewModel object = new JalviewModel();
762 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
764 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
765 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
766 "Development Build"));
769 * rjal is full height alignment, jal is actual alignment with full metadata
770 * but excludes hidden sequences.
772 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
774 if (av.hasHiddenRows())
776 rjal = jal.getHiddenSequences().getFullAlignment();
779 SequenceSet vamsasSet = new SequenceSet();
781 JalviewModelSequence jms = new JalviewModelSequence();
783 vamsasSet.setGapChar(jal.getGapCharacter() + "");
785 if (jal.getDataset() != null)
787 // dataset id is the dataset's hashcode
788 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
791 // switch jal and the dataset
792 jal = jal.getDataset();
796 if (jal.getProperties() != null)
798 Enumeration en = jal.getProperties().keys();
799 while (en.hasMoreElements())
801 String key = en.nextElement().toString();
802 SequenceSetProperties ssp = new SequenceSetProperties();
804 ssp.setValue(jal.getProperties().get(key).toString());
805 vamsasSet.addSequenceSetProperties(ssp);
810 Set<String> calcIdSet = new HashSet<>();
811 // record the set of vamsas sequence XML POJO we create.
812 HashMap<String, Sequence> vamsasSetIds = new HashMap<>();
814 for (final SequenceI jds : rjal.getSequences())
816 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
817 : jds.getDatasetSequence();
818 String id = seqHash(jds);
819 if (vamsasSetIds.get(id) == null)
821 if (seqRefIds.get(id) != null && !storeDS)
823 // This happens for two reasons: 1. multiple views are being
825 // 2. the hashCode has collided with another sequence's code. This
827 // HAPPEN! (PF00072.15.stk does this)
828 // JBPNote: Uncomment to debug writing out of files that do not read
829 // back in due to ArrayOutOfBoundExceptions.
830 // System.err.println("vamsasSeq backref: "+id+"");
831 // System.err.println(jds.getName()+"
832 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
833 // System.err.println("Hashcode: "+seqHash(jds));
834 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
835 // System.err.println(rsq.getName()+"
836 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
837 // System.err.println("Hashcode: "+seqHash(rsq));
841 vamsasSeq = createVamsasSequence(id, jds);
842 vamsasSet.addSequence(vamsasSeq);
843 vamsasSetIds.put(id, vamsasSeq);
844 seqRefIds.put(id, jds);
848 jseq.setStart(jds.getStart());
849 jseq.setEnd(jds.getEnd());
850 jseq.setColour(av.getSequenceColour(jds).getRGB());
852 jseq.setId(id); // jseq id should be a string not a number
855 // Store any sequences this sequence represents
856 if (av.hasHiddenRows())
858 // use rjal, contains the full height alignment
859 jseq.setHidden(av.getAlignment().getHiddenSequences()
862 if (av.isHiddenRepSequence(jds))
864 jalview.datamodel.SequenceI[] reps = av
865 .getRepresentedSequences(jds).getSequencesInOrder(rjal);
867 for (int h = 0; h < reps.length; h++)
871 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
876 // mark sequence as reference - if it is the reference for this view
879 jseq.setViewreference(jds == jal.getSeqrep());
883 // TODO: omit sequence features from each alignment view's XML dump if we
884 // are storing dataset
885 if (jds.getSequenceFeatures() != null)
887 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
889 while (index < sf.length)
891 Features features = new Features();
893 features.setBegin(sf[index].getBegin());
894 features.setEnd(sf[index].getEnd());
895 features.setDescription(sf[index].getDescription());
896 features.setType(sf[index].getType());
897 features.setFeatureGroup(sf[index].getFeatureGroup());
898 features.setScore(sf[index].getScore());
899 if (sf[index].links != null)
901 for (int l = 0; l < sf[index].links.size(); l++)
903 OtherData keyValue = new OtherData();
904 keyValue.setKey("LINK_" + l);
905 keyValue.setValue(sf[index].links.elementAt(l).toString());
906 features.addOtherData(keyValue);
909 if (sf[index].otherDetails != null)
912 Iterator<String> keys = sf[index].otherDetails.keySet()
914 while (keys.hasNext())
917 OtherData keyValue = new OtherData();
918 keyValue.setKey(key);
919 keyValue.setValue(sf[index].otherDetails.get(key).toString());
920 features.addOtherData(keyValue);
924 jseq.addFeatures(features);
929 if (jdatasq.getAllPDBEntries() != null)
931 Enumeration en = jdatasq.getAllPDBEntries().elements();
932 while (en.hasMoreElements())
934 Pdbids pdb = new Pdbids();
935 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
938 String pdbId = entry.getId();
940 pdb.setType(entry.getType());
943 * Store any structure views associated with this sequence. This
944 * section copes with duplicate entries in the project, so a dataset
945 * only view *should* be coped with sensibly.
947 // This must have been loaded, is it still visible?
948 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
949 String matchedFile = null;
950 for (int f = frames.length - 1; f > -1; f--)
952 if (frames[f] instanceof StructureViewerBase)
954 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
955 matchedFile = saveStructureState(ap, jds, pdb, entry,
956 viewIds, matchedFile, viewFrame);
958 * Only store each structure viewer's state once in the project
959 * jar. First time through only (storeDS==false)
961 String viewId = viewFrame.getViewId();
962 if (!storeDS && !viewIds.contains(viewId))
967 String viewerState = viewFrame.getStateInfo();
968 writeJarEntry(jout, getViewerJarEntryName(viewId),
969 viewerState.getBytes());
970 } catch (IOException e)
972 System.err.println("Error saving viewer state: "
979 if (matchedFile != null || entry.getFile() != null)
981 if (entry.getFile() != null)
984 matchedFile = entry.getFile();
986 pdb.setFile(matchedFile); // entry.getFile());
987 if (pdbfiles == null)
989 pdbfiles = new ArrayList<>();
992 if (!pdbfiles.contains(pdbId))
995 copyFileToJar(jout, matchedFile, pdbId);
999 Enumeration<String> props = entry.getProperties();
1000 if (props.hasMoreElements())
1002 PdbentryItem item = new PdbentryItem();
1003 while (props.hasMoreElements())
1005 Property prop = new Property();
1006 String key = props.nextElement();
1008 prop.setValue(entry.getProperty(key).toString());
1009 item.addProperty(prop);
1011 pdb.addPdbentryItem(item);
1014 jseq.addPdbids(pdb);
1018 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1023 if (!storeDS && av.hasHiddenRows())
1025 jal = av.getAlignment();
1029 if (storeDS && jal.getCodonFrames() != null)
1031 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1032 for (AlignedCodonFrame acf : jac)
1034 AlcodonFrame alc = new AlcodonFrame();
1035 if (acf.getProtMappings() != null
1036 && acf.getProtMappings().length > 0)
1038 boolean hasMap = false;
1039 SequenceI[] dnas = acf.getdnaSeqs();
1040 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1041 for (int m = 0; m < pmaps.length; m++)
1043 AlcodMap alcmap = new AlcodMap();
1044 alcmap.setDnasq(seqHash(dnas[m]));
1045 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1047 alc.addAlcodMap(alcmap);
1052 vamsasSet.addAlcodonFrame(alc);
1055 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1057 // AlcodonFrame alc = new AlcodonFrame();
1058 // vamsasSet.addAlcodonFrame(alc);
1059 // for (int p = 0; p < acf.aaWidth; p++)
1061 // Alcodon cmap = new Alcodon();
1062 // if (acf.codons[p] != null)
1064 // // Null codons indicate a gapped column in the translated peptide
1066 // cmap.setPos1(acf.codons[p][0]);
1067 // cmap.setPos2(acf.codons[p][1]);
1068 // cmap.setPos3(acf.codons[p][2]);
1070 // alc.addAlcodon(cmap);
1072 // if (acf.getProtMappings() != null
1073 // && acf.getProtMappings().length > 0)
1075 // SequenceI[] dnas = acf.getdnaSeqs();
1076 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1077 // for (int m = 0; m < pmaps.length; m++)
1079 // AlcodMap alcmap = new AlcodMap();
1080 // alcmap.setDnasq(seqHash(dnas[m]));
1081 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1083 // alc.addAlcodMap(alcmap);
1090 // /////////////////////////////////
1091 if (!storeDS && av.currentTree != null)
1093 // FIND ANY ASSOCIATED TREES
1094 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1095 if (Desktop.desktop != null)
1097 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1099 for (int t = 0; t < frames.length; t++)
1101 if (frames[t] instanceof TreePanel)
1103 TreePanel tp = (TreePanel) frames[t];
1105 if (tp.treeCanvas.av.getAlignment() == jal)
1107 Tree tree = new Tree();
1108 tree.setTitle(tp.getTitle());
1109 tree.setCurrentTree((av.currentTree == tp.getTree()));
1110 tree.setNewick(tp.getTree().print());
1111 tree.setThreshold(tp.treeCanvas.threshold);
1113 tree.setFitToWindow(tp.fitToWindow.getState());
1114 tree.setFontName(tp.getTreeFont().getName());
1115 tree.setFontSize(tp.getTreeFont().getSize());
1116 tree.setFontStyle(tp.getTreeFont().getStyle());
1117 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1119 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1120 tree.setShowDistances(tp.distanceMenu.getState());
1122 tree.setHeight(tp.getHeight());
1123 tree.setWidth(tp.getWidth());
1124 tree.setXpos(tp.getX());
1125 tree.setYpos(tp.getY());
1126 tree.setId(makeHashCode(tp, null));
1136 * store forward refs from an annotationRow to any groups
1138 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<>();
1141 for (SequenceI sq : jal.getSequences())
1143 // Store annotation on dataset sequences only
1144 AlignmentAnnotation[] aa = sq.getAnnotation();
1145 if (aa != null && aa.length > 0)
1147 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1154 if (jal.getAlignmentAnnotation() != null)
1156 // Store the annotation shown on the alignment.
1157 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1158 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1163 if (jal.getGroups() != null)
1165 JGroup[] groups = new JGroup[jal.getGroups().size()];
1167 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1169 JGroup jGroup = new JGroup();
1170 groups[++i] = jGroup;
1172 jGroup.setStart(sg.getStartRes());
1173 jGroup.setEnd(sg.getEndRes());
1174 jGroup.setName(sg.getName());
1175 if (groupRefs.containsKey(sg))
1177 // group has references so set its ID field
1178 jGroup.setId(groupRefs.get(sg));
1180 ColourSchemeI colourScheme = sg.getColourScheme();
1181 if (colourScheme != null)
1183 ResidueShaderI groupColourScheme = sg
1184 .getGroupColourScheme();
1185 if (groupColourScheme.conservationApplied())
1187 jGroup.setConsThreshold(groupColourScheme.getConservationInc());
1189 if (colourScheme instanceof jalview.schemes.UserColourScheme)
1191 jGroup.setColour(setUserColourScheme(colourScheme,
1196 jGroup.setColour(colourScheme.getSchemeName());
1199 else if (colourScheme instanceof jalview.schemes.AnnotationColourGradient)
1201 jGroup.setColour("AnnotationColourGradient");
1202 jGroup.setAnnotationColours(constructAnnotationColours(
1203 (jalview.schemes.AnnotationColourGradient) colourScheme,
1206 else if (colourScheme instanceof jalview.schemes.UserColourScheme)
1208 jGroup.setColour(setUserColourScheme(colourScheme,
1213 jGroup.setColour(colourScheme.getSchemeName());
1216 jGroup.setPidThreshold(groupColourScheme.getThreshold());
1219 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1220 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1221 jGroup.setDisplayText(sg.getDisplayText());
1222 jGroup.setColourText(sg.getColourText());
1223 jGroup.setTextCol1(sg.textColour.getRGB());
1224 jGroup.setTextCol2(sg.textColour2.getRGB());
1225 jGroup.setTextColThreshold(sg.thresholdTextColour);
1226 jGroup.setShowUnconserved(sg.getShowNonconserved());
1227 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1228 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1229 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1230 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1231 for (SequenceI seq : sg.getSequences())
1233 jGroup.addSeq(seqHash(seq));
1237 jms.setJGroup(groups);
1241 // /////////SAVE VIEWPORT
1242 Viewport view = new Viewport();
1243 view.setTitle(ap.alignFrame.getTitle());
1244 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1245 av.getSequenceSetId()));
1246 view.setId(av.getViewId());
1247 if (av.getCodingComplement() != null)
1249 view.setComplementId(av.getCodingComplement().getViewId());
1251 view.setViewName(av.viewName);
1252 view.setGatheredViews(av.isGatherViewsHere());
1254 Rectangle size = ap.av.getExplodedGeometry();
1255 Rectangle position = size;
1258 size = ap.alignFrame.getBounds();
1259 if (av.getCodingComplement() != null)
1261 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1269 view.setXpos(position.x);
1270 view.setYpos(position.y);
1272 view.setWidth(size.width);
1273 view.setHeight(size.height);
1275 view.setStartRes(vpRanges.getStartRes());
1276 view.setStartSeq(vpRanges.getStartSeq());
1278 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1280 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1283 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1285 AnnotationColours ac = constructAnnotationColours(
1286 (jalview.schemes.AnnotationColourGradient) av
1287 .getGlobalColourScheme(),
1290 view.setAnnotationColours(ac);
1291 view.setBgColour("AnnotationColourGradient");
1295 view.setBgColour(ColourSchemeProperty.getColourName(av
1296 .getGlobalColourScheme()));
1299 ResidueShaderI vcs = av.getResidueShading();
1300 ColourSchemeI cs = av.getGlobalColourScheme();
1304 if (vcs.conservationApplied())
1306 view.setConsThreshold(vcs.getConservationInc());
1307 if (cs instanceof jalview.schemes.UserColourScheme)
1309 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1312 view.setPidThreshold(vcs.getThreshold());
1315 view.setConservationSelected(av.getConservationSelected());
1316 view.setPidSelected(av.getAbovePIDThreshold());
1317 view.setFontName(av.font.getName());
1318 view.setFontSize(av.font.getSize());
1319 view.setFontStyle(av.font.getStyle());
1320 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1321 view.setRenderGaps(av.isRenderGaps());
1322 view.setShowAnnotation(av.isShowAnnotation());
1323 view.setShowBoxes(av.getShowBoxes());
1324 view.setShowColourText(av.getColourText());
1325 view.setShowFullId(av.getShowJVSuffix());
1326 view.setRightAlignIds(av.isRightAlignIds());
1327 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1328 view.setShowText(av.getShowText());
1329 view.setShowUnconserved(av.getShowUnconserved());
1330 view.setWrapAlignment(av.getWrapAlignment());
1331 view.setTextCol1(av.getTextColour().getRGB());
1332 view.setTextCol2(av.getTextColour2().getRGB());
1333 view.setTextColThreshold(av.getThresholdTextColour());
1334 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1335 view.setShowSequenceLogo(av.isShowSequenceLogo());
1336 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1337 view.setShowGroupConsensus(av.isShowGroupConsensus());
1338 view.setShowGroupConservation(av.isShowGroupConservation());
1339 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1340 view.setShowDbRefTooltip(av.isShowDBRefs());
1341 view.setFollowHighlight(av.isFollowHighlight());
1342 view.setFollowSelection(av.followSelection);
1343 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1344 if (av.getFeaturesDisplayed() != null)
1346 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1348 String[] renderOrder = ap.getSeqPanel().seqCanvas
1349 .getFeatureRenderer().getRenderOrder()
1350 .toArray(new String[0]);
1352 Vector<String> settingsAdded = new Vector<>();
1353 if (renderOrder != null)
1355 for (String featureType : renderOrder)
1357 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1358 .getFeatureRenderer().getFeatureStyle(featureType);
1359 Setting setting = new Setting();
1360 setting.setType(featureType);
1361 if (!fcol.isSimpleColour())
1363 setting.setColour(fcol.getMaxColour().getRGB());
1364 setting.setMincolour(fcol.getMinColour().getRGB());
1365 setting.setMin(fcol.getMin());
1366 setting.setMax(fcol.getMax());
1367 setting.setColourByLabel(fcol.isColourByLabel());
1368 setting.setAutoScale(fcol.isAutoScaled());
1369 setting.setThreshold(fcol.getThreshold());
1370 // -1 = No threshold, 0 = Below, 1 = Above
1371 setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
1372 .isBelowThreshold() ? 0 : -1));
1376 setting.setColour(fcol.getColour().getRGB());
1379 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1381 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1382 .getOrder(featureType);
1385 setting.setOrder(rorder);
1387 fs.addSetting(setting);
1388 settingsAdded.addElement(featureType);
1392 // is groups actually supposed to be a map here ?
1393 Iterator<String> en = ap.getSeqPanel().seqCanvas
1394 .getFeatureRenderer().getFeatureGroups().iterator();
1395 Vector<String> groupsAdded = new Vector<>();
1396 while (en.hasNext())
1398 String grp = en.next();
1399 if (groupsAdded.contains(grp))
1403 Group g = new Group();
1405 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1406 .getFeatureRenderer().checkGroupVisibility(grp, false))
1409 groupsAdded.addElement(grp);
1411 jms.setFeatureSettings(fs);
1414 if (av.hasHiddenColumns())
1416 jalview.datamodel.HiddenColumns hidden = av.getAlignment()
1417 .getHiddenColumns();
1420 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1424 ArrayList<int[]> hiddenRegions = hidden
1425 .getHiddenColumnsCopy();
1426 for (int[] region : hiddenRegions)
1428 HiddenColumns hc = new HiddenColumns();
1429 hc.setStart(region[0]);
1430 hc.setEnd(region[1]);
1431 view.addHiddenColumns(hc);
1435 if (calcIdSet.size() > 0)
1437 for (String calcId : calcIdSet)
1439 if (calcId.trim().length() > 0)
1441 CalcIdParam cidp = createCalcIdParam(calcId, av);
1442 // Some calcIds have no parameters.
1445 view.addCalcIdParam(cidp);
1451 jms.addViewport(view);
1453 object.setJalviewModelSequence(jms);
1454 object.getVamsasModel().addSequenceSet(vamsasSet);
1456 if (jout != null && fileName != null)
1458 // We may not want to write the object to disk,
1459 // eg we can copy the alignViewport to a new view object
1460 // using save and then load
1463 System.out.println("Writing jar entry " + fileName);
1464 JarEntry entry = new JarEntry(fileName);
1465 jout.putNextEntry(entry);
1466 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1468 Marshaller marshaller = new Marshaller(pout);
1469 marshaller.marshal(object);
1472 } catch (Exception ex)
1474 // TODO: raise error in GUI if marshalling failed.
1475 ex.printStackTrace();
1482 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1483 * for each viewer, with
1485 * <li>viewer geometry (position, size, split pane divider location)</li>
1486 * <li>index of the selected structure in the viewer (currently shows gapped
1488 * <li>the id of the annotation holding RNA secondary structure</li>
1489 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1491 * Varna viewer state is also written out (in native Varna XML) to separate
1492 * project jar entries. A separate entry is written for each RNA structure
1493 * displayed, with the naming convention
1495 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1503 * @param storeDataset
1505 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1506 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1507 boolean storeDataset)
1509 if (Desktop.desktop == null)
1513 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1514 for (int f = frames.length - 1; f > -1; f--)
1516 if (frames[f] instanceof AppVarna)
1518 AppVarna varna = (AppVarna) frames[f];
1520 * link the sequence to every viewer that is showing it and is linked to
1521 * its alignment panel
1523 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1525 String viewId = varna.getViewId();
1526 RnaViewer rna = new RnaViewer();
1527 rna.setViewId(viewId);
1528 rna.setTitle(varna.getTitle());
1529 rna.setXpos(varna.getX());
1530 rna.setYpos(varna.getY());
1531 rna.setWidth(varna.getWidth());
1532 rna.setHeight(varna.getHeight());
1533 rna.setDividerLocation(varna.getDividerLocation());
1534 rna.setSelectedRna(varna.getSelectedIndex());
1535 jseq.addRnaViewer(rna);
1538 * Store each Varna panel's state once in the project per sequence.
1539 * First time through only (storeDataset==false)
1541 // boolean storeSessions = false;
1542 // String sequenceViewId = viewId + seqsToIds.get(jds);
1543 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1545 // viewIds.add(sequenceViewId);
1546 // storeSessions = true;
1548 for (RnaModel model : varna.getModels())
1550 if (model.seq == jds)
1553 * VARNA saves each view (sequence or alignment secondary
1554 * structure, gapped or trimmed) as a separate XML file
1556 String jarEntryName = rnaSessions.get(model);
1557 if (jarEntryName == null)
1560 String varnaStateFile = varna.getStateInfo(model.rna);
1561 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1562 copyFileToJar(jout, varnaStateFile, jarEntryName);
1563 rnaSessions.put(model, jarEntryName);
1565 SecondaryStructure ss = new SecondaryStructure();
1566 String annotationId = varna.getAnnotation(jds).annotationId;
1567 ss.setAnnotationId(annotationId);
1568 ss.setViewerState(jarEntryName);
1569 ss.setGapped(model.gapped);
1570 ss.setTitle(model.title);
1571 rna.addSecondaryStructure(ss);
1580 * Copy the contents of a file to a new entry added to the output jar
1584 * @param jarEntryName
1586 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1587 String jarEntryName)
1589 DataInputStream dis = null;
1592 File file = new File(infilePath);
1593 if (file.exists() && jout != null)
1595 dis = new DataInputStream(new FileInputStream(file));
1596 byte[] data = new byte[(int) file.length()];
1597 dis.readFully(data);
1598 writeJarEntry(jout, jarEntryName, data);
1600 } catch (Exception ex)
1602 ex.printStackTrace();
1610 } catch (IOException e)
1619 * Write the data to a new entry of given name in the output jar file
1622 * @param jarEntryName
1624 * @throws IOException
1626 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1627 byte[] data) throws IOException
1631 System.out.println("Writing jar entry " + jarEntryName);
1632 jout.putNextEntry(new JarEntry(jarEntryName));
1633 DataOutputStream dout = new DataOutputStream(jout);
1634 dout.write(data, 0, data.length);
1641 * Save the state of a structure viewer
1646 * the archive XML element under which to save the state
1649 * @param matchedFile
1653 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1654 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1655 String matchedFile, StructureViewerBase viewFrame)
1657 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1660 * Look for any bindings for this viewer to the PDB file of interest
1661 * (including part matches excluding chain id)
1663 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1665 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1666 final String pdbId = pdbentry.getId();
1667 if (!pdbId.equals(entry.getId())
1668 && !(entry.getId().length() > 4 && entry.getId()
1669 .toLowerCase().startsWith(pdbId.toLowerCase())))
1672 * not interested in a binding to a different PDB entry here
1676 if (matchedFile == null)
1678 matchedFile = pdbentry.getFile();
1680 else if (!matchedFile.equals(pdbentry.getFile()))
1683 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1684 + pdbentry.getFile());
1688 // can get at it if the ID
1689 // match is ambiguous (e.g.
1692 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1694 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1695 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1697 StructureState state = new StructureState();
1698 state.setVisible(true);
1699 state.setXpos(viewFrame.getX());
1700 state.setYpos(viewFrame.getY());
1701 state.setWidth(viewFrame.getWidth());
1702 state.setHeight(viewFrame.getHeight());
1703 final String viewId = viewFrame.getViewId();
1704 state.setViewId(viewId);
1705 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1706 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1707 state.setColourByJmol(viewFrame.isColouredByViewer());
1708 state.setType(viewFrame.getViewerType().toString());
1709 pdb.addStructureState(state);
1717 * Populates the AnnotationColours xml for save. This captures the settings of
1718 * the options in the 'Colour by Annotation' dialog.
1721 * @param userColours
1725 private AnnotationColours constructAnnotationColours(
1726 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1727 JalviewModelSequence jms)
1729 AnnotationColours ac = new AnnotationColours();
1730 ac.setAboveThreshold(acg.getAboveThreshold());
1731 ac.setThreshold(acg.getAnnotationThreshold());
1732 // 2.10.2 save annotationId (unique) not annotation label
1733 ac.setAnnotation(acg.getAnnotation().annotationId);
1734 if (acg.getBaseColour() instanceof UserColourScheme)
1736 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1741 ac.setColourScheme(ColourSchemeProperty.getColourName(acg.getBaseColour()));
1744 ac.setMaxColour(acg.getMaxColour().getRGB());
1745 ac.setMinColour(acg.getMinColour().getRGB());
1746 ac.setPerSequence(acg.isSeqAssociated());
1747 ac.setPredefinedColours(acg.isPredefinedColours());
1751 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1752 IdentityHashMap<SequenceGroup, String> groupRefs,
1753 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1754 SequenceSet vamsasSet)
1757 for (int i = 0; i < aa.length; i++)
1759 Annotation an = new Annotation();
1761 AlignmentAnnotation annotation = aa[i];
1762 if (annotation.annotationId != null)
1764 annotationIds.put(annotation.annotationId, annotation);
1767 an.setId(annotation.annotationId);
1769 an.setVisible(annotation.visible);
1771 an.setDescription(annotation.description);
1773 if (annotation.sequenceRef != null)
1775 // 2.9 JAL-1781 xref on sequence id rather than name
1776 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1778 if (annotation.groupRef != null)
1780 String groupIdr = groupRefs.get(annotation.groupRef);
1781 if (groupIdr == null)
1783 // make a locally unique String
1785 annotation.groupRef,
1786 groupIdr = ("" + System.currentTimeMillis()
1787 + annotation.groupRef.getName() + groupRefs
1790 an.setGroupRef(groupIdr.toString());
1793 // store all visualization attributes for annotation
1794 an.setGraphHeight(annotation.graphHeight);
1795 an.setCentreColLabels(annotation.centreColLabels);
1796 an.setScaleColLabels(annotation.scaleColLabel);
1797 an.setShowAllColLabels(annotation.showAllColLabels);
1798 an.setBelowAlignment(annotation.belowAlignment);
1800 if (annotation.graph > 0)
1803 an.setGraphType(annotation.graph);
1804 an.setGraphGroup(annotation.graphGroup);
1805 if (annotation.getThreshold() != null)
1807 ThresholdLine line = new ThresholdLine();
1808 line.setLabel(annotation.getThreshold().label);
1809 line.setValue(annotation.getThreshold().value);
1810 line.setColour(annotation.getThreshold().colour.getRGB());
1811 an.setThresholdLine(line);
1819 an.setLabel(annotation.label);
1821 if (annotation == av.getAlignmentQualityAnnot()
1822 || annotation == av.getAlignmentConservationAnnotation()
1823 || annotation == av.getAlignmentConsensusAnnotation()
1824 || annotation.autoCalculated)
1826 // new way of indicating autocalculated annotation -
1827 an.setAutoCalculated(annotation.autoCalculated);
1829 if (annotation.hasScore())
1831 an.setScore(annotation.getScore());
1834 if (annotation.getCalcId() != null)
1836 calcIdSet.add(annotation.getCalcId());
1837 an.setCalcId(annotation.getCalcId());
1839 if (annotation.hasProperties())
1841 for (String pr : annotation.getProperties())
1843 Property prop = new Property();
1845 prop.setValue(annotation.getProperty(pr));
1846 an.addProperty(prop);
1850 AnnotationElement ae;
1851 if (annotation.annotations != null)
1853 an.setScoreOnly(false);
1854 for (int a = 0; a < annotation.annotations.length; a++)
1856 if ((annotation == null) || (annotation.annotations[a] == null))
1861 ae = new AnnotationElement();
1862 if (annotation.annotations[a].description != null)
1864 ae.setDescription(annotation.annotations[a].description);
1866 if (annotation.annotations[a].displayCharacter != null)
1868 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1871 if (!Float.isNaN(annotation.annotations[a].value))
1873 ae.setValue(annotation.annotations[a].value);
1877 if (annotation.annotations[a].secondaryStructure > ' ')
1879 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1883 if (annotation.annotations[a].colour != null
1884 && annotation.annotations[a].colour != java.awt.Color.black)
1886 ae.setColour(annotation.annotations[a].colour.getRGB());
1889 an.addAnnotationElement(ae);
1890 if (annotation.autoCalculated)
1892 // only write one non-null entry into the annotation row -
1893 // sufficient to get the visualization attributes necessary to
1901 an.setScoreOnly(true);
1903 if (!storeDS || (storeDS && !annotation.autoCalculated))
1905 // skip autocalculated annotation - these are only provided for
1907 vamsasSet.addAnnotation(an);
1913 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1915 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1916 if (settings != null)
1918 CalcIdParam vCalcIdParam = new CalcIdParam();
1919 vCalcIdParam.setCalcId(calcId);
1920 vCalcIdParam.addServiceURL(settings.getServiceURI());
1921 // generic URI allowing a third party to resolve another instance of the
1922 // service used for this calculation
1923 for (String urls : settings.getServiceURLs())
1925 vCalcIdParam.addServiceURL(urls);
1927 vCalcIdParam.setVersion("1.0");
1928 if (settings.getPreset() != null)
1930 WsParamSetI setting = settings.getPreset();
1931 vCalcIdParam.setName(setting.getName());
1932 vCalcIdParam.setDescription(setting.getDescription());
1936 vCalcIdParam.setName("");
1937 vCalcIdParam.setDescription("Last used parameters");
1939 // need to be able to recover 1) settings 2) user-defined presets or
1940 // recreate settings from preset 3) predefined settings provided by
1941 // service - or settings that can be transferred (or discarded)
1942 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1944 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1945 // todo - decide if updateImmediately is needed for any projects.
1947 return vCalcIdParam;
1952 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1955 if (calcIdParam.getVersion().equals("1.0"))
1957 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1958 .getPreferredServiceFor(calcIdParam.getServiceURL());
1959 if (service != null)
1961 WsParamSetI parmSet = null;
1964 parmSet = service.getParamStore().parseServiceParameterFile(
1965 calcIdParam.getName(), calcIdParam.getDescription(),
1966 calcIdParam.getServiceURL(),
1967 calcIdParam.getParameters().replace("|\\n|", "\n"));
1968 } catch (IOException x)
1970 warn("Couldn't parse parameter data for "
1971 + calcIdParam.getCalcId(), x);
1974 List<ArgumentI> argList = null;
1975 if (calcIdParam.getName().length() > 0)
1977 parmSet = service.getParamStore()
1978 .getPreset(calcIdParam.getName());
1979 if (parmSet != null)
1981 // TODO : check we have a good match with settings in AACon -
1982 // otherwise we'll need to create a new preset
1987 argList = parmSet.getArguments();
1990 AAConSettings settings = new AAConSettings(
1991 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1992 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1993 calcIdParam.isNeedsUpdate());
1998 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
2002 throw new Error(MessageManager.formatMessage(
2003 "error.unsupported_version_calcIdparam",
2004 new Object[] { calcIdParam.toString() }));
2008 * External mapping between jalview objects and objects yielding a valid and
2009 * unique object ID string. This is null for normal Jalview project IO, but
2010 * non-null when a jalview project is being read or written as part of a
2013 IdentityHashMap jv2vobj = null;
2016 * Construct a unique ID for jvobj using either existing bindings or if none
2017 * exist, the result of the hashcode call for the object.
2020 * jalview data object
2021 * @return unique ID for referring to jvobj
2023 private String makeHashCode(Object jvobj, String altCode)
2025 if (jv2vobj != null)
2027 Object id = jv2vobj.get(jvobj);
2030 return id.toString();
2032 // check string ID mappings
2033 if (jvids2vobj != null && jvobj instanceof String)
2035 id = jvids2vobj.get(jvobj);
2039 return id.toString();
2041 // give up and warn that something has gone wrong
2042 warn("Cannot find ID for object in external mapping : " + jvobj);
2048 * return local jalview object mapped to ID, if it exists
2052 * @return null or object bound to idcode
2054 private Object retrieveExistingObj(String idcode)
2056 if (idcode != null && vobj2jv != null)
2058 return vobj2jv.get(idcode);
2064 * binding from ID strings from external mapping table to jalview data model
2067 private Hashtable vobj2jv;
2069 private Sequence createVamsasSequence(String id, SequenceI jds)
2071 return createVamsasSequence(true, id, jds, null);
2074 private Sequence createVamsasSequence(boolean recurse, String id,
2075 SequenceI jds, SequenceI parentseq)
2077 Sequence vamsasSeq = new Sequence();
2078 vamsasSeq.setId(id);
2079 vamsasSeq.setName(jds.getName());
2080 vamsasSeq.setSequence(jds.getSequenceAsString());
2081 vamsasSeq.setDescription(jds.getDescription());
2082 jalview.datamodel.DBRefEntry[] dbrefs = null;
2083 if (jds.getDatasetSequence() != null)
2085 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2089 // seqId==dsseqid so we can tell which sequences really are
2090 // dataset sequences only
2091 vamsasSeq.setDsseqid(id);
2092 dbrefs = jds.getDBRefs();
2093 if (parentseq == null)
2100 for (int d = 0; d < dbrefs.length; d++)
2102 DBRef dbref = new DBRef();
2103 dbref.setSource(dbrefs[d].getSource());
2104 dbref.setVersion(dbrefs[d].getVersion());
2105 dbref.setAccessionId(dbrefs[d].getAccessionId());
2106 if (dbrefs[d].hasMap())
2108 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2110 dbref.setMapping(mp);
2112 vamsasSeq.addDBRef(dbref);
2118 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2119 SequenceI parentseq, SequenceI jds, boolean recurse)
2122 if (jmp.getMap() != null)
2126 jalview.util.MapList mlst = jmp.getMap();
2127 List<int[]> r = mlst.getFromRanges();
2128 for (int[] range : r)
2130 MapListFrom mfrom = new MapListFrom();
2131 mfrom.setStart(range[0]);
2132 mfrom.setEnd(range[1]);
2133 mp.addMapListFrom(mfrom);
2135 r = mlst.getToRanges();
2136 for (int[] range : r)
2138 MapListTo mto = new MapListTo();
2139 mto.setStart(range[0]);
2140 mto.setEnd(range[1]);
2141 mp.addMapListTo(mto);
2143 mp.setMapFromUnit(mlst.getFromRatio());
2144 mp.setMapToUnit(mlst.getToRatio());
2145 if (jmp.getTo() != null)
2147 MappingChoice mpc = new MappingChoice();
2149 // check/create ID for the sequence referenced by getTo()
2152 SequenceI ps = null;
2153 if (parentseq != jmp.getTo()
2154 && parentseq.getDatasetSequence() != jmp.getTo())
2156 // chaining dbref rather than a handshaking one
2157 jmpid = seqHash(ps = jmp.getTo());
2161 jmpid = seqHash(ps = parentseq);
2163 mpc.setDseqFor(jmpid);
2164 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2166 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2167 seqRefIds.put(mpc.getDseqFor(), ps);
2171 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2174 mp.setMappingChoice(mpc);
2180 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2181 List<UserColourScheme> userColours, JalviewModelSequence jms)
2184 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2185 boolean newucs = false;
2186 if (!userColours.contains(ucs))
2188 userColours.add(ucs);
2191 id = "ucs" + userColours.indexOf(ucs);
2194 // actually create the scheme's entry in the XML model
2195 java.awt.Color[] colours = ucs.getColours();
2196 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2197 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2199 for (int i = 0; i < colours.length; i++)
2201 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2202 col.setName(ResidueProperties.aa[i]);
2203 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2204 jbucs.addColour(col);
2206 if (ucs.getLowerCaseColours() != null)
2208 colours = ucs.getLowerCaseColours();
2209 for (int i = 0; i < colours.length; i++)
2211 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2212 col.setName(ResidueProperties.aa[i].toLowerCase());
2213 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2214 jbucs.addColour(col);
2219 uc.setUserColourScheme(jbucs);
2220 jms.addUserColours(uc);
2226 jalview.schemes.UserColourScheme getUserColourScheme(
2227 JalviewModelSequence jms, String id)
2229 UserColours[] uc = jms.getUserColours();
2230 UserColours colours = null;
2232 for (int i = 0; i < uc.length; i++)
2234 if (uc[i].getId().equals(id))
2242 java.awt.Color[] newColours = new java.awt.Color[24];
2244 for (int i = 0; i < 24; i++)
2246 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2247 .getUserColourScheme().getColour(i).getRGB(), 16));
2250 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2253 if (colours.getUserColourScheme().getColourCount() > 24)
2255 newColours = new java.awt.Color[23];
2256 for (int i = 0; i < 23; i++)
2258 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2259 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2261 ucs.setLowerCaseColours(newColours);
2268 * contains last error message (if any) encountered by XML loader.
2270 String errorMessage = null;
2273 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2274 * exceptions are raised during project XML parsing
2276 public boolean attemptversion1parse = true;
2279 * Load a jalview project archive from a jar file
2282 * - HTTP URL or filename
2284 public AlignFrame loadJalviewAlign(final String file)
2287 jalview.gui.AlignFrame af = null;
2291 // create list to store references for any new Jmol viewers created
2292 newStructureViewers = new Vector<>();
2293 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2294 // Workaround is to make sure caller implements the JarInputStreamProvider
2296 // so we can re-open the jar input stream for each entry.
2298 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2299 af = loadJalviewAlign(jprovider);
2301 } catch (MalformedURLException e)
2303 errorMessage = "Invalid URL format for '" + file + "'";
2309 SwingUtilities.invokeAndWait(new Runnable()
2314 setLoadingFinishedForNewStructureViewers();
2317 } catch (Exception x)
2319 System.err.println("Error loading alignment: " + x.getMessage());
2325 private jarInputStreamProvider createjarInputStreamProvider(
2326 final String file) throws MalformedURLException
2329 errorMessage = null;
2330 uniqueSetSuffix = null;
2332 viewportsAdded.clear();
2333 frefedSequence = null;
2335 if (file.startsWith("http://"))
2337 url = new URL(file);
2339 final URL _url = url;
2340 return new jarInputStreamProvider()
2344 public JarInputStream getJarInputStream() throws IOException
2348 return new JarInputStream(_url.openStream());
2352 return new JarInputStream(new FileInputStream(file));
2357 public String getFilename()
2365 * Recover jalview session from a jalview project archive. Caller may
2366 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2367 * themselves. Any null fields will be initialised with default values,
2368 * non-null fields are left alone.
2373 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2375 errorMessage = null;
2376 if (uniqueSetSuffix == null)
2378 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2380 if (seqRefIds == null)
2384 AlignFrame af = null, _af = null;
2385 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<>();
2386 Map<String, AlignFrame> gatherToThisFrame = new HashMap<>();
2387 final String file = jprovider.getFilename();
2390 JarInputStream jin = null;
2391 JarEntry jarentry = null;
2396 jin = jprovider.getJarInputStream();
2397 for (int i = 0; i < entryCount; i++)
2399 jarentry = jin.getNextJarEntry();
2402 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2404 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2405 JalviewModel object = new JalviewModel();
2407 Unmarshaller unmar = new Unmarshaller(object);
2408 unmar.setValidation(false);
2409 object = (JalviewModel) unmar.unmarshal(in);
2410 if (true) // !skipViewport(object))
2412 _af = loadFromObject(object, file, true, jprovider);
2414 && object.getJalviewModelSequence().getViewportCount() > 0)
2418 // store a reference to the first view
2421 if (_af.viewport.isGatherViewsHere())
2423 // if this is a gathered view, keep its reference since
2424 // after gathering views, only this frame will remain
2426 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2428 // Save dataset to register mappings once all resolved
2429 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2430 af.viewport.getAlignment().getDataset());
2435 else if (jarentry != null)
2437 // Some other file here.
2440 } while (jarentry != null);
2441 resolveFrefedSequences();
2442 } catch (IOException ex)
2444 ex.printStackTrace();
2445 errorMessage = "Couldn't locate Jalview XML file : " + file;
2446 System.err.println("Exception whilst loading jalview XML file : "
2448 } catch (Exception ex)
2450 System.err.println("Parsing as Jalview Version 2 file failed.");
2451 ex.printStackTrace(System.err);
2452 if (attemptversion1parse)
2454 // Is Version 1 Jar file?
2457 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2458 } catch (Exception ex2)
2460 System.err.println("Exception whilst loading as jalviewXMLV1:");
2461 ex2.printStackTrace();
2465 if (Desktop.instance != null)
2467 Desktop.instance.stopLoading();
2471 System.out.println("Successfully loaded archive file");
2474 ex.printStackTrace();
2476 System.err.println("Exception whilst loading jalview XML file : "
2478 } catch (OutOfMemoryError e)
2480 // Don't use the OOM Window here
2481 errorMessage = "Out of memory loading jalview XML file";
2482 System.err.println("Out of memory whilst loading jalview XML file");
2483 e.printStackTrace();
2487 * Regather multiple views (with the same sequence set id) to the frame (if
2488 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2489 * views instead of separate frames. Note this doesn't restore a state where
2490 * some expanded views in turn have tabbed views - the last "first tab" read
2491 * in will play the role of gatherer for all.
2493 for (AlignFrame fr : gatherToThisFrame.values())
2495 Desktop.instance.gatherViews(fr);
2498 restoreSplitFrames();
2499 for (AlignmentI ds : importedDatasets.keySet())
2501 if (ds.getCodonFrames() != null)
2503 StructureSelectionManager.getStructureSelectionManager(
2504 Desktop.instance).registerMappings(ds.getCodonFrames());
2507 if (errorMessage != null)
2512 if (Desktop.instance != null)
2514 Desktop.instance.stopLoading();
2521 * Try to reconstruct and display SplitFrame windows, where each contains
2522 * complementary dna and protein alignments. Done by pairing up AlignFrame
2523 * objects (created earlier) which have complementary viewport ids associated.
2525 protected void restoreSplitFrames()
2527 List<SplitFrame> gatherTo = new ArrayList<>();
2528 List<AlignFrame> addedToSplitFrames = new ArrayList<>();
2529 Map<String, AlignFrame> dna = new HashMap<>();
2532 * Identify the DNA alignments
2534 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2537 AlignFrame af = candidate.getValue();
2538 if (af.getViewport().getAlignment().isNucleotide())
2540 dna.put(candidate.getKey().getId(), af);
2545 * Try to match up the protein complements
2547 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2550 AlignFrame af = candidate.getValue();
2551 if (!af.getViewport().getAlignment().isNucleotide())
2553 String complementId = candidate.getKey().getComplementId();
2554 // only non-null complements should be in the Map
2555 if (complementId != null && dna.containsKey(complementId))
2557 final AlignFrame dnaFrame = dna.get(complementId);
2558 SplitFrame sf = createSplitFrame(dnaFrame, af);
2559 addedToSplitFrames.add(dnaFrame);
2560 addedToSplitFrames.add(af);
2561 dnaFrame.setMenusForViewport();
2562 af.setMenusForViewport();
2563 if (af.viewport.isGatherViewsHere())
2572 * Open any that we failed to pair up (which shouldn't happen!) as
2573 * standalone AlignFrame's.
2575 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2578 AlignFrame af = candidate.getValue();
2579 if (!addedToSplitFrames.contains(af))
2581 Viewport view = candidate.getKey();
2582 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2584 af.setMenusForViewport();
2585 System.err.println("Failed to restore view " + view.getTitle()
2586 + " to split frame");
2591 * Gather back into tabbed views as flagged.
2593 for (SplitFrame sf : gatherTo)
2595 Desktop.instance.gatherViews(sf);
2598 splitFrameCandidates.clear();
2602 * Construct and display one SplitFrame holding DNA and protein alignments.
2605 * @param proteinFrame
2608 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2609 AlignFrame proteinFrame)
2611 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2612 String title = MessageManager.getString("label.linked_view_title");
2613 int width = (int) dnaFrame.getBounds().getWidth();
2614 int height = (int) (dnaFrame.getBounds().getHeight()
2615 + proteinFrame.getBounds().getHeight() + 50);
2618 * SplitFrame location is saved to both enclosed frames
2620 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2621 Desktop.addInternalFrame(splitFrame, title, width, height);
2624 * And compute cDNA consensus (couldn't do earlier with consensus as
2625 * mappings were not yet present)
2627 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2633 * check errorMessage for a valid error message and raise an error box in the
2634 * GUI or write the current errorMessage to stderr and then clear the error
2637 protected void reportErrors()
2639 reportErrors(false);
2642 protected void reportErrors(final boolean saving)
2644 if (errorMessage != null)
2646 final String finalErrorMessage = errorMessage;
2649 javax.swing.SwingUtilities.invokeLater(new Runnable()
2655 .showInternalMessageDialog(Desktop.desktop,
2656 finalErrorMessage, "Error "
2657 + (saving ? "saving" : "loading")
2659 JvOptionPane.WARNING_MESSAGE);
2665 System.err.println("Problem loading Jalview file: " + errorMessage);
2668 errorMessage = null;
2671 Map<String, String> alreadyLoadedPDB = new HashMap<>();
2674 * when set, local views will be updated from view stored in JalviewXML
2675 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2676 * sync if this is set to true.
2678 private final boolean updateLocalViews = false;
2681 * Returns the path to a temporary file holding the PDB file for the given PDB
2682 * id. The first time of asking, searches for a file of that name in the
2683 * Jalview project jar, and copies it to a new temporary file. Any repeat
2684 * requests just return the path to the file previously created.
2690 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2693 if (alreadyLoadedPDB.containsKey(pdbId))
2695 return alreadyLoadedPDB.get(pdbId).toString();
2698 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2700 if (tempFile != null)
2702 alreadyLoadedPDB.put(pdbId, tempFile);
2708 * Copies the jar entry of given name to a new temporary file and returns the
2709 * path to the file, or null if the entry is not found.
2712 * @param jarEntryName
2714 * a prefix for the temporary file name, must be at least three
2717 * null or original file - so new file can be given the same suffix
2721 protected String copyJarEntry(jarInputStreamProvider jprovider,
2722 String jarEntryName, String prefix, String origFile)
2724 BufferedReader in = null;
2725 PrintWriter out = null;
2726 String suffix = ".tmp";
2727 if (origFile == null)
2729 origFile = jarEntryName;
2731 int sfpos = origFile.lastIndexOf(".");
2732 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2734 suffix = "." + origFile.substring(sfpos + 1);
2738 JarInputStream jin = jprovider.getJarInputStream();
2740 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2741 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2742 * FileInputStream(jprovider)); }
2745 JarEntry entry = null;
2748 entry = jin.getNextJarEntry();
2749 } while (entry != null && !entry.getName().equals(jarEntryName));
2752 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2753 File outFile = File.createTempFile(prefix, suffix);
2754 outFile.deleteOnExit();
2755 out = new PrintWriter(new FileOutputStream(outFile));
2758 while ((data = in.readLine()) != null)
2763 String t = outFile.getAbsolutePath();
2768 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2770 } catch (Exception ex)
2772 ex.printStackTrace();
2780 } catch (IOException e)
2794 private class JvAnnotRow
2796 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2803 * persisted version of annotation row from which to take vis properties
2805 public jalview.datamodel.AlignmentAnnotation template;
2808 * original position of the annotation row in the alignment
2814 * Load alignment frame from jalview XML DOM object
2819 * filename source string
2820 * @param loadTreesAndStructures
2821 * when false only create Viewport
2823 * data source provider
2824 * @return alignment frame created from view stored in DOM
2826 AlignFrame loadFromObject(JalviewModel object, String file,
2827 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2829 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2830 Sequence[] vamsasSeq = vamsasSet.getSequence();
2832 JalviewModelSequence jms = object.getJalviewModelSequence();
2834 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2837 // ////////////////////////////////
2840 List<SequenceI> hiddenSeqs = null;
2842 List<SequenceI> tmpseqs = new ArrayList<>();
2844 boolean multipleView = false;
2845 SequenceI referenceseqForView = null;
2846 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2847 int vi = 0; // counter in vamsasSeq array
2848 for (int i = 0; i < jseqs.length; i++)
2850 String seqId = jseqs[i].getId();
2852 SequenceI tmpSeq = seqRefIds.get(seqId);
2855 if (!incompleteSeqs.containsKey(seqId))
2857 // may not need this check, but keep it for at least 2.9,1 release
2858 if (tmpSeq.getStart() != jseqs[i].getStart()
2859 || tmpSeq.getEnd() != jseqs[i].getEnd())
2862 .println("Warning JAL-2154 regression: updating start/end for sequence "
2863 + tmpSeq.toString() + " to " + jseqs[i]);
2868 incompleteSeqs.remove(seqId);
2870 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2872 // most likely we are reading a dataset XML document so
2873 // update from vamsasSeq section of XML for this sequence
2874 tmpSeq.setName(vamsasSeq[vi].getName());
2875 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2876 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2881 // reading multiple views, so vamsasSeq set is a subset of JSeq
2882 multipleView = true;
2884 tmpSeq.setStart(jseqs[i].getStart());
2885 tmpSeq.setEnd(jseqs[i].getEnd());
2886 tmpseqs.add(tmpSeq);
2890 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2891 vamsasSeq[vi].getSequence());
2892 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2893 tmpSeq.setStart(jseqs[i].getStart());
2894 tmpSeq.setEnd(jseqs[i].getEnd());
2895 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2896 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2897 tmpseqs.add(tmpSeq);
2901 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2903 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2906 if (jseqs[i].getHidden())
2908 if (hiddenSeqs == null)
2910 hiddenSeqs = new ArrayList<>();
2913 hiddenSeqs.add(tmpSeq);
2918 // Create the alignment object from the sequence set
2919 // ///////////////////////////////
2920 SequenceI[] orderedSeqs = tmpseqs
2921 .toArray(new SequenceI[tmpseqs.size()]);
2923 AlignmentI al = null;
2924 // so we must create or recover the dataset alignment before going further
2925 // ///////////////////////////////
2926 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2928 // older jalview projects do not have a dataset - so creat alignment and
2930 al = new Alignment(orderedSeqs);
2931 al.setDataset(null);
2935 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2938 // we are importing a dataset record, so
2939 // recover reference to an alignment already materialsed as dataset
2940 al = getDatasetFor(vamsasSet.getDatasetId());
2944 // materialse the alignment
2945 al = new Alignment(orderedSeqs);
2949 addDatasetRef(vamsasSet.getDatasetId(), al);
2952 // finally, verify all data in vamsasSet is actually present in al
2953 // passing on flag indicating if it is actually a stored dataset
2954 recoverDatasetFor(vamsasSet, al, isdsal);
2957 if (referenceseqForView != null)
2959 al.setSeqrep(referenceseqForView);
2961 // / Add the alignment properties
2962 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2964 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2965 al.setProperty(ssp.getKey(), ssp.getValue());
2968 // ///////////////////////////////
2970 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2973 // load sequence features, database references and any associated PDB
2974 // structures for the alignment
2976 // prior to 2.10, this part would only be executed the first time a
2977 // sequence was encountered, but not afterwards.
2978 // now, for 2.10 projects, this is also done if the xml doc includes
2979 // dataset sequences not actually present in any particular view.
2981 for (int i = 0; i < vamsasSeq.length; i++)
2983 if (jseqs[i].getFeaturesCount() > 0)
2985 Features[] features = jseqs[i].getFeatures();
2986 for (int f = 0; f < features.length; f++)
2988 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2989 features[f].getType(), features[f].getDescription(),
2990 features[f].getStatus(), features[f].getBegin(),
2991 features[f].getEnd(), features[f].getFeatureGroup());
2993 sf.setScore(features[f].getScore());
2994 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2996 OtherData keyValue = features[f].getOtherData(od);
2997 if (keyValue.getKey().startsWith("LINK"))
2999 sf.addLink(keyValue.getValue());
3003 sf.setValue(keyValue.getKey(), keyValue.getValue());
3007 // adds feature to datasequence's feature set (since Jalview 2.10)
3008 al.getSequenceAt(i).addSequenceFeature(sf);
3011 if (vamsasSeq[i].getDBRefCount() > 0)
3013 // adds dbrefs to datasequence's set (since Jalview 2.10)
3015 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
3016 : al.getSequenceAt(i).getDatasetSequence(),
3019 if (jseqs[i].getPdbidsCount() > 0)
3021 Pdbids[] ids = jseqs[i].getPdbids();
3022 for (int p = 0; p < ids.length; p++)
3024 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
3025 entry.setId(ids[p].getId());
3026 if (ids[p].getType() != null)
3028 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3030 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3034 entry.setType(PDBEntry.Type.FILE);
3037 // jprovider is null when executing 'New View'
3038 if (ids[p].getFile() != null && jprovider != null)
3040 if (!pdbloaded.containsKey(ids[p].getFile()))
3042 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3047 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3050 if (ids[p].getPdbentryItem() != null)
3052 for (PdbentryItem item : ids[p].getPdbentryItem())
3054 for (Property pr : item.getProperty())
3056 entry.setProperty(pr.getName(), pr.getValue());
3060 StructureSelectionManager.getStructureSelectionManager(
3061 Desktop.instance).registerPDBEntry(entry);
3062 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3063 if (al.getSequenceAt(i).getDatasetSequence() != null)
3065 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3069 al.getSequenceAt(i).addPDBId(entry);
3074 } // end !multipleview
3076 // ///////////////////////////////
3077 // LOAD SEQUENCE MAPPINGS
3079 if (vamsasSet.getAlcodonFrameCount() > 0)
3081 // TODO Potentially this should only be done once for all views of an
3083 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3084 for (int i = 0; i < alc.length; i++)
3086 AlignedCodonFrame cf = new AlignedCodonFrame();
3087 if (alc[i].getAlcodMapCount() > 0)
3089 AlcodMap[] maps = alc[i].getAlcodMap();
3090 for (int m = 0; m < maps.length; m++)
3092 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3094 jalview.datamodel.Mapping mapping = null;
3095 // attach to dna sequence reference.
3096 if (maps[m].getMapping() != null)
3098 mapping = addMapping(maps[m].getMapping());
3099 if (dnaseq != null && mapping.getTo() != null)
3101 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3106 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3111 al.addCodonFrame(cf);
3116 // ////////////////////////////////
3118 List<JvAnnotRow> autoAlan = new ArrayList<>();
3121 * store any annotations which forward reference a group's ID
3123 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<>();
3125 if (vamsasSet.getAnnotationCount() > 0)
3127 Annotation[] an = vamsasSet.getAnnotation();
3129 for (int i = 0; i < an.length; i++)
3131 Annotation annotation = an[i];
3134 * test if annotation is automatically calculated for this view only
3136 boolean autoForView = false;
3137 if (annotation.getLabel().equals("Quality")
3138 || annotation.getLabel().equals("Conservation")
3139 || annotation.getLabel().equals("Consensus"))
3141 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3143 if (!annotation.hasAutoCalculated())
3145 annotation.setAutoCalculated(true);
3149 || (annotation.hasAutoCalculated() && annotation
3150 .isAutoCalculated()))
3152 // remove ID - we don't recover annotation from other views for
3153 // view-specific annotation
3154 annotation.setId(null);
3157 // set visiblity for other annotation in this view
3158 String annotationId = annotation.getId();
3159 if (annotationId != null && annotationIds.containsKey(annotationId))
3161 AlignmentAnnotation jda = annotationIds.get(annotationId);
3162 // in principle Visible should always be true for annotation displayed
3163 // in multiple views
3164 if (annotation.hasVisible())
3166 jda.visible = annotation.getVisible();
3169 al.addAnnotation(jda);
3173 // Construct new annotation from model.
3174 AnnotationElement[] ae = annotation.getAnnotationElement();
3175 jalview.datamodel.Annotation[] anot = null;
3176 java.awt.Color firstColour = null;
3178 if (!annotation.getScoreOnly())
3180 anot = new jalview.datamodel.Annotation[al.getWidth()];
3181 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3183 anpos = ae[aa].getPosition();
3185 if (anpos >= anot.length)
3190 anot[anpos] = new jalview.datamodel.Annotation(
3192 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3193 (ae[aa].getSecondaryStructure() == null || ae[aa]
3194 .getSecondaryStructure().length() == 0) ? ' '
3195 : ae[aa].getSecondaryStructure().charAt(0),
3199 // JBPNote: Consider verifying dataflow for IO of secondary
3200 // structure annotation read from Stockholm files
3201 // this was added to try to ensure that
3202 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3204 // anot[ae[aa].getPosition()].displayCharacter = "";
3206 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3207 if (firstColour == null)
3209 firstColour = anot[anpos].colour;
3213 jalview.datamodel.AlignmentAnnotation jaa = null;
3215 if (annotation.getGraph())
3217 float llim = 0, hlim = 0;
3218 // if (autoForView || an[i].isAutoCalculated()) {
3221 jaa = new jalview.datamodel.AlignmentAnnotation(
3222 annotation.getLabel(), annotation.getDescription(), anot,
3223 llim, hlim, annotation.getGraphType());
3225 jaa.graphGroup = annotation.getGraphGroup();
3226 jaa._linecolour = firstColour;
3227 if (annotation.getThresholdLine() != null)
3229 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3230 .getThresholdLine().getValue(), annotation
3231 .getThresholdLine().getLabel(), new java.awt.Color(
3232 annotation.getThresholdLine().getColour())));
3235 if (autoForView || annotation.isAutoCalculated())
3237 // Hardwire the symbol display line to ensure that labels for
3238 // histograms are displayed
3244 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3245 an[i].getDescription(), anot);
3246 jaa._linecolour = firstColour;
3248 // register new annotation
3249 if (an[i].getId() != null)
3251 annotationIds.put(an[i].getId(), jaa);
3252 jaa.annotationId = an[i].getId();
3254 // recover sequence association
3255 String sequenceRef = an[i].getSequenceRef();
3256 if (sequenceRef != null)
3258 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3259 SequenceI sequence = seqRefIds.get(sequenceRef);
3260 if (sequence == null)
3262 // in pre-2.9 projects sequence ref is to sequence name
3263 sequence = al.findName(sequenceRef);
3265 if (sequence != null)
3267 jaa.createSequenceMapping(sequence, 1, true);
3268 sequence.addAlignmentAnnotation(jaa);
3271 // and make a note of any group association
3272 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3274 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3275 .get(an[i].getGroupRef());
3278 aal = new ArrayList<>();
3279 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3284 if (an[i].hasScore())
3286 jaa.setScore(an[i].getScore());
3288 if (an[i].hasVisible())
3290 jaa.visible = an[i].getVisible();
3293 if (an[i].hasCentreColLabels())
3295 jaa.centreColLabels = an[i].getCentreColLabels();
3298 if (an[i].hasScaleColLabels())
3300 jaa.scaleColLabel = an[i].getScaleColLabels();
3302 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3304 // newer files have an 'autoCalculated' flag and store calculation
3305 // state in viewport properties
3306 jaa.autoCalculated = true; // means annotation will be marked for
3307 // update at end of load.
3309 if (an[i].hasGraphHeight())
3311 jaa.graphHeight = an[i].getGraphHeight();
3313 if (an[i].hasBelowAlignment())
3315 jaa.belowAlignment = an[i].isBelowAlignment();
3317 jaa.setCalcId(an[i].getCalcId());
3318 if (an[i].getPropertyCount() > 0)
3320 for (jalview.schemabinding.version2.Property prop : an[i]
3323 jaa.setProperty(prop.getName(), prop.getValue());
3326 if (jaa.autoCalculated)
3328 autoAlan.add(new JvAnnotRow(i, jaa));
3331 // if (!autoForView)
3333 // add autocalculated group annotation and any user created annotation
3335 al.addAnnotation(jaa);
3339 // ///////////////////////
3341 // Create alignment markup and styles for this view
3342 if (jms.getJGroupCount() > 0)
3344 JGroup[] groups = jms.getJGroup();
3345 boolean addAnnotSchemeGroup = false;
3346 for (int i = 0; i < groups.length; i++)
3348 JGroup jGroup = groups[i];
3349 ColourSchemeI cs = null;
3350 if (jGroup.getColour() != null)
3352 if (jGroup.getColour().startsWith("ucs"))
3354 cs = getUserColourScheme(jms, jGroup.getColour());
3356 else if (jGroup.getColour().equals("AnnotationColourGradient")
3357 && jGroup.getAnnotationColours() != null)
3359 addAnnotSchemeGroup = true;
3363 cs = ColourSchemeProperty.getColourScheme(al, jGroup.getColour());
3366 int pidThreshold = jGroup.getPidThreshold();
3368 Vector<SequenceI> seqs = new Vector<>();
3370 for (int s = 0; s < jGroup.getSeqCount(); s++)
3372 String seqId = jGroup.getSeq(s) + "";
3373 SequenceI ts = seqRefIds.get(seqId);
3377 seqs.addElement(ts);
3381 if (seqs.size() < 1)
3386 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3387 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3388 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3389 sg.getGroupColourScheme().setThreshold(pidThreshold, true);
3390 sg.getGroupColourScheme().setConservationInc(jGroup.getConsThreshold());
3391 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3393 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3394 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3395 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3396 .isShowUnconserved() : false);
3397 sg.thresholdTextColour = jGroup.getTextColThreshold();
3398 if (jGroup.hasShowConsensusHistogram())
3400 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3403 if (jGroup.hasShowSequenceLogo())
3405 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3407 if (jGroup.hasNormaliseSequenceLogo())
3409 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3411 if (jGroup.hasIgnoreGapsinConsensus())
3413 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3415 if (jGroup.getConsThreshold() != 0)
3417 Conservation c = new Conservation("All", sg.getSequences(null),
3418 0, sg.getWidth() - 1);
3420 c.verdict(false, 25);
3421 sg.cs.setConservation(c);
3424 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3426 // re-instate unique group/annotation row reference
3427 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3431 for (AlignmentAnnotation jaa : jaal)
3434 if (jaa.autoCalculated)
3436 // match up and try to set group autocalc alignment row for this
3438 if (jaa.label.startsWith("Consensus for "))
3440 sg.setConsensus(jaa);
3442 // match up and try to set group autocalc alignment row for this
3444 if (jaa.label.startsWith("Conservation for "))
3446 sg.setConservationRow(jaa);
3453 if (addAnnotSchemeGroup)
3455 // reconstruct the annotation colourscheme
3456 sg.setColourScheme(constructAnnotationColour(
3457 jGroup.getAnnotationColours(), null, al, jms, false));
3463 // only dataset in this model, so just return.
3466 // ///////////////////////////////
3469 // If we just load in the same jar file again, the sequenceSetId
3470 // will be the same, and we end up with multiple references
3471 // to the same sequenceSet. We must modify this id on load
3472 // so that each load of the file gives a unique id
3473 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3474 String viewId = (view.getId() == null ? null : view.getId()
3476 AlignFrame af = null;
3477 AlignViewport av = null;
3478 // now check to see if we really need to create a new viewport.
3479 if (multipleView && viewportsAdded.size() == 0)
3481 // We recovered an alignment for which a viewport already exists.
3482 // TODO: fix up any settings necessary for overlaying stored state onto
3483 // state recovered from another document. (may not be necessary).
3484 // we may need a binding from a viewport in memory to one recovered from
3486 // and then recover its containing af to allow the settings to be applied.
3487 // TODO: fix for vamsas demo
3489 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3491 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3492 if (seqsetobj != null)
3494 if (seqsetobj instanceof String)
3496 uniqueSeqSetId = (String) seqsetobj;
3498 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3504 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3510 * indicate that annotation colours are applied across all groups (pre
3511 * Jalview 2.8.1 behaviour)
3513 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3514 "2.8.1", object.getVersion());
3516 AlignmentPanel ap = null;
3517 boolean isnewview = true;
3520 // Check to see if this alignment already has a view id == viewId
3521 jalview.gui.AlignmentPanel views[] = Desktop
3522 .getAlignmentPanels(uniqueSeqSetId);
3523 if (views != null && views.length > 0)
3525 for (int v = 0; v < views.length; v++)
3527 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3529 // recover the existing alignpanel, alignframe, viewport
3530 af = views[v].alignFrame;
3533 // TODO: could even skip resetting view settings if we don't want to
3534 // change the local settings from other jalview processes
3543 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3544 uniqueSeqSetId, viewId, autoAlan);
3550 * Load any trees, PDB structures and viewers
3552 * Not done if flag is false (when this method is used for New View)
3554 if (loadTreesAndStructures)
3556 loadTrees(jms, view, af, av, ap);
3557 loadPDBStructures(jprovider, jseqs, af, ap);
3558 loadRnaViewers(jprovider, jseqs, ap);
3560 // and finally return.
3565 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3566 * panel is restored from separate jar entries, two (gapped and trimmed) per
3567 * sequence and secondary structure.
3569 * Currently each viewer shows just one sequence and structure (gapped and
3570 * trimmed), however this method is designed to support multiple sequences or
3571 * structures in viewers if wanted in future.
3577 private void loadRnaViewers(jarInputStreamProvider jprovider,
3578 JSeq[] jseqs, AlignmentPanel ap)
3581 * scan the sequences for references to viewers; create each one the first
3582 * time it is referenced, add Rna models to existing viewers
3584 for (JSeq jseq : jseqs)
3586 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3588 RnaViewer viewer = jseq.getRnaViewer(i);
3589 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3590 uniqueSetSuffix, ap);
3592 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3594 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3595 SequenceI seq = seqRefIds.get(jseq.getId());
3596 AlignmentAnnotation ann = this.annotationIds.get(ss
3597 .getAnnotationId());
3600 * add the structure to the Varna display (with session state copied
3601 * from the jar to a temporary file)
3603 boolean gapped = ss.isGapped();
3604 String rnaTitle = ss.getTitle();
3605 String sessionState = ss.getViewerState();
3606 String tempStateFile = copyJarEntry(jprovider, sessionState,
3608 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3609 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3611 appVarna.setInitialSelection(viewer.getSelectedRna());
3617 * Locate and return an already instantiated matching AppVarna, or create one
3621 * @param viewIdSuffix
3625 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3626 String viewIdSuffix, AlignmentPanel ap)
3629 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3630 * if load is repeated
3632 String postLoadId = viewer.getViewId() + viewIdSuffix;
3633 for (JInternalFrame frame : getAllFrames())
3635 if (frame instanceof AppVarna)
3637 AppVarna varna = (AppVarna) frame;
3638 if (postLoadId.equals(varna.getViewId()))
3640 // this viewer is already instantiated
3641 // could in future here add ap as another 'parent' of the
3642 // AppVarna window; currently just 1-to-many
3649 * viewer not found - make it
3651 RnaViewerModel model = new RnaViewerModel(postLoadId,
3652 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3653 viewer.getWidth(), viewer.getHeight(),
3654 viewer.getDividerLocation());
3655 AppVarna varna = new AppVarna(model, ap);
3661 * Load any saved trees
3669 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3670 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3672 // TODO result of automated refactoring - are all these parameters needed?
3675 for (int t = 0; t < jms.getTreeCount(); t++)
3678 Tree tree = jms.getTree(t);
3680 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3683 tp = af.showNewickTree(
3684 new jalview.io.NewickFile(tree.getNewick()),
3685 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3686 tree.getXpos(), tree.getYpos());
3687 if (tree.getId() != null)
3689 // perhaps bind the tree id to something ?
3694 // update local tree attributes ?
3695 // TODO: should check if tp has been manipulated by user - if so its
3696 // settings shouldn't be modified
3697 tp.setTitle(tree.getTitle());
3698 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3699 .getWidth(), tree.getHeight()));
3700 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3703 tp.treeCanvas.av = av; // af.viewport;
3704 tp.treeCanvas.ap = ap; // af.alignPanel;
3709 warn("There was a problem recovering stored Newick tree: \n"
3710 + tree.getNewick());
3714 tp.fitToWindow.setState(tree.getFitToWindow());
3715 tp.fitToWindow_actionPerformed(null);
3717 if (tree.getFontName() != null)
3719 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3720 .getFontStyle(), tree.getFontSize()));
3724 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3725 .getFontStyle(), tree.getFontSize()));
3728 tp.showPlaceholders(tree.getMarkUnlinked());
3729 tp.showBootstrap(tree.getShowBootstrap());
3730 tp.showDistances(tree.getShowDistances());
3732 tp.treeCanvas.threshold = tree.getThreshold();
3734 if (tree.getCurrentTree())
3736 af.viewport.setCurrentTree(tp.getTree());
3740 } catch (Exception ex)
3742 ex.printStackTrace();
3747 * Load and link any saved structure viewers.
3754 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3755 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3758 * Run through all PDB ids on the alignment, and collect mappings between
3759 * distinct view ids and all sequences referring to that view.
3761 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<>();
3763 for (int i = 0; i < jseqs.length; i++)
3765 if (jseqs[i].getPdbidsCount() > 0)
3767 Pdbids[] ids = jseqs[i].getPdbids();
3768 for (int p = 0; p < ids.length; p++)
3770 final int structureStateCount = ids[p].getStructureStateCount();
3771 for (int s = 0; s < structureStateCount; s++)
3773 // check to see if we haven't already created this structure view
3774 final StructureState structureState = ids[p]
3775 .getStructureState(s);
3776 String sviewid = (structureState.getViewId() == null) ? null
3777 : structureState.getViewId() + uniqueSetSuffix;
3778 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3779 // Originally : ids[p].getFile()
3780 // : TODO: verify external PDB file recovery still works in normal
3781 // jalview project load
3782 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3784 jpdb.setId(ids[p].getId());
3786 int x = structureState.getXpos();
3787 int y = structureState.getYpos();
3788 int width = structureState.getWidth();
3789 int height = structureState.getHeight();
3791 // Probably don't need to do this anymore...
3792 // Desktop.desktop.getComponentAt(x, y);
3793 // TODO: NOW: check that this recovers the PDB file correctly.
3794 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3796 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3798 if (sviewid == null)
3800 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3803 if (!structureViewers.containsKey(sviewid))
3805 structureViewers.put(sviewid,
3806 new StructureViewerModel(x, y, width, height, false,
3807 false, true, structureState.getViewId(),
3808 structureState.getType()));
3809 // Legacy pre-2.7 conversion JAL-823 :
3810 // do not assume any view has to be linked for colour by
3814 // assemble String[] { pdb files }, String[] { id for each
3815 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3816 // seqs_file 2}, boolean[] {
3817 // linkAlignPanel,superposeWithAlignpanel}} from hash
3818 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3819 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3820 | (structureState.hasAlignwithAlignPanel() ? structureState
3821 .getAlignwithAlignPanel() : false));
3824 * Default colour by linked panel to false if not specified (e.g.
3825 * for pre-2.7 projects)
3827 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3828 colourWithAlignPanel |= (structureState
3829 .hasColourwithAlignPanel() ? structureState
3830 .getColourwithAlignPanel() : false);
3831 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3834 * Default colour by viewer to true if not specified (e.g. for
3837 boolean colourByViewer = jmoldat.isColourByViewer();
3838 colourByViewer &= structureState.hasColourByJmol() ? structureState
3839 .getColourByJmol() : true;
3840 jmoldat.setColourByViewer(colourByViewer);
3842 if (jmoldat.getStateData().length() < structureState
3843 .getContent().length())
3846 jmoldat.setStateData(structureState.getContent());
3849 if (ids[p].getFile() != null)
3851 File mapkey = new File(ids[p].getFile());
3852 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3853 if (seqstrmaps == null)
3855 jmoldat.getFileData().put(
3857 seqstrmaps = jmoldat.new StructureData(pdbFile,
3860 if (!seqstrmaps.getSeqList().contains(seq))
3862 seqstrmaps.getSeqList().add(seq);
3868 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");
3875 // Instantiate the associated structure views
3876 for (Entry<String, StructureViewerModel> entry : structureViewers
3881 createOrLinkStructureViewer(entry, af, ap, jprovider);
3882 } catch (Exception e)
3884 System.err.println("Error loading structure viewer: "
3886 // failed - try the next one
3898 protected void createOrLinkStructureViewer(
3899 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3900 AlignmentPanel ap, jarInputStreamProvider jprovider)
3902 final StructureViewerModel stateData = viewerData.getValue();
3905 * Search for any viewer windows already open from other alignment views
3906 * that exactly match the stored structure state
3908 StructureViewerBase comp = findMatchingViewer(viewerData);
3912 linkStructureViewer(ap, comp, stateData);
3917 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3918 * "viewer_"+stateData.viewId
3920 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3922 createChimeraViewer(viewerData, af, jprovider);
3927 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3929 createJmolViewer(viewerData, af, jprovider);
3934 * Create a new Chimera viewer.
3940 protected void createChimeraViewer(
3941 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3942 jarInputStreamProvider jprovider)
3944 StructureViewerModel data = viewerData.getValue();
3945 String chimeraSessionFile = data.getStateData();
3948 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3950 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3951 * 'uniquified' sviewid used to reconstruct the viewer here
3953 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3954 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3957 Set<Entry<File, StructureData>> fileData = data.getFileData()
3959 List<PDBEntry> pdbs = new ArrayList<>();
3960 List<SequenceI[]> allseqs = new ArrayList<>();
3961 for (Entry<File, StructureData> pdb : fileData)
3963 String filePath = pdb.getValue().getFilePath();
3964 String pdbId = pdb.getValue().getPdbId();
3965 // pdbs.add(new PDBEntry(filePath, pdbId));
3966 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3967 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3968 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3972 boolean colourByChimera = data.isColourByViewer();
3973 boolean colourBySequence = data.isColourWithAlignPanel();
3975 // TODO use StructureViewer as a factory here, see JAL-1761
3976 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3977 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3979 String newViewId = viewerData.getKey();
3981 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3982 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3983 colourBySequence, newViewId);
3984 cvf.setSize(data.getWidth(), data.getHeight());
3985 cvf.setLocation(data.getX(), data.getY());
3989 * Create a new Jmol window. First parse the Jmol state to translate filenames
3990 * loaded into the view, and record the order in which files are shown in the
3991 * Jmol view, so we can add the sequence mappings in same order.
3997 protected void createJmolViewer(
3998 final Entry<String, StructureViewerModel> viewerData,
3999 AlignFrame af, jarInputStreamProvider jprovider)
4001 final StructureViewerModel svattrib = viewerData.getValue();
4002 String state = svattrib.getStateData();
4005 * Pre-2.9: state element value is the Jmol state string
4007 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
4010 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
4012 state = readJarEntry(jprovider,
4013 getViewerJarEntryName(svattrib.getViewId()));
4016 List<String> pdbfilenames = new ArrayList<>();
4017 List<SequenceI[]> seqmaps = new ArrayList<>();
4018 List<String> pdbids = new ArrayList<>();
4019 StringBuilder newFileLoc = new StringBuilder(64);
4020 int cp = 0, ncp, ecp;
4021 Map<File, StructureData> oldFiles = svattrib.getFileData();
4022 while ((ncp = state.indexOf("load ", cp)) > -1)
4026 // look for next filename in load statement
4027 newFileLoc.append(state.substring(cp,
4028 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4029 String oldfilenam = state.substring(ncp,
4030 ecp = state.indexOf("\"", ncp));
4031 // recover the new mapping data for this old filename
4032 // have to normalize filename - since Jmol and jalview do
4034 // translation differently.
4035 StructureData filedat = oldFiles.get(new File(oldfilenam));
4036 if (filedat == null)
4038 String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
4039 filedat = oldFiles.get(new File(reformatedOldFilename));
4041 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4042 pdbfilenames.add(filedat.getFilePath());
4043 pdbids.add(filedat.getPdbId());
4044 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4045 newFileLoc.append("\"");
4046 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4047 // look for next file statement.
4048 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4052 // just append rest of state
4053 newFileLoc.append(state.substring(cp));
4057 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4058 newFileLoc = new StringBuilder(state);
4059 newFileLoc.append("; load append ");
4060 for (File id : oldFiles.keySet())
4062 // add this and any other pdb files that should be present in
4064 StructureData filedat = oldFiles.get(id);
4065 newFileLoc.append(filedat.getFilePath());
4066 pdbfilenames.add(filedat.getFilePath());
4067 pdbids.add(filedat.getPdbId());
4068 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4069 newFileLoc.append(" \"");
4070 newFileLoc.append(filedat.getFilePath());
4071 newFileLoc.append("\"");
4074 newFileLoc.append(";");
4077 if (newFileLoc.length() == 0)
4081 int histbug = newFileLoc.indexOf("history = ");
4085 * change "history = [true|false];" to "history = [1|0];"
4088 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4089 String val = (diff == -1) ? null : newFileLoc
4090 .substring(histbug, diff);
4091 if (val != null && val.length() >= 4)
4093 if (val.contains("e")) // eh? what can it be?
4095 if (val.trim().equals("true"))
4103 newFileLoc.replace(histbug, diff, val);
4108 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4110 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4111 final SequenceI[][] sq = seqmaps
4112 .toArray(new SequenceI[seqmaps.size()][]);
4113 final String fileloc = newFileLoc.toString();
4114 final String sviewid = viewerData.getKey();
4115 final AlignFrame alf = af;
4116 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4117 svattrib.getWidth(), svattrib.getHeight());
4120 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4125 JalviewStructureDisplayI sview = null;
4128 sview = new StructureViewer(alf.alignPanel
4129 .getStructureSelectionManager()).createView(
4130 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4131 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4132 addNewStructureViewer(sview);
4133 } catch (OutOfMemoryError ex)
4135 new OOMWarning("restoring structure view for PDB id " + id,
4136 (OutOfMemoryError) ex.getCause());
4137 if (sview != null && sview.isVisible())
4139 sview.closeViewer(false);
4140 sview.setVisible(false);
4146 } catch (InvocationTargetException ex)
4148 warn("Unexpected error when opening Jmol view.", ex);
4150 } catch (InterruptedException e)
4152 // e.printStackTrace();
4158 * Generates a name for the entry in the project jar file to hold state
4159 * information for a structure viewer
4164 protected String getViewerJarEntryName(String viewId)
4166 return VIEWER_PREFIX + viewId;
4170 * Returns any open frame that matches given structure viewer data. The match
4171 * is based on the unique viewId, or (for older project versions) the frame's
4177 protected StructureViewerBase findMatchingViewer(
4178 Entry<String, StructureViewerModel> viewerData)
4180 final String sviewid = viewerData.getKey();
4181 final StructureViewerModel svattrib = viewerData.getValue();
4182 StructureViewerBase comp = null;
4183 JInternalFrame[] frames = getAllFrames();
4184 for (JInternalFrame frame : frames)
4186 if (frame instanceof StructureViewerBase)
4189 * Post jalview 2.4 schema includes structure view id
4192 && ((StructureViewerBase) frame).getViewId()
4195 comp = (StructureViewerBase) frame;
4196 break; // break added in 2.9
4199 * Otherwise test for matching position and size of viewer frame
4201 else if (frame.getX() == svattrib.getX()
4202 && frame.getY() == svattrib.getY()
4203 && frame.getHeight() == svattrib.getHeight()
4204 && frame.getWidth() == svattrib.getWidth())
4206 comp = (StructureViewerBase) frame;
4207 // no break in faint hope of an exact match on viewId
4215 * Link an AlignmentPanel to an existing structure viewer.
4220 * @param useinViewerSuperpos
4221 * @param usetoColourbyseq
4222 * @param viewerColouring
4224 protected void linkStructureViewer(AlignmentPanel ap,
4225 StructureViewerBase viewer, StructureViewerModel stateData)
4227 // NOTE: if the jalview project is part of a shared session then
4228 // view synchronization should/could be done here.
4230 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4231 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4232 final boolean viewerColouring = stateData.isColourByViewer();
4233 Map<File, StructureData> oldFiles = stateData.getFileData();
4236 * Add mapping for sequences in this view to an already open viewer
4238 final AAStructureBindingModel binding = viewer.getBinding();
4239 for (File id : oldFiles.keySet())
4241 // add this and any other pdb files that should be present in the
4243 StructureData filedat = oldFiles.get(id);
4244 String pdbFile = filedat.getFilePath();
4245 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4246 binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE);
4247 binding.addSequenceForStructFile(pdbFile, seq);
4249 // and add the AlignmentPanel's reference to the view panel
4250 viewer.addAlignmentPanel(ap);
4251 if (useinViewerSuperpos)
4253 viewer.useAlignmentPanelForSuperposition(ap);
4257 viewer.excludeAlignmentPanelForSuperposition(ap);
4259 if (usetoColourbyseq)
4261 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4265 viewer.excludeAlignmentPanelForColourbyseq(ap);
4270 * Get all frames within the Desktop.
4274 protected JInternalFrame[] getAllFrames()
4276 JInternalFrame[] frames = null;
4277 // TODO is this necessary - is it safe - risk of hanging?
4282 frames = Desktop.desktop.getAllFrames();
4283 } catch (ArrayIndexOutOfBoundsException e)
4285 // occasional No such child exceptions are thrown here...
4289 } catch (InterruptedException f)
4293 } while (frames == null);
4298 * Answers true if 'version' is equal to or later than 'supported', where each
4299 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4300 * changes. Development and test values for 'version' are leniently treated
4304 * - minimum version we are comparing against
4306 * - version of data being processsed
4309 public static boolean isVersionStringLaterThan(String supported,
4312 if (supported == null || version == null
4313 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4314 || version.equalsIgnoreCase("Test")
4315 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4317 System.err.println("Assuming project file with "
4318 + (version == null ? "null" : version)
4319 + " is compatible with Jalview version " + supported);
4324 return StringUtils.compareVersions(version, supported, "b") >= 0;
4328 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4330 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4332 if (newStructureViewers != null)
4334 sview.getBinding().setFinishedLoadingFromArchive(false);
4335 newStructureViewers.add(sview);
4339 protected void setLoadingFinishedForNewStructureViewers()
4341 if (newStructureViewers != null)
4343 for (JalviewStructureDisplayI sview : newStructureViewers)
4345 sview.getBinding().setFinishedLoadingFromArchive(true);
4347 newStructureViewers.clear();
4348 newStructureViewers = null;
4352 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4353 List<SequenceI> hiddenSeqs, AlignmentI al,
4354 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4355 String viewId, List<JvAnnotRow> autoAlan)
4357 AlignFrame af = null;
4358 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4359 uniqueSeqSetId, viewId);
4361 af.setFileName(file, FileFormat.Jalview);
4363 for (int i = 0; i < JSEQ.length; i++)
4365 af.viewport.setSequenceColour(af.viewport.getAlignment()
4366 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4371 af.getViewport().setColourByReferenceSeq(true);
4372 af.getViewport().setDisplayReferenceSeq(true);
4375 af.viewport.setGatherViewsHere(view.getGatheredViews());
4377 if (view.getSequenceSetId() != null)
4379 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4381 af.viewport.setSequenceSetId(uniqueSeqSetId);
4384 // propagate shared settings to this new view
4385 af.viewport.setHistoryList(av.getHistoryList());
4386 af.viewport.setRedoList(av.getRedoList());
4390 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4392 // TODO: check if this method can be called repeatedly without
4393 // side-effects if alignpanel already registered.
4394 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4396 // apply Hidden regions to view.
4397 if (hiddenSeqs != null)
4399 for (int s = 0; s < JSEQ.length; s++)
4401 SequenceGroup hidden = new SequenceGroup();
4402 boolean isRepresentative = false;
4403 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4405 isRepresentative = true;
4406 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4407 .getHiddenSequences(r));
4408 hidden.addSequence(sequenceToHide, false);
4409 // remove from hiddenSeqs list so we don't try to hide it twice
4410 hiddenSeqs.remove(sequenceToHide);
4412 if (isRepresentative)
4414 SequenceI representativeSequence = al.getSequenceAt(s);
4415 hidden.addSequence(representativeSequence, false);
4416 af.viewport.hideRepSequences(representativeSequence, hidden);
4420 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4422 af.viewport.hideSequence(hseqs);
4425 // recover view properties and display parameters
4426 if (view.getViewName() != null)
4428 af.viewport.viewName = view.getViewName();
4429 af.setInitialTabVisible();
4431 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4434 af.viewport.setShowAnnotation(view.getShowAnnotation());
4435 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4436 af.viewport.setThreshold(view.getPidThreshold());
4438 af.viewport.setColourText(view.getShowColourText());
4440 af.viewport.setConservationSelected(view.getConservationSelected());
4441 af.viewport.setIncrement(view.getConsThreshold());
4442 af.viewport.setShowJVSuffix(view.getShowFullId());
4443 af.viewport.setRightAlignIds(view.getRightAlignIds());
4444 af.viewport.setFont(
4445 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4446 .getFontSize()), true);
4447 ViewStyleI vs = af.viewport.getViewStyle();
4448 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4449 af.viewport.setViewStyle(vs);
4450 // TODO: allow custom charWidth/Heights to be restored by updating them
4451 // after setting font - which means set above to false
4452 af.viewport.setRenderGaps(view.getRenderGaps());
4453 af.viewport.setWrapAlignment(view.getWrapAlignment());
4454 af.viewport.setShowAnnotation(view.getShowAnnotation());
4456 af.viewport.setShowBoxes(view.getShowBoxes());
4458 af.viewport.setShowText(view.getShowText());
4460 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4461 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4462 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4463 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4464 .isShowUnconserved() : false);
4465 af.viewport.getRanges().setStartRes(view.getStartRes());
4466 // startSeq set in af.alignPanel.updateLayout below
4467 af.alignPanel.updateLayout();
4468 ColourSchemeI cs = null;
4469 // apply colourschemes
4470 if (view.getBgColour() != null)
4472 if (view.getBgColour().startsWith("ucs"))
4474 cs = getUserColourScheme(jms, view.getBgColour());
4476 else if (view.getBgColour().startsWith("Annotation"))
4478 AnnotationColours viewAnnColour = view.getAnnotationColours();
4479 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4486 cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour());
4490 af.viewport.setGlobalColourScheme(cs);
4491 af.viewport.getResidueShading().setThreshold(
4492 view.getPidThreshold(), true);
4493 af.viewport.getResidueShading().setConsensus(
4494 af.viewport.getSequenceConsensusHash());
4495 af.viewport.setColourAppliesToAllGroups(false);
4497 if (view.getConservationSelected() && cs != null)
4499 af.viewport.getResidueShading().setConservationInc(
4500 view.getConsThreshold());
4503 af.changeColour(cs);
4505 af.viewport.setColourAppliesToAllGroups(true);
4507 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4509 if (view.hasCentreColumnLabels())
4511 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4513 if (view.hasIgnoreGapsinConsensus())
4515 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4518 if (view.hasFollowHighlight())
4520 af.viewport.setFollowHighlight(view.getFollowHighlight());
4522 if (view.hasFollowSelection())
4524 af.viewport.followSelection = view.getFollowSelection();
4526 if (view.hasShowConsensusHistogram())
4528 af.viewport.setShowConsensusHistogram(view
4529 .getShowConsensusHistogram());
4533 af.viewport.setShowConsensusHistogram(true);
4535 if (view.hasShowSequenceLogo())
4537 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4541 af.viewport.setShowSequenceLogo(false);
4543 if (view.hasNormaliseSequenceLogo())
4545 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4547 if (view.hasShowDbRefTooltip())
4549 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4551 if (view.hasShowNPfeatureTooltip())
4553 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4555 if (view.hasShowGroupConsensus())
4557 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4561 af.viewport.setShowGroupConsensus(false);
4563 if (view.hasShowGroupConservation())
4565 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4569 af.viewport.setShowGroupConservation(false);
4572 // recover featre settings
4573 if (jms.getFeatureSettings() != null)
4575 FeaturesDisplayed fdi;
4576 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4577 String[] renderOrder = new String[jms.getFeatureSettings()
4578 .getSettingCount()];
4579 Map<String, FeatureColourI> featureColours = new Hashtable<>();
4580 Map<String, Float> featureOrder = new Hashtable<>();
4582 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4584 Setting setting = jms.getFeatureSettings().getSetting(fs);
4585 if (setting.hasMincolour())
4587 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4588 new Color(setting.getMincolour()), new Color(
4589 setting.getColour()), setting.getMin(),
4590 setting.getMax()) : new FeatureColour(new Color(
4591 setting.getMincolour()), new Color(setting.getColour()),
4593 if (setting.hasThreshold())
4595 gc.setThreshold(setting.getThreshold());
4596 int threshstate = setting.getThreshstate();
4597 // -1 = None, 0 = Below, 1 = Above threshold
4598 if (threshstate == 0)
4600 gc.setBelowThreshold(true);
4602 else if (threshstate == 1)
4604 gc.setAboveThreshold(true);
4607 gc.setAutoScaled(true); // default
4608 if (setting.hasAutoScale())
4610 gc.setAutoScaled(setting.getAutoScale());
4612 if (setting.hasColourByLabel())
4614 gc.setColourByLabel(setting.getColourByLabel());
4616 // and put in the feature colour table.
4617 featureColours.put(setting.getType(), gc);
4621 featureColours.put(setting.getType(), new FeatureColour(
4622 new Color(setting.getColour())));
4624 renderOrder[fs] = setting.getType();
4625 if (setting.hasOrder())
4627 featureOrder.put(setting.getType(), setting.getOrder());
4631 featureOrder.put(setting.getType(), new Float(fs
4632 / jms.getFeatureSettings().getSettingCount()));
4634 if (setting.getDisplay())
4636 fdi.setVisible(setting.getType());
4639 Map<String, Boolean> fgtable = new Hashtable<>();
4640 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4642 Group grp = jms.getFeatureSettings().getGroup(gs);
4643 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4645 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4646 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4647 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4648 FeatureRendererSettings frs = new FeatureRendererSettings(
4649 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4650 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4651 .transferSettings(frs);
4655 if (view.getHiddenColumnsCount() > 0)
4657 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4659 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4660 .getHiddenColumns(c).getEnd() // +1
4664 if (view.getCalcIdParam() != null)
4666 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4668 if (calcIdParam != null)
4670 if (recoverCalcIdParam(calcIdParam, af.viewport))
4675 warn("Couldn't recover parameters for "
4676 + calcIdParam.getCalcId());
4681 af.setMenusFromViewport(af.viewport);
4682 af.setTitle(view.getTitle());
4683 // TODO: we don't need to do this if the viewport is aready visible.
4685 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4686 * has a 'cdna/protein complement' view, in which case save it in order to
4687 * populate a SplitFrame once all views have been read in.
4689 String complementaryViewId = view.getComplementId();
4690 if (complementaryViewId == null)
4692 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4694 // recompute any autoannotation
4695 af.alignPanel.updateAnnotation(false, true);
4696 reorderAutoannotation(af, al, autoAlan);
4697 af.alignPanel.alignmentChanged();
4701 splitFrameCandidates.put(view, af);
4707 * Reads saved data to restore Colour by Annotation settings
4709 * @param viewAnnColour
4713 * @param checkGroupAnnColour
4716 private ColourSchemeI constructAnnotationColour(
4717 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4718 JalviewModelSequence jms, boolean checkGroupAnnColour)
4720 boolean propagateAnnColour = false;
4721 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4722 if (checkGroupAnnColour && al.getGroups() != null
4723 && al.getGroups().size() > 0)
4725 // pre 2.8.1 behaviour
4726 // check to see if we should transfer annotation colours
4727 propagateAnnColour = true;
4728 for (SequenceGroup sg : al.getGroups())
4730 if (sg.getColourScheme() instanceof AnnotationColourGradient)
4732 propagateAnnColour = false;
4738 * 2.10.2- : saved annotationId is AlignmentAnnotation.annotationId
4740 String annotationId = viewAnnColour.getAnnotation();
4741 AlignmentAnnotation matchedAnnotation = annotationIds.get(annotationId);
4744 * pre 2.10.2: saved annotationId is AlignmentAnnotation.label
4746 if (matchedAnnotation == null && annAlignment.getAlignmentAnnotation() != null)
4748 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4751 .equals(annAlignment.getAlignmentAnnotation()[i].label))
4753 matchedAnnotation = annAlignment.getAlignmentAnnotation()[i];
4758 if (matchedAnnotation == null)
4760 System.err.println("Failed to match annotation colour scheme for "
4764 if (matchedAnnotation.getThreshold() == null)
4766 matchedAnnotation.setThreshold(new GraphLine(viewAnnColour.getThreshold(),
4767 "Threshold", Color.black));
4770 AnnotationColourGradient cs = null;
4771 if (viewAnnColour.getColourScheme().equals("None"))
4773 cs = new AnnotationColourGradient(matchedAnnotation, new Color(
4774 viewAnnColour.getMinColour()), new Color(
4775 viewAnnColour.getMaxColour()),
4776 viewAnnColour.getAboveThreshold());
4778 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4780 cs = new AnnotationColourGradient(matchedAnnotation, getUserColourScheme(
4781 jms, viewAnnColour.getColourScheme()),
4782 viewAnnColour.getAboveThreshold());
4786 cs = new AnnotationColourGradient(matchedAnnotation,
4787 ColourSchemeProperty.getColourScheme(al,
4788 viewAnnColour.getColourScheme()),
4789 viewAnnColour.getAboveThreshold());
4792 boolean perSequenceOnly = viewAnnColour.isPerSequence();
4793 boolean useOriginalColours = viewAnnColour.isPredefinedColours();
4794 cs.setSeqAssociated(perSequenceOnly);
4795 cs.setPredefinedColours(useOriginalColours);
4797 if (propagateAnnColour && al.getGroups() != null)
4799 // Also use these settings for all the groups
4800 for (int g = 0; g < al.getGroups().size(); g++)
4802 SequenceGroup sg = al.getGroups().get(g);
4803 if (sg.getGroupColourScheme() == null)
4808 AnnotationColourGradient groupScheme = new AnnotationColourGradient(
4809 matchedAnnotation, sg.getColourScheme(),
4810 viewAnnColour.getAboveThreshold());
4811 sg.setColourScheme(groupScheme);
4812 groupScheme.setSeqAssociated(perSequenceOnly);
4813 groupScheme.setPredefinedColours(useOriginalColours);
4819 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4820 List<JvAnnotRow> autoAlan)
4822 // copy over visualization settings for autocalculated annotation in the
4824 if (al.getAlignmentAnnotation() != null)
4827 * Kludge for magic autoannotation names (see JAL-811)
4829 String[] magicNames = new String[] { "Consensus", "Quality",
4831 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4832 Hashtable<String, JvAnnotRow> visan = new Hashtable<>();
4833 for (String nm : magicNames)
4835 visan.put(nm, nullAnnot);
4837 for (JvAnnotRow auan : autoAlan)
4839 visan.put(auan.template.label
4840 + (auan.template.getCalcId() == null ? "" : "\t"
4841 + auan.template.getCalcId()), auan);
4843 int hSize = al.getAlignmentAnnotation().length;
4844 List<JvAnnotRow> reorder = new ArrayList<>();
4845 // work through any autoCalculated annotation already on the view
4846 // removing it if it should be placed in a different location on the
4847 // annotation panel.
4848 List<String> remains = new ArrayList<>(visan.keySet());
4849 for (int h = 0; h < hSize; h++)
4851 jalview.datamodel.AlignmentAnnotation jalan = al
4852 .getAlignmentAnnotation()[h];
4853 if (jalan.autoCalculated)
4856 JvAnnotRow valan = visan.get(k = jalan.label);
4857 if (jalan.getCalcId() != null)
4859 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4864 // delete the auto calculated row from the alignment
4865 al.deleteAnnotation(jalan, false);
4869 if (valan != nullAnnot)
4871 if (jalan != valan.template)
4873 // newly created autoannotation row instance
4874 // so keep a reference to the visible annotation row
4875 // and copy over all relevant attributes
4876 if (valan.template.graphHeight >= 0)
4879 jalan.graphHeight = valan.template.graphHeight;
4881 jalan.visible = valan.template.visible;
4883 reorder.add(new JvAnnotRow(valan.order, jalan));
4888 // Add any (possibly stale) autocalculated rows that were not appended to
4889 // the view during construction
4890 for (String other : remains)
4892 JvAnnotRow othera = visan.get(other);
4893 if (othera != nullAnnot && othera.template.getCalcId() != null
4894 && othera.template.getCalcId().length() > 0)
4896 reorder.add(othera);
4899 // now put the automatic annotation in its correct place
4900 int s = 0, srt[] = new int[reorder.size()];
4901 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4902 for (JvAnnotRow jvar : reorder)
4905 srt[s++] = jvar.order;
4908 jalview.util.QuickSort.sort(srt, rws);
4909 // and re-insert the annotation at its correct position
4910 for (JvAnnotRow jvar : rws)
4912 al.addAnnotation(jvar.template, jvar.order);
4914 af.alignPanel.adjustAnnotationHeight();
4918 Hashtable skipList = null;
4921 * TODO remove this method
4924 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4925 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4926 * throw new Error("Implementation Error. No skipList defined for this
4927 * Jalview2XML instance."); } return (AlignFrame)
4928 * skipList.get(view.getSequenceSetId()); }
4932 * Check if the Jalview view contained in object should be skipped or not.
4935 * @return true if view's sequenceSetId is a key in skipList
4937 private boolean skipViewport(JalviewModel object)
4939 if (skipList == null)
4944 if (skipList.containsKey(id = object.getJalviewModelSequence()
4945 .getViewport()[0].getSequenceSetId()))
4947 if (Cache.log != null && Cache.log.isDebugEnabled())
4949 Cache.log.debug("Skipping seuqence set id " + id);
4956 public void addToSkipList(AlignFrame af)
4958 if (skipList == null)
4960 skipList = new Hashtable();
4962 skipList.put(af.getViewport().getSequenceSetId(), af);
4965 public void clearSkipList()
4967 if (skipList != null)
4974 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4975 boolean ignoreUnrefed)
4977 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4979 Vector dseqs = null;
4982 // create a list of new dataset sequences
4983 dseqs = new Vector();
4985 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4987 Sequence vamsasSeq = vamsasSet.getSequence(i);
4988 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4990 // create a new dataset
4993 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4994 dseqs.copyInto(dsseqs);
4995 ds = new jalview.datamodel.Alignment(dsseqs);
4996 debug("Created new dataset " + vamsasSet.getDatasetId()
4997 + " for alignment " + System.identityHashCode(al));
4998 addDatasetRef(vamsasSet.getDatasetId(), ds);
5000 // set the dataset for the newly imported alignment.
5001 if (al.getDataset() == null && !ignoreUnrefed)
5010 * sequence definition to create/merge dataset sequence for
5014 * vector to add new dataset sequence to
5015 * @param ignoreUnrefed
5016 * - when true, don't create new sequences from vamsasSeq if it's id
5017 * doesn't already have an asssociated Jalview sequence.
5019 * - used to reorder the sequence in the alignment according to the
5020 * vamsasSeq array ordering, to preserve ordering of dataset
5022 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5023 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5025 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5027 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5028 boolean reorder = false;
5029 SequenceI dsq = null;
5030 if (sq != null && sq.getDatasetSequence() != null)
5032 dsq = sq.getDatasetSequence();
5038 if (sq == null && ignoreUnrefed)
5042 String sqid = vamsasSeq.getDsseqid();
5045 // need to create or add a new dataset sequence reference to this sequence
5048 dsq = seqRefIds.get(sqid);
5053 // make a new dataset sequence
5054 dsq = sq.createDatasetSequence();
5057 // make up a new dataset reference for this sequence
5058 sqid = seqHash(dsq);
5060 dsq.setVamsasId(uniqueSetSuffix + sqid);
5061 seqRefIds.put(sqid, dsq);
5066 dseqs.addElement(dsq);
5071 ds.addSequence(dsq);
5077 { // make this dataset sequence sq's dataset sequence
5078 sq.setDatasetSequence(dsq);
5079 // and update the current dataset alignment
5084 if (!dseqs.contains(dsq))
5091 if (ds.findIndex(dsq) < 0)
5093 ds.addSequence(dsq);
5100 // TODO: refactor this as a merge dataset sequence function
5101 // now check that sq (the dataset sequence) sequence really is the union of
5102 // all references to it
5103 // boolean pre = sq.getStart() < dsq.getStart();
5104 // boolean post = sq.getEnd() > dsq.getEnd();
5108 // StringBuffer sb = new StringBuffer();
5109 String newres = jalview.analysis.AlignSeq.extractGaps(
5110 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5111 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5112 && newres.length() > dsq.getLength())
5114 // Update with the longer sequence.
5118 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5119 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5120 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5121 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5123 dsq.setSequence(newres);
5125 // TODO: merges will never happen if we 'know' we have the real dataset
5126 // sequence - this should be detected when id==dssid
5128 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5129 // + (pre ? "prepended" : "") + " "
5130 // + (post ? "appended" : ""));
5135 // sequence refs are identical. We may need to update the existing dataset
5136 // alignment with this one, though.
5137 if (ds != null && dseqs == null)
5139 int opos = ds.findIndex(dsq);
5140 SequenceI tseq = null;
5141 if (opos != -1 && vseqpos != opos)
5143 // remove from old position
5144 ds.deleteSequence(dsq);
5146 if (vseqpos < ds.getHeight())
5148 if (vseqpos != opos)
5150 // save sequence at destination position
5151 tseq = ds.getSequenceAt(vseqpos);
5152 ds.replaceSequenceAt(vseqpos, dsq);
5153 ds.addSequence(tseq);
5158 ds.addSequence(dsq);
5165 * TODO use AlignmentI here and in related methods - needs
5166 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5168 Hashtable<String, AlignmentI> datasetIds = null;
5170 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5172 private AlignmentI getDatasetFor(String datasetId)
5174 if (datasetIds == null)
5176 datasetIds = new Hashtable<>();
5179 if (datasetIds.containsKey(datasetId))
5181 return datasetIds.get(datasetId);
5186 private void addDatasetRef(String datasetId, AlignmentI dataset)
5188 if (datasetIds == null)
5190 datasetIds = new Hashtable<>();
5192 datasetIds.put(datasetId, dataset);
5196 * make a new dataset ID for this jalview dataset alignment
5201 private String getDatasetIdRef(AlignmentI dataset)
5203 if (dataset.getDataset() != null)
5205 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5207 String datasetId = makeHashCode(dataset, null);
5208 if (datasetId == null)
5210 // make a new datasetId and record it
5211 if (dataset2Ids == null)
5213 dataset2Ids = new IdentityHashMap<>();
5217 datasetId = dataset2Ids.get(dataset);
5219 if (datasetId == null)
5221 datasetId = "ds" + dataset2Ids.size() + 1;
5222 dataset2Ids.put(dataset, datasetId);
5228 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5230 for (int d = 0; d < sequence.getDBRefCount(); d++)
5232 DBRef dr = sequence.getDBRef(d);
5233 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5234 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5235 .getVersion(), sequence.getDBRef(d).getAccessionId());
5236 if (dr.getMapping() != null)
5238 entry.setMap(addMapping(dr.getMapping()));
5240 datasetSequence.addDBRef(entry);
5244 private jalview.datamodel.Mapping addMapping(Mapping m)
5246 SequenceI dsto = null;
5247 // Mapping m = dr.getMapping();
5248 int fr[] = new int[m.getMapListFromCount() * 2];
5249 Enumeration f = m.enumerateMapListFrom();
5250 for (int _i = 0; f.hasMoreElements(); _i += 2)
5252 MapListFrom mf = (MapListFrom) f.nextElement();
5253 fr[_i] = mf.getStart();
5254 fr[_i + 1] = mf.getEnd();
5256 int fto[] = new int[m.getMapListToCount() * 2];
5257 f = m.enumerateMapListTo();
5258 for (int _i = 0; f.hasMoreElements(); _i += 2)
5260 MapListTo mf = (MapListTo) f.nextElement();
5261 fto[_i] = mf.getStart();
5262 fto[_i + 1] = mf.getEnd();
5264 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5265 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5266 if (m.getMappingChoice() != null)
5268 MappingChoice mc = m.getMappingChoice();
5269 if (mc.getDseqFor() != null)
5271 String dsfor = "" + mc.getDseqFor();
5272 if (seqRefIds.containsKey(dsfor))
5277 jmap.setTo(seqRefIds.get(dsfor));
5281 frefedSequence.add(newMappingRef(dsfor, jmap));
5287 * local sequence definition
5289 Sequence ms = mc.getSequence();
5290 SequenceI djs = null;
5291 String sqid = ms.getDsseqid();
5292 if (sqid != null && sqid.length() > 0)
5295 * recover dataset sequence
5297 djs = seqRefIds.get(sqid);
5302 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5303 sqid = ((Object) ms).toString(); // make up a new hascode for
5304 // undefined dataset sequence hash
5305 // (unlikely to happen)
5311 * make a new dataset sequence and add it to refIds hash
5313 djs = new jalview.datamodel.Sequence(ms.getName(),
5315 djs.setStart(jmap.getMap().getToLowest());
5316 djs.setEnd(jmap.getMap().getToHighest());
5317 djs.setVamsasId(uniqueSetSuffix + sqid);
5319 incompleteSeqs.put(sqid, djs);
5320 seqRefIds.put(sqid, djs);
5323 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5332 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5333 boolean keepSeqRefs)
5336 JalviewModel jm = saveState(ap, null, null, null);
5341 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5345 uniqueSetSuffix = "";
5346 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5351 if (this.frefedSequence == null)
5353 frefedSequence = new Vector();
5356 viewportsAdded.clear();
5358 AlignFrame af = loadFromObject(jm, null, false, null);
5359 af.alignPanels.clear();
5360 af.closeMenuItem_actionPerformed(true);
5363 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5364 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5365 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5366 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5367 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5370 return af.alignPanel;
5374 * flag indicating if hashtables should be cleared on finalization TODO this
5375 * flag may not be necessary
5377 private final boolean _cleartables = true;
5379 private Hashtable jvids2vobj;
5384 * @see java.lang.Object#finalize()
5387 protected void finalize() throws Throwable
5389 // really make sure we have no buried refs left.
5394 this.seqRefIds = null;
5395 this.seqsToIds = null;
5399 private void warn(String msg)
5404 private void warn(String msg, Exception e)
5406 if (Cache.log != null)
5410 Cache.log.warn(msg, e);
5414 Cache.log.warn(msg);
5419 System.err.println("Warning: " + msg);
5422 e.printStackTrace();
5427 private void debug(String string)
5429 debug(string, null);
5432 private void debug(String msg, Exception e)
5434 if (Cache.log != null)
5438 Cache.log.debug(msg, e);
5442 Cache.log.debug(msg);
5447 System.err.println("Warning: " + msg);
5450 e.printStackTrace();
5456 * set the object to ID mapping tables used to write/recover objects and XML
5457 * ID strings for the jalview project. If external tables are provided then
5458 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5459 * object goes out of scope. - also populates the datasetIds hashtable with
5460 * alignment objects containing dataset sequences
5463 * Map from ID strings to jalview datamodel
5465 * Map from jalview datamodel to ID strings
5469 public void setObjectMappingTables(Hashtable vobj2jv,
5470 IdentityHashMap jv2vobj)
5472 this.jv2vobj = jv2vobj;
5473 this.vobj2jv = vobj2jv;
5474 Iterator ds = jv2vobj.keySet().iterator();
5476 while (ds.hasNext())
5478 Object jvobj = ds.next();
5479 id = jv2vobj.get(jvobj).toString();
5480 if (jvobj instanceof jalview.datamodel.Alignment)
5482 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5484 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5487 else if (jvobj instanceof jalview.datamodel.Sequence)
5489 // register sequence object so the XML parser can recover it.
5490 if (seqRefIds == null)
5492 seqRefIds = new HashMap<>();
5494 if (seqsToIds == null)
5496 seqsToIds = new IdentityHashMap<>();
5498 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5499 seqsToIds.put((SequenceI) jvobj, id);
5501 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5504 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5505 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5506 if (jvann.annotationId == null)
5508 jvann.annotationId = anid;
5510 if (!jvann.annotationId.equals(anid))
5512 // TODO verify that this is the correct behaviour
5513 this.warn("Overriding Annotation ID for " + anid
5514 + " from different id : " + jvann.annotationId);
5515 jvann.annotationId = anid;
5518 else if (jvobj instanceof String)
5520 if (jvids2vobj == null)
5522 jvids2vobj = new Hashtable();
5523 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5528 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5534 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5535 * objects created from the project archive. If string is null (default for
5536 * construction) then suffix will be set automatically.
5540 public void setUniqueSetSuffix(String string)
5542 uniqueSetSuffix = string;
5547 * uses skipList2 as the skipList for skipping views on sequence sets
5548 * associated with keys in the skipList
5552 public void setSkipList(Hashtable skipList2)
5554 skipList = skipList2;
5558 * Reads the jar entry of given name and returns its contents, or null if the
5559 * entry is not found.
5562 * @param jarEntryName
5565 protected String readJarEntry(jarInputStreamProvider jprovider,
5566 String jarEntryName)
5568 String result = null;
5569 BufferedReader in = null;
5574 * Reopen the jar input stream and traverse its entries to find a matching
5577 JarInputStream jin = jprovider.getJarInputStream();
5578 JarEntry entry = null;
5581 entry = jin.getNextJarEntry();
5582 } while (entry != null && !entry.getName().equals(jarEntryName));
5586 StringBuilder out = new StringBuilder(256);
5587 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5590 while ((data = in.readLine()) != null)
5594 result = out.toString();
5598 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5600 } catch (Exception ex)
5602 ex.printStackTrace();
5610 } catch (IOException e)
5621 * Returns an incrementing counter (0, 1, 2...)
5625 private synchronized int nextCounter()