2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.analysis.Conservation;
24 import jalview.api.FeatureColourI;
25 import jalview.api.ViewStyleI;
26 import jalview.api.structures.JalviewStructureDisplayI;
27 import jalview.bin.Cache;
28 import jalview.datamodel.AlignedCodonFrame;
29 import jalview.datamodel.Alignment;
30 import jalview.datamodel.AlignmentAnnotation;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.RnaViewerModel;
34 import jalview.datamodel.SequenceGroup;
35 import jalview.datamodel.SequenceI;
36 import jalview.datamodel.StructureViewerModel;
37 import jalview.datamodel.StructureViewerModel.StructureData;
38 import jalview.ext.varna.RnaModel;
39 import jalview.gui.StructureViewer.ViewerType;
40 import jalview.schemabinding.version2.AlcodMap;
41 import jalview.schemabinding.version2.AlcodonFrame;
42 import jalview.schemabinding.version2.Annotation;
43 import jalview.schemabinding.version2.AnnotationColours;
44 import jalview.schemabinding.version2.AnnotationElement;
45 import jalview.schemabinding.version2.CalcIdParam;
46 import jalview.schemabinding.version2.DBRef;
47 import jalview.schemabinding.version2.Features;
48 import jalview.schemabinding.version2.Group;
49 import jalview.schemabinding.version2.HiddenColumns;
50 import jalview.schemabinding.version2.JGroup;
51 import jalview.schemabinding.version2.JSeq;
52 import jalview.schemabinding.version2.JalviewModel;
53 import jalview.schemabinding.version2.JalviewModelSequence;
54 import jalview.schemabinding.version2.MapListFrom;
55 import jalview.schemabinding.version2.MapListTo;
56 import jalview.schemabinding.version2.Mapping;
57 import jalview.schemabinding.version2.MappingChoice;
58 import jalview.schemabinding.version2.OtherData;
59 import jalview.schemabinding.version2.PdbentryItem;
60 import jalview.schemabinding.version2.Pdbids;
61 import jalview.schemabinding.version2.Property;
62 import jalview.schemabinding.version2.RnaViewer;
63 import jalview.schemabinding.version2.SecondaryStructure;
64 import jalview.schemabinding.version2.Sequence;
65 import jalview.schemabinding.version2.SequenceSet;
66 import jalview.schemabinding.version2.SequenceSetProperties;
67 import jalview.schemabinding.version2.Setting;
68 import jalview.schemabinding.version2.StructureState;
69 import jalview.schemabinding.version2.ThresholdLine;
70 import jalview.schemabinding.version2.Tree;
71 import jalview.schemabinding.version2.UserColours;
72 import jalview.schemabinding.version2.Viewport;
73 import jalview.schemes.AnnotationColourGradient;
74 import jalview.schemes.ColourSchemeI;
75 import jalview.schemes.ColourSchemeProperty;
76 import jalview.schemes.FeatureColour;
77 import jalview.schemes.ResidueColourScheme;
78 import jalview.schemes.ResidueProperties;
79 import jalview.schemes.UserColourScheme;
80 import jalview.structure.StructureSelectionManager;
81 import jalview.structures.models.AAStructureBindingModel;
82 import jalview.util.MessageManager;
83 import jalview.util.Platform;
84 import jalview.util.StringUtils;
85 import jalview.util.jarInputStreamProvider;
86 import jalview.viewmodel.AlignmentViewport;
87 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
88 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
89 import jalview.ws.jws2.Jws2Discoverer;
90 import jalview.ws.jws2.dm.AAConSettings;
91 import jalview.ws.jws2.jabaws2.Jws2Instance;
92 import jalview.ws.params.ArgumentI;
93 import jalview.ws.params.AutoCalcSetting;
94 import jalview.ws.params.WsParamSetI;
96 import java.awt.Color;
97 import java.awt.Rectangle;
98 import java.io.BufferedReader;
99 import java.io.DataInputStream;
100 import java.io.DataOutputStream;
102 import java.io.FileInputStream;
103 import java.io.FileOutputStream;
104 import java.io.IOException;
105 import java.io.InputStreamReader;
106 import java.io.OutputStreamWriter;
107 import java.io.PrintWriter;
108 import java.lang.reflect.InvocationTargetException;
109 import java.net.MalformedURLException;
111 import java.util.ArrayList;
112 import java.util.Arrays;
113 import java.util.Enumeration;
114 import java.util.HashMap;
115 import java.util.HashSet;
116 import java.util.Hashtable;
117 import java.util.IdentityHashMap;
118 import java.util.Iterator;
119 import java.util.LinkedHashMap;
120 import java.util.List;
121 import java.util.Map;
122 import java.util.Map.Entry;
123 import java.util.Set;
124 import java.util.Vector;
125 import java.util.jar.JarEntry;
126 import java.util.jar.JarInputStream;
127 import java.util.jar.JarOutputStream;
129 import javax.swing.JInternalFrame;
130 import javax.swing.JOptionPane;
131 import javax.swing.SwingUtilities;
133 import org.exolab.castor.xml.Marshaller;
134 import org.exolab.castor.xml.Unmarshaller;
137 * Write out the current jalview desktop state as a Jalview XML stream.
139 * Note: the vamsas objects referred to here are primitive versions of the
140 * VAMSAS project schema elements - they are not the same and most likely never
144 * @version $Revision: 1.134 $
146 public class Jalview2XML
148 private static final String VIEWER_PREFIX = "viewer_";
150 private static final String RNA_PREFIX = "rna_";
152 private static final String UTF_8 = "UTF-8";
154 // use this with nextCounter() to make unique names for entities
155 private int counter = 0;
158 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
159 * of sequence objects are created.
161 IdentityHashMap<SequenceI, String> seqsToIds = null;
164 * jalview XML Sequence ID to jalview sequence object reference (both dataset
165 * and alignment sequences. Populated as XML reps of sequence objects are
168 Map<String, SequenceI> seqRefIds = null;
170 Map<String, SequenceI> incompleteSeqs = null;
172 List<SeqFref> frefedSequence = null;
174 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
177 * Map of reconstructed AlignFrame objects that appear to have come from
178 * SplitFrame objects (have a dna/protein complement view).
180 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
183 * Map from displayed rna structure models to their saved session state jar
186 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
189 * create/return unique hash string for sq
192 * @return new or existing unique string for sq
194 String seqHash(SequenceI sq)
196 if (seqsToIds == null)
200 if (seqsToIds.containsKey(sq))
202 return seqsToIds.get(sq);
206 // create sequential key
207 String key = "sq" + (seqsToIds.size() + 1);
208 key = makeHashCode(sq, key); // check we don't have an external reference
210 seqsToIds.put(sq, key);
219 if (seqRefIds != null)
223 if (seqsToIds != null)
227 if (incompleteSeqs != null)
229 incompleteSeqs.clear();
237 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
238 // seqRefIds = new Hashtable();
239 // seqsToIds = new IdentityHashMap();
245 if (seqsToIds == null)
247 seqsToIds = new IdentityHashMap<SequenceI, String>();
249 if (seqRefIds == null)
251 seqRefIds = new HashMap<String, SequenceI>();
253 if (incompleteSeqs == null)
255 incompleteSeqs = new HashMap<String, SequenceI>();
257 if (frefedSequence == null)
259 frefedSequence = new ArrayList<SeqFref>();
267 public Jalview2XML(boolean raiseGUI)
269 this.raiseGUI = raiseGUI;
273 * base class for resolving forward references to sequences by their ID
278 abstract class SeqFref
284 public SeqFref(String _sref, String type)
290 public String getSref()
295 public SequenceI getSrefSeq()
297 return seqRefIds.get(sref);
300 public boolean isResolvable()
302 return seqRefIds.get(sref) != null;
305 public SequenceI getSrefDatasetSeq()
307 SequenceI sq = seqRefIds.get(sref);
310 while (sq.getDatasetSequence() != null)
312 sq = sq.getDatasetSequence();
318 * @return true if the forward reference was fully resolved
320 abstract boolean resolve();
323 public String toString()
325 return type + " reference to " + sref;
330 * create forward reference for a mapping
336 public SeqFref newMappingRef(final String sref,
337 final jalview.datamodel.Mapping _jmap)
339 SeqFref fref = new SeqFref(sref, "Mapping")
341 public jalview.datamodel.Mapping jmap = _jmap;
346 SequenceI seq = getSrefDatasetSeq();
358 public SeqFref newAlcodMapRef(final String sref,
359 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
362 SeqFref fref = new SeqFref(sref, "Codon Frame")
364 AlignedCodonFrame cf = _cf;
366 public jalview.datamodel.Mapping mp = _jmap;
369 public boolean isResolvable()
371 return super.isResolvable() && mp.getTo() != null;
377 SequenceI seq = getSrefDatasetSeq();
382 cf.addMap(seq, mp.getTo(), mp.getMap());
389 public void resolveFrefedSequences()
391 Iterator<SeqFref> nextFref=frefedSequence.iterator();
392 int toresolve=frefedSequence.size();
393 int unresolved=0,failedtoresolve=0;
394 while (nextFref.hasNext()) {
395 SeqFref ref = nextFref.next();
396 if (ref.isResolvable())
405 } catch (Exception x) {
406 System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
416 System.err.println("Jalview Project Import: There were " + unresolved
417 + " forward references left unresolved on the stack.");
419 if (failedtoresolve>0)
421 System.err.println("SERIOUS! " + failedtoresolve
422 + " resolvable forward references failed to resolve.");
424 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
426 System.err.println("Jalview Project Import: There are "
427 + incompleteSeqs.size()
428 + " sequences which may have incomplete metadata.");
429 if (incompleteSeqs.size() < 10)
431 for (SequenceI s : incompleteSeqs.values())
433 System.err.println(s.toString());
439 .println("Too many to report. Skipping output of incomplete sequences.");
445 * This maintains a map of viewports, the key being the seqSetId. Important to
446 * set historyItem and redoList for multiple views
448 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
450 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
452 String uniqueSetSuffix = "";
455 * List of pdbfiles added to Jar
457 List<String> pdbfiles = null;
459 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
460 public void saveState(File statefile)
462 FileOutputStream fos = null;
465 fos = new FileOutputStream(statefile);
466 JarOutputStream jout = new JarOutputStream(fos);
469 } catch (Exception e)
471 // TODO: inform user of the problem - they need to know if their data was
473 if (errorMessage == null)
475 errorMessage = "Couldn't write Jalview Archive to output file '"
476 + statefile + "' - See console error log for details";
480 errorMessage += "(output file was '" + statefile + "')";
490 } catch (IOException e)
500 * Writes a jalview project archive to the given Jar output stream.
504 public void saveState(JarOutputStream jout)
506 AlignFrame[] frames = Desktop.getAlignFrames();
512 saveAllFrames(Arrays.asList(frames), jout);
516 * core method for storing state for a set of AlignFrames.
519 * - frames involving all data to be exported (including containing
522 * - project output stream
524 private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
526 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
529 * ensure cached data is clear before starting
531 // todo tidy up seqRefIds, seqsToIds initialisation / reset
533 splitFrameCandidates.clear();
538 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
539 // //////////////////////////////////////////////////
541 List<String> shortNames = new ArrayList<String>();
542 List<String> viewIds = new ArrayList<String>();
545 for (int i = frames.size() - 1; i > -1; i--)
547 AlignFrame af = frames.get(i);
551 .containsKey(af.getViewport().getSequenceSetId()))
556 String shortName = makeFilename(af, shortNames);
558 int ap, apSize = af.alignPanels.size();
560 for (ap = 0; ap < apSize; ap++)
562 AlignmentPanel apanel = af.alignPanels.get(ap);
563 String fileName = apSize == 1 ? shortName : ap + shortName;
564 if (!fileName.endsWith(".xml"))
566 fileName = fileName + ".xml";
569 saveState(apanel, fileName, jout, viewIds);
571 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
573 if (!dsses.containsKey(dssid))
575 dsses.put(dssid, af);
580 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
586 } catch (Exception foo)
591 } catch (Exception ex)
593 // TODO: inform user of the problem - they need to know if their data was
595 if (errorMessage == null)
597 errorMessage = "Couldn't write Jalview Archive - see error output for details";
599 ex.printStackTrace();
604 * Generates a distinct file name, based on the title of the AlignFrame, by
605 * appending _n for increasing n until an unused name is generated. The new
606 * name (without its extension) is added to the list.
610 * @return the generated name, with .xml extension
612 protected String makeFilename(AlignFrame af, List<String> namesUsed)
614 String shortName = af.getTitle();
616 if (shortName.indexOf(File.separatorChar) > -1)
618 shortName = shortName.substring(shortName
619 .lastIndexOf(File.separatorChar) + 1);
624 while (namesUsed.contains(shortName))
626 if (shortName.endsWith("_" + (count - 1)))
628 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
631 shortName = shortName.concat("_" + count);
635 namesUsed.add(shortName);
637 if (!shortName.endsWith(".xml"))
639 shortName = shortName + ".xml";
644 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
645 public boolean saveAlignment(AlignFrame af, String jarFile,
650 FileOutputStream fos = new FileOutputStream(jarFile);
651 JarOutputStream jout = new JarOutputStream(fos);
652 List<AlignFrame> frames = new ArrayList<AlignFrame>();
654 // resolve splitframes
655 if (af.getViewport().getCodingComplement() != null)
657 frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
663 saveAllFrames(frames, jout);
667 } catch (Exception foo)
673 } catch (Exception ex)
675 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
676 ex.printStackTrace();
681 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
682 String fileName, JarOutputStream jout)
685 for (String dssids : dsses.keySet())
687 AlignFrame _af = dsses.get(dssids);
688 String jfileName = fileName + " Dataset for " + _af.getTitle();
689 if (!jfileName.endsWith(".xml"))
691 jfileName = jfileName + ".xml";
693 saveState(_af.alignPanel, jfileName, true, jout, null);
698 * create a JalviewModel from an alignment view and marshall it to a
702 * panel to create jalview model for
704 * name of alignment panel written to output stream
711 public JalviewModel saveState(AlignmentPanel ap, String fileName,
712 JarOutputStream jout, List<String> viewIds)
714 return saveState(ap, fileName, false, jout, viewIds);
718 * create a JalviewModel from an alignment view and marshall it to a
722 * panel to create jalview model for
724 * name of alignment panel written to output stream
726 * when true, only write the dataset for the alignment, not the data
727 * associated with the view.
733 public JalviewModel saveState(AlignmentPanel ap, String fileName,
734 boolean storeDS, JarOutputStream jout, List<String> viewIds)
738 viewIds = new ArrayList<String>();
743 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
745 AlignViewport av = ap.av;
747 JalviewModel object = new JalviewModel();
748 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
750 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
751 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
752 "Development Build"));
755 * rjal is full height alignment, jal is actual alignment with full metadata
756 * but excludes hidden sequences.
758 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
760 if (av.hasHiddenRows())
762 rjal = jal.getHiddenSequences().getFullAlignment();
765 SequenceSet vamsasSet = new SequenceSet();
767 JalviewModelSequence jms = new JalviewModelSequence();
769 vamsasSet.setGapChar(jal.getGapCharacter() + "");
771 if (jal.getDataset() != null)
773 // dataset id is the dataset's hashcode
774 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
777 // switch jal and the dataset
778 jal = jal.getDataset();
782 if (jal.getProperties() != null)
784 Enumeration en = jal.getProperties().keys();
785 while (en.hasMoreElements())
787 String key = en.nextElement().toString();
788 SequenceSetProperties ssp = new SequenceSetProperties();
790 ssp.setValue(jal.getProperties().get(key).toString());
791 vamsasSet.addSequenceSetProperties(ssp);
796 Set<String> calcIdSet = new HashSet<String>();
797 // record the set of vamsas sequence XML POJO we create.
798 HashMap<String,Sequence> vamsasSetIds = new HashMap<String,Sequence>();
800 for (final SequenceI jds : rjal.getSequences())
802 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
803 : jds.getDatasetSequence();
804 String id = seqHash(jds);
805 if (vamsasSetIds.get(id) == null)
807 if (seqRefIds.get(id) != null && !storeDS)
809 // This happens for two reasons: 1. multiple views are being
811 // 2. the hashCode has collided with another sequence's code. This
813 // HAPPEN! (PF00072.15.stk does this)
814 // JBPNote: Uncomment to debug writing out of files that do not read
815 // back in due to ArrayOutOfBoundExceptions.
816 // System.err.println("vamsasSeq backref: "+id+"");
817 // System.err.println(jds.getName()+"
818 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
819 // System.err.println("Hashcode: "+seqHash(jds));
820 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
821 // System.err.println(rsq.getName()+"
822 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
823 // System.err.println("Hashcode: "+seqHash(rsq));
827 vamsasSeq = createVamsasSequence(id, jds);
828 vamsasSet.addSequence(vamsasSeq);
829 vamsasSetIds.put(id, vamsasSeq);
830 seqRefIds.put(id, jds);
834 jseq.setStart(jds.getStart());
835 jseq.setEnd(jds.getEnd());
836 jseq.setColour(av.getSequenceColour(jds).getRGB());
838 jseq.setId(id); // jseq id should be a string not a number
841 // Store any sequences this sequence represents
842 if (av.hasHiddenRows())
844 // use rjal, contains the full height alignment
845 jseq.setHidden(av.getAlignment().getHiddenSequences()
848 if (av.isHiddenRepSequence(jds))
850 jalview.datamodel.SequenceI[] reps = av
851 .getRepresentedSequences(jds)
852 .getSequencesInOrder(rjal);
854 for (int h = 0; h < reps.length; h++)
858 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
863 // mark sequence as reference - if it is the reference for this view
866 jseq.setViewreference(jds == jal.getSeqrep());
870 // TODO: omit sequence features from each alignment view's XML dump if we
871 // are storing dataset
872 if (jds.getSequenceFeatures() != null)
874 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
876 while (index < sf.length)
878 Features features = new Features();
880 features.setBegin(sf[index].getBegin());
881 features.setEnd(sf[index].getEnd());
882 features.setDescription(sf[index].getDescription());
883 features.setType(sf[index].getType());
884 features.setFeatureGroup(sf[index].getFeatureGroup());
885 features.setScore(sf[index].getScore());
886 if (sf[index].links != null)
888 for (int l = 0; l < sf[index].links.size(); l++)
890 OtherData keyValue = new OtherData();
891 keyValue.setKey("LINK_" + l);
892 keyValue.setValue(sf[index].links.elementAt(l).toString());
893 features.addOtherData(keyValue);
896 if (sf[index].otherDetails != null)
899 Iterator<String> keys = sf[index].otherDetails.keySet()
901 while (keys.hasNext())
904 OtherData keyValue = new OtherData();
905 keyValue.setKey(key);
906 keyValue.setValue(sf[index].otherDetails.get(key).toString());
907 features.addOtherData(keyValue);
911 jseq.addFeatures(features);
916 if (jdatasq.getAllPDBEntries() != null)
918 Enumeration en = jdatasq.getAllPDBEntries().elements();
919 while (en.hasMoreElements())
921 Pdbids pdb = new Pdbids();
922 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
925 String pdbId = entry.getId();
927 pdb.setType(entry.getType());
930 * Store any structure views associated with this sequence. This
931 * section copes with duplicate entries in the project, so a dataset
932 * only view *should* be coped with sensibly.
934 // This must have been loaded, is it still visible?
935 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
936 String matchedFile = null;
937 for (int f = frames.length - 1; f > -1; f--)
939 if (frames[f] instanceof StructureViewerBase)
941 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
942 matchedFile = saveStructureState(ap, jds, pdb, entry,
943 viewIds, matchedFile, viewFrame);
945 * Only store each structure viewer's state once in the project
946 * jar. First time through only (storeDS==false)
948 String viewId = viewFrame.getViewId();
949 if (!storeDS && !viewIds.contains(viewId))
954 String viewerState = viewFrame.getStateInfo();
955 writeJarEntry(jout, getViewerJarEntryName(viewId),
956 viewerState.getBytes());
957 } catch (IOException e)
959 System.err.println("Error saving viewer state: "
966 if (matchedFile != null || entry.getFile() != null)
968 if (entry.getFile() != null)
971 matchedFile = entry.getFile();
973 pdb.setFile(matchedFile); // entry.getFile());
974 if (pdbfiles == null)
976 pdbfiles = new ArrayList<String>();
979 if (!pdbfiles.contains(pdbId))
982 copyFileToJar(jout, matchedFile, pdbId);
986 Enumeration<String> props = entry.getProperties();
987 if (props.hasMoreElements())
989 PdbentryItem item = new PdbentryItem();
990 while (props.hasMoreElements())
992 Property prop = new Property();
993 String key = props.nextElement();
995 prop.setValue(entry.getProperty(key).toString());
996 item.addProperty(prop);
998 pdb.addPdbentryItem(item);
1001 jseq.addPdbids(pdb);
1005 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1010 if (!storeDS && av.hasHiddenRows())
1012 jal = av.getAlignment();
1016 if (storeDS && jal.getCodonFrames() != null)
1018 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1019 for (AlignedCodonFrame acf : jac)
1021 AlcodonFrame alc = new AlcodonFrame();
1022 if (acf.getProtMappings() != null
1023 && acf.getProtMappings().length > 0)
1025 boolean hasMap = false;
1026 SequenceI[] dnas = acf.getdnaSeqs();
1027 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1028 for (int m = 0; m < pmaps.length; m++)
1030 AlcodMap alcmap = new AlcodMap();
1031 alcmap.setDnasq(seqHash(dnas[m]));
1032 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1034 alc.addAlcodMap(alcmap);
1039 vamsasSet.addAlcodonFrame(alc);
1042 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1044 // AlcodonFrame alc = new AlcodonFrame();
1045 // vamsasSet.addAlcodonFrame(alc);
1046 // for (int p = 0; p < acf.aaWidth; p++)
1048 // Alcodon cmap = new Alcodon();
1049 // if (acf.codons[p] != null)
1051 // // Null codons indicate a gapped column in the translated peptide
1053 // cmap.setPos1(acf.codons[p][0]);
1054 // cmap.setPos2(acf.codons[p][1]);
1055 // cmap.setPos3(acf.codons[p][2]);
1057 // alc.addAlcodon(cmap);
1059 // if (acf.getProtMappings() != null
1060 // && acf.getProtMappings().length > 0)
1062 // SequenceI[] dnas = acf.getdnaSeqs();
1063 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1064 // for (int m = 0; m < pmaps.length; m++)
1066 // AlcodMap alcmap = new AlcodMap();
1067 // alcmap.setDnasq(seqHash(dnas[m]));
1068 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1070 // alc.addAlcodMap(alcmap);
1077 // /////////////////////////////////
1078 if (!storeDS && av.currentTree != null)
1080 // FIND ANY ASSOCIATED TREES
1081 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1082 if (Desktop.desktop != null)
1084 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1086 for (int t = 0; t < frames.length; t++)
1088 if (frames[t] instanceof TreePanel)
1090 TreePanel tp = (TreePanel) frames[t];
1092 if (tp.treeCanvas.av.getAlignment() == jal)
1094 Tree tree = new Tree();
1095 tree.setTitle(tp.getTitle());
1096 tree.setCurrentTree((av.currentTree == tp.getTree()));
1097 tree.setNewick(tp.getTree().toString());
1098 tree.setThreshold(tp.treeCanvas.threshold);
1100 tree.setFitToWindow(tp.fitToWindow.getState());
1101 tree.setFontName(tp.getTreeFont().getName());
1102 tree.setFontSize(tp.getTreeFont().getSize());
1103 tree.setFontStyle(tp.getTreeFont().getStyle());
1104 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1106 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1107 tree.setShowDistances(tp.distanceMenu.getState());
1109 tree.setHeight(tp.getHeight());
1110 tree.setWidth(tp.getWidth());
1111 tree.setXpos(tp.getX());
1112 tree.setYpos(tp.getY());
1113 tree.setId(makeHashCode(tp, null));
1123 * store forward refs from an annotationRow to any groups
1125 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1128 for (SequenceI sq : jal.getSequences())
1130 // Store annotation on dataset sequences only
1131 AlignmentAnnotation[] aa = sq.getAnnotation();
1132 if (aa != null && aa.length > 0)
1134 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1141 if (jal.getAlignmentAnnotation() != null)
1143 // Store the annotation shown on the alignment.
1144 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1145 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1150 if (jal.getGroups() != null)
1152 JGroup[] groups = new JGroup[jal.getGroups().size()];
1154 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1156 JGroup jGroup = new JGroup();
1157 groups[++i] = jGroup;
1159 jGroup.setStart(sg.getStartRes());
1160 jGroup.setEnd(sg.getEndRes());
1161 jGroup.setName(sg.getName());
1162 if (groupRefs.containsKey(sg))
1164 // group has references so set its ID field
1165 jGroup.setId(groupRefs.get(sg));
1169 if (sg.cs.conservationApplied())
1171 jGroup.setConsThreshold(sg.cs.getConservationInc());
1173 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1175 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1179 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1182 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1184 jGroup.setColour("AnnotationColourGradient");
1185 jGroup.setAnnotationColours(constructAnnotationColours(
1186 (jalview.schemes.AnnotationColourGradient) sg.cs,
1189 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1191 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1195 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1198 jGroup.setPidThreshold(sg.cs.getThreshold());
1201 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1202 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1203 jGroup.setDisplayText(sg.getDisplayText());
1204 jGroup.setColourText(sg.getColourText());
1205 jGroup.setTextCol1(sg.textColour.getRGB());
1206 jGroup.setTextCol2(sg.textColour2.getRGB());
1207 jGroup.setTextColThreshold(sg.thresholdTextColour);
1208 jGroup.setShowUnconserved(sg.getShowNonconserved());
1209 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1210 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1211 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1212 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1213 for (SequenceI seq : sg.getSequences())
1215 jGroup.addSeq(seqHash(seq));
1219 jms.setJGroup(groups);
1223 // /////////SAVE VIEWPORT
1224 Viewport view = new Viewport();
1225 view.setTitle(ap.alignFrame.getTitle());
1226 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1227 av.getSequenceSetId()));
1228 view.setId(av.getViewId());
1229 if (av.getCodingComplement() != null)
1231 view.setComplementId(av.getCodingComplement().getViewId());
1233 view.setViewName(av.viewName);
1234 view.setGatheredViews(av.isGatherViewsHere());
1236 Rectangle size = ap.av.getExplodedGeometry();
1237 Rectangle position = size;
1240 size = ap.alignFrame.getBounds();
1241 if (av.getCodingComplement() != null)
1243 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1251 view.setXpos(position.x);
1252 view.setYpos(position.y);
1254 view.setWidth(size.width);
1255 view.setHeight(size.height);
1257 view.setStartRes(av.startRes);
1258 view.setStartSeq(av.startSeq);
1260 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1262 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1265 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1267 AnnotationColours ac = constructAnnotationColours(
1268 (jalview.schemes.AnnotationColourGradient) av
1269 .getGlobalColourScheme(),
1272 view.setAnnotationColours(ac);
1273 view.setBgColour("AnnotationColourGradient");
1277 view.setBgColour(ColourSchemeProperty.getColourName(av
1278 .getGlobalColourScheme()));
1281 ColourSchemeI cs = av.getGlobalColourScheme();
1285 if (cs.conservationApplied())
1287 view.setConsThreshold(cs.getConservationInc());
1288 if (cs instanceof jalview.schemes.UserColourScheme)
1290 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1294 if (cs instanceof ResidueColourScheme)
1296 view.setPidThreshold(cs.getThreshold());
1300 view.setConservationSelected(av.getConservationSelected());
1301 view.setPidSelected(av.getAbovePIDThreshold());
1302 view.setFontName(av.font.getName());
1303 view.setFontSize(av.font.getSize());
1304 view.setFontStyle(av.font.getStyle());
1305 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1306 view.setRenderGaps(av.isRenderGaps());
1307 view.setShowAnnotation(av.isShowAnnotation());
1308 view.setShowBoxes(av.getShowBoxes());
1309 view.setShowColourText(av.getColourText());
1310 view.setShowFullId(av.getShowJVSuffix());
1311 view.setRightAlignIds(av.isRightAlignIds());
1312 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1313 view.setShowText(av.getShowText());
1314 view.setShowUnconserved(av.getShowUnconserved());
1315 view.setWrapAlignment(av.getWrapAlignment());
1316 view.setTextCol1(av.getTextColour().getRGB());
1317 view.setTextCol2(av.getTextColour2().getRGB());
1318 view.setTextColThreshold(av.getThresholdTextColour());
1319 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1320 view.setShowSequenceLogo(av.isShowSequenceLogo());
1321 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1322 view.setShowGroupConsensus(av.isShowGroupConsensus());
1323 view.setShowGroupConservation(av.isShowGroupConservation());
1324 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1325 view.setShowDbRefTooltip(av.isShowDBRefs());
1326 view.setFollowHighlight(av.isFollowHighlight());
1327 view.setFollowSelection(av.followSelection);
1328 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1329 if (av.getFeaturesDisplayed() != null)
1331 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1333 String[] renderOrder = ap.getSeqPanel().seqCanvas
1334 .getFeatureRenderer().getRenderOrder()
1335 .toArray(new String[0]);
1337 Vector<String> settingsAdded = new Vector<String>();
1338 if (renderOrder != null)
1340 for (String featureType : renderOrder)
1342 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1343 .getFeatureRenderer()
1344 .getFeatureStyle(featureType);
1345 Setting setting = new Setting();
1346 setting.setType(featureType);
1347 if (!fcol.isSimpleColour())
1349 setting.setColour(fcol.getMaxColour().getRGB());
1350 setting.setMincolour(fcol.getMinColour().getRGB());
1351 setting.setMin(fcol.getMin());
1352 setting.setMax(fcol.getMax());
1353 setting.setColourByLabel(fcol.isColourByLabel());
1354 setting.setAutoScale(fcol.isAutoScaled());
1355 setting.setThreshold(fcol.getThreshold());
1356 // -1 = No threshold, 0 = Below, 1 = Above
1357 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1358 : (fcol.isBelowThreshold() ? 0 : -1));
1362 setting.setColour(fcol.getColour().getRGB());
1365 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1367 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1368 .getOrder(featureType);
1371 setting.setOrder(rorder);
1373 fs.addSetting(setting);
1374 settingsAdded.addElement(featureType);
1378 // is groups actually supposed to be a map here ?
1379 Iterator<String> en = ap.getSeqPanel().seqCanvas
1380 .getFeatureRenderer()
1381 .getFeatureGroups().iterator();
1382 Vector<String> groupsAdded = new Vector<String>();
1383 while (en.hasNext())
1385 String grp = en.next();
1386 if (groupsAdded.contains(grp))
1390 Group g = new Group();
1392 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1393 .getFeatureRenderer().checkGroupVisibility(grp, false))
1396 groupsAdded.addElement(grp);
1398 jms.setFeatureSettings(fs);
1401 if (av.hasHiddenColumns())
1403 if (av.getColumnSelection() == null
1404 || av.getColumnSelection().getHiddenColumns() == null)
1406 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1410 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1413 int[] region = av.getColumnSelection().getHiddenColumns()
1415 HiddenColumns hc = new HiddenColumns();
1416 hc.setStart(region[0]);
1417 hc.setEnd(region[1]);
1418 view.addHiddenColumns(hc);
1422 if (calcIdSet.size() > 0)
1424 for (String calcId : calcIdSet)
1426 if (calcId.trim().length() > 0)
1428 CalcIdParam cidp = createCalcIdParam(calcId, av);
1429 // Some calcIds have no parameters.
1432 view.addCalcIdParam(cidp);
1438 jms.addViewport(view);
1440 object.setJalviewModelSequence(jms);
1441 object.getVamsasModel().addSequenceSet(vamsasSet);
1443 if (jout != null && fileName != null)
1445 // We may not want to write the object to disk,
1446 // eg we can copy the alignViewport to a new view object
1447 // using save and then load
1450 System.out.println("Writing jar entry " + fileName);
1451 JarEntry entry = new JarEntry(fileName);
1452 jout.putNextEntry(entry);
1453 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1455 Marshaller marshaller = new Marshaller(pout);
1456 marshaller.marshal(object);
1459 } catch (Exception ex)
1461 // TODO: raise error in GUI if marshalling failed.
1462 ex.printStackTrace();
1469 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1470 * for each viewer, with
1472 * <li>viewer geometry (position, size, split pane divider location)</li>
1473 * <li>index of the selected structure in the viewer (currently shows gapped
1475 * <li>the id of the annotation holding RNA secondary structure</li>
1476 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1478 * Varna viewer state is also written out (in native Varna XML) to separate
1479 * project jar entries. A separate entry is written for each RNA structure
1480 * displayed, with the naming convention
1482 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1490 * @param storeDataset
1492 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1493 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1494 boolean storeDataset)
1496 if (Desktop.desktop == null)
1500 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1501 for (int f = frames.length - 1; f > -1; f--)
1503 if (frames[f] instanceof AppVarna)
1505 AppVarna varna = (AppVarna) frames[f];
1507 * link the sequence to every viewer that is showing it and is linked to
1508 * its alignment panel
1510 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1512 String viewId = varna.getViewId();
1513 RnaViewer rna = new RnaViewer();
1514 rna.setViewId(viewId);
1515 rna.setTitle(varna.getTitle());
1516 rna.setXpos(varna.getX());
1517 rna.setYpos(varna.getY());
1518 rna.setWidth(varna.getWidth());
1519 rna.setHeight(varna.getHeight());
1520 rna.setDividerLocation(varna.getDividerLocation());
1521 rna.setSelectedRna(varna.getSelectedIndex());
1522 jseq.addRnaViewer(rna);
1525 * Store each Varna panel's state once in the project per sequence.
1526 * First time through only (storeDataset==false)
1528 // boolean storeSessions = false;
1529 // String sequenceViewId = viewId + seqsToIds.get(jds);
1530 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1532 // viewIds.add(sequenceViewId);
1533 // storeSessions = true;
1535 for (RnaModel model : varna.getModels())
1537 if (model.seq == jds)
1540 * VARNA saves each view (sequence or alignment secondary
1541 * structure, gapped or trimmed) as a separate XML file
1543 String jarEntryName = rnaSessions.get(model);
1544 if (jarEntryName == null)
1547 String varnaStateFile = varna.getStateInfo(model.rna);
1548 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1549 copyFileToJar(jout, varnaStateFile, jarEntryName);
1550 rnaSessions.put(model, jarEntryName);
1552 SecondaryStructure ss = new SecondaryStructure();
1553 String annotationId = varna.getAnnotation(jds).annotationId;
1554 ss.setAnnotationId(annotationId);
1555 ss.setViewerState(jarEntryName);
1556 ss.setGapped(model.gapped);
1557 ss.setTitle(model.title);
1558 rna.addSecondaryStructure(ss);
1567 * Copy the contents of a file to a new entry added to the output jar
1571 * @param jarEntryName
1573 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1574 String jarEntryName)
1576 DataInputStream dis = null;
1579 File file = new File(infilePath);
1580 if (file.exists() && jout != null)
1582 dis = new DataInputStream(new FileInputStream(file));
1583 byte[] data = new byte[(int) file.length()];
1584 dis.readFully(data);
1585 writeJarEntry(jout, jarEntryName, data);
1587 } catch (Exception ex)
1589 ex.printStackTrace();
1597 } catch (IOException e)
1606 * Write the data to a new entry of given name in the output jar file
1609 * @param jarEntryName
1611 * @throws IOException
1613 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1614 byte[] data) throws IOException
1618 System.out.println("Writing jar entry " + jarEntryName);
1619 jout.putNextEntry(new JarEntry(jarEntryName));
1620 DataOutputStream dout = new DataOutputStream(jout);
1621 dout.write(data, 0, data.length);
1628 * Save the state of a structure viewer
1633 * the archive XML element under which to save the state
1636 * @param matchedFile
1640 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1641 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1642 String matchedFile, StructureViewerBase viewFrame)
1644 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1647 * Look for any bindings for this viewer to the PDB file of interest
1648 * (including part matches excluding chain id)
1650 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1652 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1653 final String pdbId = pdbentry.getId();
1654 if (!pdbId.equals(entry.getId())
1655 && !(entry.getId().length() > 4 && entry.getId()
1656 .toLowerCase().startsWith(pdbId.toLowerCase())))
1659 * not interested in a binding to a different PDB entry here
1663 if (matchedFile == null)
1665 matchedFile = pdbentry.getFile();
1667 else if (!matchedFile.equals(pdbentry.getFile()))
1670 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1671 + pdbentry.getFile());
1675 // can get at it if the ID
1676 // match is ambiguous (e.g.
1679 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1681 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1682 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1684 StructureState state = new StructureState();
1685 state.setVisible(true);
1686 state.setXpos(viewFrame.getX());
1687 state.setYpos(viewFrame.getY());
1688 state.setWidth(viewFrame.getWidth());
1689 state.setHeight(viewFrame.getHeight());
1690 final String viewId = viewFrame.getViewId();
1691 state.setViewId(viewId);
1692 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1693 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1694 state.setColourByJmol(viewFrame.isColouredByViewer());
1695 state.setType(viewFrame.getViewerType().toString());
1696 pdb.addStructureState(state);
1703 private AnnotationColours constructAnnotationColours(
1704 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1705 JalviewModelSequence jms)
1707 AnnotationColours ac = new AnnotationColours();
1708 ac.setAboveThreshold(acg.getAboveThreshold());
1709 ac.setThreshold(acg.getAnnotationThreshold());
1710 ac.setAnnotation(acg.getAnnotation());
1711 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1713 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1718 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1722 ac.setMaxColour(acg.getMaxColour().getRGB());
1723 ac.setMinColour(acg.getMinColour().getRGB());
1724 ac.setPerSequence(acg.isSeqAssociated());
1725 ac.setPredefinedColours(acg.isPredefinedColours());
1729 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1730 IdentityHashMap<SequenceGroup, String> groupRefs,
1731 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1732 SequenceSet vamsasSet)
1735 for (int i = 0; i < aa.length; i++)
1737 Annotation an = new Annotation();
1739 AlignmentAnnotation annotation = aa[i];
1740 if (annotation.annotationId != null)
1742 annotationIds.put(annotation.annotationId, annotation);
1745 an.setId(annotation.annotationId);
1747 an.setVisible(annotation.visible);
1749 an.setDescription(annotation.description);
1751 if (annotation.sequenceRef != null)
1753 // 2.9 JAL-1781 xref on sequence id rather than name
1754 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1756 if (annotation.groupRef != null)
1758 String groupIdr = groupRefs.get(annotation.groupRef);
1759 if (groupIdr == null)
1761 // make a locally unique String
1763 annotation.groupRef,
1764 groupIdr = ("" + System.currentTimeMillis()
1765 + annotation.groupRef.getName() + groupRefs
1768 an.setGroupRef(groupIdr.toString());
1771 // store all visualization attributes for annotation
1772 an.setGraphHeight(annotation.graphHeight);
1773 an.setCentreColLabels(annotation.centreColLabels);
1774 an.setScaleColLabels(annotation.scaleColLabel);
1775 an.setShowAllColLabels(annotation.showAllColLabels);
1776 an.setBelowAlignment(annotation.belowAlignment);
1778 if (annotation.graph > 0)
1781 an.setGraphType(annotation.graph);
1782 an.setGraphGroup(annotation.graphGroup);
1783 if (annotation.getThreshold() != null)
1785 ThresholdLine line = new ThresholdLine();
1786 line.setLabel(annotation.getThreshold().label);
1787 line.setValue(annotation.getThreshold().value);
1788 line.setColour(annotation.getThreshold().colour.getRGB());
1789 an.setThresholdLine(line);
1797 an.setLabel(annotation.label);
1799 if (annotation == av.getAlignmentQualityAnnot()
1800 || annotation == av.getAlignmentConservationAnnotation()
1801 || annotation == av.getAlignmentConsensusAnnotation()
1802 || annotation.autoCalculated)
1804 // new way of indicating autocalculated annotation -
1805 an.setAutoCalculated(annotation.autoCalculated);
1807 if (annotation.hasScore())
1809 an.setScore(annotation.getScore());
1812 if (annotation.getCalcId() != null)
1814 calcIdSet.add(annotation.getCalcId());
1815 an.setCalcId(annotation.getCalcId());
1817 if (annotation.hasProperties())
1819 for (String pr : annotation.getProperties())
1821 Property prop = new Property();
1823 prop.setValue(annotation.getProperty(pr));
1824 an.addProperty(prop);
1828 AnnotationElement ae;
1829 if (annotation.annotations != null)
1831 an.setScoreOnly(false);
1832 for (int a = 0; a < annotation.annotations.length; a++)
1834 if ((annotation == null) || (annotation.annotations[a] == null))
1839 ae = new AnnotationElement();
1840 if (annotation.annotations[a].description != null)
1842 ae.setDescription(annotation.annotations[a].description);
1844 if (annotation.annotations[a].displayCharacter != null)
1846 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1849 if (!Float.isNaN(annotation.annotations[a].value))
1851 ae.setValue(annotation.annotations[a].value);
1855 if (annotation.annotations[a].secondaryStructure > ' ')
1857 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1861 if (annotation.annotations[a].colour != null
1862 && annotation.annotations[a].colour != java.awt.Color.black)
1864 ae.setColour(annotation.annotations[a].colour.getRGB());
1867 an.addAnnotationElement(ae);
1868 if (annotation.autoCalculated)
1870 // only write one non-null entry into the annotation row -
1871 // sufficient to get the visualization attributes necessary to
1879 an.setScoreOnly(true);
1881 if (!storeDS || (storeDS && !annotation.autoCalculated))
1883 // skip autocalculated annotation - these are only provided for
1885 vamsasSet.addAnnotation(an);
1891 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1893 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1894 if (settings != null)
1896 CalcIdParam vCalcIdParam = new CalcIdParam();
1897 vCalcIdParam.setCalcId(calcId);
1898 vCalcIdParam.addServiceURL(settings.getServiceURI());
1899 // generic URI allowing a third party to resolve another instance of the
1900 // service used for this calculation
1901 for (String urls : settings.getServiceURLs())
1903 vCalcIdParam.addServiceURL(urls);
1905 vCalcIdParam.setVersion("1.0");
1906 if (settings.getPreset() != null)
1908 WsParamSetI setting = settings.getPreset();
1909 vCalcIdParam.setName(setting.getName());
1910 vCalcIdParam.setDescription(setting.getDescription());
1914 vCalcIdParam.setName("");
1915 vCalcIdParam.setDescription("Last used parameters");
1917 // need to be able to recover 1) settings 2) user-defined presets or
1918 // recreate settings from preset 3) predefined settings provided by
1919 // service - or settings that can be transferred (or discarded)
1920 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1922 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1923 // todo - decide if updateImmediately is needed for any projects.
1925 return vCalcIdParam;
1930 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1933 if (calcIdParam.getVersion().equals("1.0"))
1935 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1936 .getPreferredServiceFor(calcIdParam.getServiceURL());
1937 if (service != null)
1939 WsParamSetI parmSet = null;
1942 parmSet = service.getParamStore().parseServiceParameterFile(
1943 calcIdParam.getName(), calcIdParam.getDescription(),
1944 calcIdParam.getServiceURL(),
1945 calcIdParam.getParameters().replace("|\\n|", "\n"));
1946 } catch (IOException x)
1948 warn("Couldn't parse parameter data for "
1949 + calcIdParam.getCalcId(), x);
1952 List<ArgumentI> argList = null;
1953 if (calcIdParam.getName().length() > 0)
1955 parmSet = service.getParamStore()
1956 .getPreset(calcIdParam.getName());
1957 if (parmSet != null)
1959 // TODO : check we have a good match with settings in AACon -
1960 // otherwise we'll need to create a new preset
1965 argList = parmSet.getArguments();
1968 AAConSettings settings = new AAConSettings(
1969 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1970 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1971 calcIdParam.isNeedsUpdate());
1976 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1980 throw new Error(MessageManager.formatMessage(
1981 "error.unsupported_version_calcIdparam",
1982 new Object[] { calcIdParam.toString() }));
1986 * External mapping between jalview objects and objects yielding a valid and
1987 * unique object ID string. This is null for normal Jalview project IO, but
1988 * non-null when a jalview project is being read or written as part of a
1991 IdentityHashMap jv2vobj = null;
1994 * Construct a unique ID for jvobj using either existing bindings or if none
1995 * exist, the result of the hashcode call for the object.
1998 * jalview data object
1999 * @return unique ID for referring to jvobj
2001 private String makeHashCode(Object jvobj, String altCode)
2003 if (jv2vobj != null)
2005 Object id = jv2vobj.get(jvobj);
2008 return id.toString();
2010 // check string ID mappings
2011 if (jvids2vobj != null && jvobj instanceof String)
2013 id = jvids2vobj.get(jvobj);
2017 return id.toString();
2019 // give up and warn that something has gone wrong
2020 warn("Cannot find ID for object in external mapping : " + jvobj);
2026 * return local jalview object mapped to ID, if it exists
2030 * @return null or object bound to idcode
2032 private Object retrieveExistingObj(String idcode)
2034 if (idcode != null && vobj2jv != null)
2036 return vobj2jv.get(idcode);
2042 * binding from ID strings from external mapping table to jalview data model
2045 private Hashtable vobj2jv;
2047 private Sequence createVamsasSequence(String id, SequenceI jds)
2049 return createVamsasSequence(true, id, jds, null);
2052 private Sequence createVamsasSequence(boolean recurse, String id,
2053 SequenceI jds, SequenceI parentseq)
2055 Sequence vamsasSeq = new Sequence();
2056 vamsasSeq.setId(id);
2057 vamsasSeq.setName(jds.getName());
2058 vamsasSeq.setSequence(jds.getSequenceAsString());
2059 vamsasSeq.setDescription(jds.getDescription());
2060 jalview.datamodel.DBRefEntry[] dbrefs = null;
2061 if (jds.getDatasetSequence() != null)
2063 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2067 // seqId==dsseqid so we can tell which sequences really are
2068 // dataset sequences only
2069 vamsasSeq.setDsseqid(id);
2070 dbrefs = jds.getDBRefs();
2071 if (parentseq == null)
2078 for (int d = 0; d < dbrefs.length; d++)
2080 DBRef dbref = new DBRef();
2081 dbref.setSource(dbrefs[d].getSource());
2082 dbref.setVersion(dbrefs[d].getVersion());
2083 dbref.setAccessionId(dbrefs[d].getAccessionId());
2084 if (dbrefs[d].hasMap())
2086 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2088 dbref.setMapping(mp);
2090 vamsasSeq.addDBRef(dbref);
2096 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2097 SequenceI parentseq, SequenceI jds, boolean recurse)
2100 if (jmp.getMap() != null)
2104 jalview.util.MapList mlst = jmp.getMap();
2105 List<int[]> r = mlst.getFromRanges();
2106 for (int[] range : r)
2108 MapListFrom mfrom = new MapListFrom();
2109 mfrom.setStart(range[0]);
2110 mfrom.setEnd(range[1]);
2111 mp.addMapListFrom(mfrom);
2113 r = mlst.getToRanges();
2114 for (int[] range : r)
2116 MapListTo mto = new MapListTo();
2117 mto.setStart(range[0]);
2118 mto.setEnd(range[1]);
2119 mp.addMapListTo(mto);
2121 mp.setMapFromUnit(mlst.getFromRatio());
2122 mp.setMapToUnit(mlst.getToRatio());
2123 if (jmp.getTo() != null)
2125 MappingChoice mpc = new MappingChoice();
2127 // check/create ID for the sequence referenced by getTo()
2130 SequenceI ps = null;
2131 if (parentseq != jmp.getTo()
2132 && parentseq.getDatasetSequence() != jmp.getTo())
2134 // chaining dbref rather than a handshaking one
2135 jmpid = seqHash(ps = jmp.getTo());
2139 jmpid = seqHash(ps = parentseq);
2141 mpc.setDseqFor(jmpid);
2142 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2144 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2145 seqRefIds.put(mpc.getDseqFor(), ps);
2149 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2152 mp.setMappingChoice(mpc);
2158 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2159 List<UserColourScheme> userColours, JalviewModelSequence jms)
2162 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2163 boolean newucs = false;
2164 if (!userColours.contains(ucs))
2166 userColours.add(ucs);
2169 id = "ucs" + userColours.indexOf(ucs);
2172 // actually create the scheme's entry in the XML model
2173 java.awt.Color[] colours = ucs.getColours();
2174 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2175 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2177 for (int i = 0; i < colours.length; i++)
2179 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2180 col.setName(ResidueProperties.aa[i]);
2181 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2182 jbucs.addColour(col);
2184 if (ucs.getLowerCaseColours() != null)
2186 colours = ucs.getLowerCaseColours();
2187 for (int i = 0; i < colours.length; i++)
2189 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2190 col.setName(ResidueProperties.aa[i].toLowerCase());
2191 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2192 jbucs.addColour(col);
2197 uc.setUserColourScheme(jbucs);
2198 jms.addUserColours(uc);
2204 jalview.schemes.UserColourScheme getUserColourScheme(
2205 JalviewModelSequence jms, String id)
2207 UserColours[] uc = jms.getUserColours();
2208 UserColours colours = null;
2210 for (int i = 0; i < uc.length; i++)
2212 if (uc[i].getId().equals(id))
2220 java.awt.Color[] newColours = new java.awt.Color[24];
2222 for (int i = 0; i < 24; i++)
2224 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2225 .getUserColourScheme().getColour(i).getRGB(), 16));
2228 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2231 if (colours.getUserColourScheme().getColourCount() > 24)
2233 newColours = new java.awt.Color[23];
2234 for (int i = 0; i < 23; i++)
2236 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2237 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2239 ucs.setLowerCaseColours(newColours);
2246 * contains last error message (if any) encountered by XML loader.
2248 String errorMessage = null;
2251 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2252 * exceptions are raised during project XML parsing
2254 public boolean attemptversion1parse = true;
2257 * Load a jalview project archive from a jar file
2260 * - HTTP URL or filename
2262 public AlignFrame loadJalviewAlign(final String file)
2265 jalview.gui.AlignFrame af = null;
2269 // create list to store references for any new Jmol viewers created
2270 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2271 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2272 // Workaround is to make sure caller implements the JarInputStreamProvider
2274 // so we can re-open the jar input stream for each entry.
2276 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2277 af = loadJalviewAlign(jprovider);
2279 } catch (MalformedURLException e)
2281 errorMessage = "Invalid URL format for '" + file + "'";
2287 SwingUtilities.invokeAndWait(new Runnable()
2292 setLoadingFinishedForNewStructureViewers();
2295 } catch (Exception x)
2297 System.err.println("Error loading alignment: " + x.getMessage());
2303 private jarInputStreamProvider createjarInputStreamProvider(
2304 final String file) throws MalformedURLException
2307 errorMessage = null;
2308 uniqueSetSuffix = null;
2310 viewportsAdded.clear();
2311 frefedSequence = null;
2313 if (file.startsWith("http://"))
2315 url = new URL(file);
2317 final URL _url = url;
2318 return new jarInputStreamProvider()
2322 public JarInputStream getJarInputStream() throws IOException
2326 return new JarInputStream(_url.openStream());
2330 return new JarInputStream(new FileInputStream(file));
2335 public String getFilename()
2343 * Recover jalview session from a jalview project archive. Caller may
2344 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2345 * themselves. Any null fields will be initialised with default values,
2346 * non-null fields are left alone.
2351 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2353 errorMessage = null;
2354 if (uniqueSetSuffix == null)
2356 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2358 if (seqRefIds == null)
2362 AlignFrame af = null, _af = null;
2363 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2364 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2365 final String file = jprovider.getFilename();
2368 JarInputStream jin = null;
2369 JarEntry jarentry = null;
2374 jin = jprovider.getJarInputStream();
2375 for (int i = 0; i < entryCount; i++)
2377 jarentry = jin.getNextJarEntry();
2380 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2382 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2383 JalviewModel object = new JalviewModel();
2385 Unmarshaller unmar = new Unmarshaller(object);
2386 unmar.setValidation(false);
2387 object = (JalviewModel) unmar.unmarshal(in);
2388 if (true) // !skipViewport(object))
2390 _af = loadFromObject(object, file, true, jprovider);
2392 && object.getJalviewModelSequence().getViewportCount() > 0)
2396 // store a reference to the first view
2399 if (_af.viewport.isGatherViewsHere())
2401 // if this is a gathered view, keep its reference since
2402 // after gathering views, only this frame will remain
2404 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2406 // Save dataset to register mappings once all resolved
2407 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2408 af.viewport.getAlignment().getDataset());
2413 else if (jarentry != null)
2415 // Some other file here.
2418 } while (jarentry != null);
2419 resolveFrefedSequences();
2420 } catch (IOException ex)
2422 ex.printStackTrace();
2423 errorMessage = "Couldn't locate Jalview XML file : " + file;
2424 System.err.println("Exception whilst loading jalview XML file : "
2426 } catch (Exception ex)
2428 System.err.println("Parsing as Jalview Version 2 file failed.");
2429 ex.printStackTrace(System.err);
2430 if (attemptversion1parse)
2432 // Is Version 1 Jar file?
2435 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2436 } catch (Exception ex2)
2438 System.err.println("Exception whilst loading as jalviewXMLV1:");
2439 ex2.printStackTrace();
2443 if (Desktop.instance != null)
2445 Desktop.instance.stopLoading();
2449 System.out.println("Successfully loaded archive file");
2452 ex.printStackTrace();
2454 System.err.println("Exception whilst loading jalview XML file : "
2456 } catch (OutOfMemoryError e)
2458 // Don't use the OOM Window here
2459 errorMessage = "Out of memory loading jalview XML file";
2460 System.err.println("Out of memory whilst loading jalview XML file");
2461 e.printStackTrace();
2465 * Regather multiple views (with the same sequence set id) to the frame (if
2466 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2467 * views instead of separate frames. Note this doesn't restore a state where
2468 * some expanded views in turn have tabbed views - the last "first tab" read
2469 * in will play the role of gatherer for all.
2471 for (AlignFrame fr : gatherToThisFrame.values())
2473 Desktop.instance.gatherViews(fr);
2476 restoreSplitFrames();
2477 for (AlignmentI ds : importedDatasets.keySet())
2479 if (ds.getCodonFrames() != null)
2481 StructureSelectionManager.getStructureSelectionManager(
2482 Desktop.instance).registerMappings(ds.getCodonFrames());
2485 if (errorMessage != null)
2490 if (Desktop.instance != null)
2492 Desktop.instance.stopLoading();
2499 * Try to reconstruct and display SplitFrame windows, where each contains
2500 * complementary dna and protein alignments. Done by pairing up AlignFrame
2501 * objects (created earlier) which have complementary viewport ids associated.
2503 protected void restoreSplitFrames()
2505 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2506 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2507 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2510 * Identify the DNA alignments
2512 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2515 AlignFrame af = candidate.getValue();
2516 if (af.getViewport().getAlignment().isNucleotide())
2518 dna.put(candidate.getKey().getId(), af);
2523 * Try to match up the protein complements
2525 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2528 AlignFrame af = candidate.getValue();
2529 if (!af.getViewport().getAlignment().isNucleotide())
2531 String complementId = candidate.getKey().getComplementId();
2532 // only non-null complements should be in the Map
2533 if (complementId != null && dna.containsKey(complementId))
2535 final AlignFrame dnaFrame = dna.get(complementId);
2536 SplitFrame sf = createSplitFrame(dnaFrame, af);
2537 addedToSplitFrames.add(dnaFrame);
2538 addedToSplitFrames.add(af);
2539 if (af.viewport.isGatherViewsHere())
2548 * Open any that we failed to pair up (which shouldn't happen!) as
2549 * standalone AlignFrame's.
2551 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2554 AlignFrame af = candidate.getValue();
2555 if (!addedToSplitFrames.contains(af))
2557 Viewport view = candidate.getKey();
2558 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2560 System.err.println("Failed to restore view " + view.getTitle()
2561 + " to split frame");
2566 * Gather back into tabbed views as flagged.
2568 for (SplitFrame sf : gatherTo)
2570 Desktop.instance.gatherViews(sf);
2573 splitFrameCandidates.clear();
2577 * Construct and display one SplitFrame holding DNA and protein alignments.
2580 * @param proteinFrame
2583 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2584 AlignFrame proteinFrame)
2586 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2587 String title = MessageManager.getString("label.linked_view_title");
2588 int width = (int) dnaFrame.getBounds().getWidth();
2589 int height = (int) (dnaFrame.getBounds().getHeight()
2590 + proteinFrame.getBounds().getHeight() + 50);
2593 * SplitFrame location is saved to both enclosed frames
2595 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2596 Desktop.addInternalFrame(splitFrame, title, width, height);
2599 * And compute cDNA consensus (couldn't do earlier with consensus as
2600 * mappings were not yet present)
2602 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2608 * check errorMessage for a valid error message and raise an error box in the
2609 * GUI or write the current errorMessage to stderr and then clear the error
2612 protected void reportErrors()
2614 reportErrors(false);
2617 protected void reportErrors(final boolean saving)
2619 if (errorMessage != null)
2621 final String finalErrorMessage = errorMessage;
2624 javax.swing.SwingUtilities.invokeLater(new Runnable()
2629 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2630 finalErrorMessage, "Error "
2631 + (saving ? "saving" : "loading")
2632 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2638 System.err.println("Problem loading Jalview file: " + errorMessage);
2641 errorMessage = null;
2644 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2647 * when set, local views will be updated from view stored in JalviewXML
2648 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2649 * sync if this is set to true.
2651 private final boolean updateLocalViews = false;
2654 * Returns the path to a temporary file holding the PDB file for the given PDB
2655 * id. The first time of asking, searches for a file of that name in the
2656 * Jalview project jar, and copies it to a new temporary file. Any repeat
2657 * requests just return the path to the file previously created.
2663 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2666 if (alreadyLoadedPDB.containsKey(pdbId))
2668 return alreadyLoadedPDB.get(pdbId).toString();
2671 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2673 if (tempFile != null)
2675 alreadyLoadedPDB.put(pdbId, tempFile);
2681 * Copies the jar entry of given name to a new temporary file and returns the
2682 * path to the file, or null if the entry is not found.
2685 * @param jarEntryName
2687 * a prefix for the temporary file name, must be at least three
2690 * null or original file - so new file can be given the same suffix
2694 protected String copyJarEntry(jarInputStreamProvider jprovider,
2695 String jarEntryName, String prefix, String origFile)
2697 BufferedReader in = null;
2698 PrintWriter out = null;
2699 String suffix = ".tmp";
2700 if (origFile == null)
2702 origFile = jarEntryName;
2704 int sfpos = origFile.lastIndexOf(".");
2705 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2707 suffix = "." + origFile.substring(sfpos + 1);
2711 JarInputStream jin = jprovider.getJarInputStream();
2713 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2714 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2715 * FileInputStream(jprovider)); }
2718 JarEntry entry = null;
2721 entry = jin.getNextJarEntry();
2722 } while (entry != null && !entry.getName().equals(jarEntryName));
2725 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2726 File outFile = File.createTempFile(prefix, suffix);
2727 outFile.deleteOnExit();
2728 out = new PrintWriter(new FileOutputStream(outFile));
2731 while ((data = in.readLine()) != null)
2736 String t = outFile.getAbsolutePath();
2741 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2743 } catch (Exception ex)
2745 ex.printStackTrace();
2753 } catch (IOException e)
2767 private class JvAnnotRow
2769 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2776 * persisted version of annotation row from which to take vis properties
2778 public jalview.datamodel.AlignmentAnnotation template;
2781 * original position of the annotation row in the alignment
2787 * Load alignment frame from jalview XML DOM object
2792 * filename source string
2793 * @param loadTreesAndStructures
2794 * when false only create Viewport
2796 * data source provider
2797 * @return alignment frame created from view stored in DOM
2799 AlignFrame loadFromObject(JalviewModel object, String file,
2800 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2802 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2803 Sequence[] vamsasSeq = vamsasSet.getSequence();
2805 JalviewModelSequence jms = object.getJalviewModelSequence();
2807 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2810 // ////////////////////////////////
2813 List<SequenceI> hiddenSeqs = null;
2816 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2818 boolean multipleView = false;
2819 SequenceI referenceseqForView = null;
2820 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2821 int vi = 0; // counter in vamsasSeq array
2822 for (int i = 0; i < jseqs.length; i++)
2824 String seqId = jseqs[i].getId();
2826 SequenceI tmpSeq = seqRefIds.get(seqId);
2829 if (!incompleteSeqs.containsKey(seqId))
2831 // may not need this check, but keep it for at least 2.9,1 release
2832 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2835 .println("Warning JAL-2154 regression: updating start/end for sequence "
2836 + tmpSeq.toString() + " to " + jseqs[i]);
2839 incompleteSeqs.remove(seqId);
2841 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2843 // most likely we are reading a dataset XML document so
2844 // update from vamsasSeq section of XML for this sequence
2845 tmpSeq.setName(vamsasSeq[vi].getName());
2846 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2847 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2852 // reading multiple views, so vamsasSeq set is a subset of JSeq
2853 multipleView = true;
2855 tmpSeq.setStart(jseqs[i].getStart());
2856 tmpSeq.setEnd(jseqs[i].getEnd());
2857 tmpseqs.add(tmpSeq);
2861 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2862 vamsasSeq[vi].getSequence());
2863 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2864 tmpSeq.setStart(jseqs[i].getStart());
2865 tmpSeq.setEnd(jseqs[i].getEnd());
2866 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2867 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2868 tmpseqs.add(tmpSeq);
2872 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2874 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2877 if (jseqs[i].getHidden())
2879 if (hiddenSeqs == null)
2881 hiddenSeqs = new ArrayList<SequenceI>();
2884 hiddenSeqs.add(tmpSeq);
2889 // Create the alignment object from the sequence set
2890 // ///////////////////////////////
2891 SequenceI[] orderedSeqs = tmpseqs
2892 .toArray(new SequenceI[tmpseqs.size()]);
2894 AlignmentI al = null;
2895 // so we must create or recover the dataset alignment before going further
2896 // ///////////////////////////////
2897 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2899 // older jalview projects do not have a dataset - so creat alignment and
2901 al = new Alignment(orderedSeqs);
2902 al.setDataset(null);
2906 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2909 // we are importing a dataset record, so
2910 // recover reference to an alignment already materialsed as dataset
2911 al = getDatasetFor(vamsasSet.getDatasetId());
2915 // materialse the alignment
2916 al = new Alignment(orderedSeqs);
2920 addDatasetRef(vamsasSet.getDatasetId(), al);
2923 // finally, verify all data in vamsasSet is actually present in al
2924 // passing on flag indicating if it is actually a stored dataset
2925 recoverDatasetFor(vamsasSet, al, isdsal);
2928 if (referenceseqForView != null)
2930 al.setSeqrep(referenceseqForView);
2932 // / Add the alignment properties
2933 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2935 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2936 al.setProperty(ssp.getKey(), ssp.getValue());
2939 // ///////////////////////////////
2941 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2944 // load sequence features, database references and any associated PDB
2945 // structures for the alignment
2947 // prior to 2.10, this part would only be executed the first time a
2948 // sequence was encountered, but not afterwards.
2949 // now, for 2.10 projects, this is also done if the xml doc includes
2950 // dataset sequences not actually present in any particular view.
2952 for (int i = 0; i < vamsasSeq.length; i++)
2954 if (jseqs[i].getFeaturesCount() > 0)
2956 Features[] features = jseqs[i].getFeatures();
2957 for (int f = 0; f < features.length; f++)
2959 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2960 features[f].getType(), features[f].getDescription(),
2961 features[f].getStatus(), features[f].getBegin(),
2962 features[f].getEnd(), features[f].getFeatureGroup());
2964 sf.setScore(features[f].getScore());
2965 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2967 OtherData keyValue = features[f].getOtherData(od);
2968 if (keyValue.getKey().startsWith("LINK"))
2970 sf.addLink(keyValue.getValue());
2974 sf.setValue(keyValue.getKey(), keyValue.getValue());
2978 // adds feature to datasequence's feature set (since Jalview 2.10)
2979 al.getSequenceAt(i).addSequenceFeature(sf);
2982 if (vamsasSeq[i].getDBRefCount() > 0)
2984 // adds dbrefs to datasequence's set (since Jalview 2.10)
2986 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
2987 : al.getSequenceAt(i).getDatasetSequence(),
2990 if (jseqs[i].getPdbidsCount() > 0)
2992 Pdbids[] ids = jseqs[i].getPdbids();
2993 for (int p = 0; p < ids.length; p++)
2995 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2996 entry.setId(ids[p].getId());
2997 if (ids[p].getType() != null)
2999 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3001 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3005 entry.setType(PDBEntry.Type.FILE);
3008 if (ids[p].getFile() != null)
3010 if (!pdbloaded.containsKey(ids[p].getFile()))
3012 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3017 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3020 if (ids[p].getPdbentryItem() != null)
3022 for (PdbentryItem item : ids[p].getPdbentryItem())
3024 for (Property pr : item.getProperty())
3026 entry.setProperty(pr.getName(), pr.getValue());
3030 StructureSelectionManager.getStructureSelectionManager(
3031 Desktop.instance).registerPDBEntry(entry);
3032 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3033 if (al.getSequenceAt(i).getDatasetSequence() != null)
3035 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3039 al.getSequenceAt(i).addPDBId(entry);
3044 } // end !multipleview
3046 // ///////////////////////////////
3047 // LOAD SEQUENCE MAPPINGS
3049 if (vamsasSet.getAlcodonFrameCount() > 0)
3051 // TODO Potentially this should only be done once for all views of an
3053 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3054 for (int i = 0; i < alc.length; i++)
3056 AlignedCodonFrame cf = new AlignedCodonFrame();
3057 if (alc[i].getAlcodMapCount() > 0)
3059 AlcodMap[] maps = alc[i].getAlcodMap();
3060 for (int m = 0; m < maps.length; m++)
3062 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3064 jalview.datamodel.Mapping mapping = null;
3065 // attach to dna sequence reference.
3066 if (maps[m].getMapping() != null)
3068 mapping = addMapping(maps[m].getMapping());
3069 if (dnaseq != null && mapping.getTo() != null)
3071 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3076 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3081 al.addCodonFrame(cf);
3086 // ////////////////////////////////
3088 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3091 * store any annotations which forward reference a group's ID
3093 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3095 if (vamsasSet.getAnnotationCount() > 0)
3097 Annotation[] an = vamsasSet.getAnnotation();
3099 for (int i = 0; i < an.length; i++)
3101 Annotation annotation = an[i];
3104 * test if annotation is automatically calculated for this view only
3106 boolean autoForView = false;
3107 if (annotation.getLabel().equals("Quality")
3108 || annotation.getLabel().equals("Conservation")
3109 || annotation.getLabel().equals("Consensus"))
3111 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3113 if (!annotation.hasAutoCalculated())
3115 annotation.setAutoCalculated(true);
3119 || (annotation.hasAutoCalculated() && annotation
3120 .isAutoCalculated()))
3122 // remove ID - we don't recover annotation from other views for
3123 // view-specific annotation
3124 annotation.setId(null);
3127 // set visiblity for other annotation in this view
3128 String annotationId = annotation.getId();
3129 if (annotationId != null && annotationIds.containsKey(annotationId))
3131 AlignmentAnnotation jda = annotationIds.get(annotationId);
3132 // in principle Visible should always be true for annotation displayed
3133 // in multiple views
3134 if (annotation.hasVisible())
3136 jda.visible = annotation.getVisible();
3139 al.addAnnotation(jda);
3143 // Construct new annotation from model.
3144 AnnotationElement[] ae = annotation.getAnnotationElement();
3145 jalview.datamodel.Annotation[] anot = null;
3146 java.awt.Color firstColour = null;
3148 if (!annotation.getScoreOnly())
3150 anot = new jalview.datamodel.Annotation[al.getWidth()];
3151 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3153 anpos = ae[aa].getPosition();
3155 if (anpos >= anot.length)
3160 anot[anpos] = new jalview.datamodel.Annotation(
3162 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3163 (ae[aa].getSecondaryStructure() == null || ae[aa]
3164 .getSecondaryStructure().length() == 0) ? ' '
3165 : ae[aa].getSecondaryStructure().charAt(0),
3169 // JBPNote: Consider verifying dataflow for IO of secondary
3170 // structure annotation read from Stockholm files
3171 // this was added to try to ensure that
3172 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3174 // anot[ae[aa].getPosition()].displayCharacter = "";
3176 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3177 if (firstColour == null)
3179 firstColour = anot[anpos].colour;
3183 jalview.datamodel.AlignmentAnnotation jaa = null;
3185 if (annotation.getGraph())
3187 float llim = 0, hlim = 0;
3188 // if (autoForView || an[i].isAutoCalculated()) {
3191 jaa = new jalview.datamodel.AlignmentAnnotation(
3192 annotation.getLabel(), annotation.getDescription(), anot,
3193 llim, hlim, annotation.getGraphType());
3195 jaa.graphGroup = annotation.getGraphGroup();
3196 jaa._linecolour = firstColour;
3197 if (annotation.getThresholdLine() != null)
3199 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3200 .getThresholdLine().getValue(), annotation
3201 .getThresholdLine().getLabel(), new java.awt.Color(
3202 annotation.getThresholdLine().getColour())));
3205 if (autoForView || annotation.isAutoCalculated())
3207 // Hardwire the symbol display line to ensure that labels for
3208 // histograms are displayed
3214 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3215 an[i].getDescription(), anot);
3216 jaa._linecolour = firstColour;
3218 // register new annotation
3219 if (an[i].getId() != null)
3221 annotationIds.put(an[i].getId(), jaa);
3222 jaa.annotationId = an[i].getId();
3224 // recover sequence association
3225 String sequenceRef = an[i].getSequenceRef();
3226 if (sequenceRef != null)
3228 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3229 SequenceI sequence = seqRefIds.get(sequenceRef);
3230 if (sequence == null)
3232 // in pre-2.9 projects sequence ref is to sequence name
3233 sequence = al.findName(sequenceRef);
3235 if (sequence != null)
3237 jaa.createSequenceMapping(sequence, 1, true);
3238 sequence.addAlignmentAnnotation(jaa);
3241 // and make a note of any group association
3242 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3244 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3245 .get(an[i].getGroupRef());
3248 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3249 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3254 if (an[i].hasScore())
3256 jaa.setScore(an[i].getScore());
3258 if (an[i].hasVisible())
3260 jaa.visible = an[i].getVisible();
3263 if (an[i].hasCentreColLabels())
3265 jaa.centreColLabels = an[i].getCentreColLabels();
3268 if (an[i].hasScaleColLabels())
3270 jaa.scaleColLabel = an[i].getScaleColLabels();
3272 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3274 // newer files have an 'autoCalculated' flag and store calculation
3275 // state in viewport properties
3276 jaa.autoCalculated = true; // means annotation will be marked for
3277 // update at end of load.
3279 if (an[i].hasGraphHeight())
3281 jaa.graphHeight = an[i].getGraphHeight();
3283 if (an[i].hasBelowAlignment())
3285 jaa.belowAlignment = an[i].isBelowAlignment();
3287 jaa.setCalcId(an[i].getCalcId());
3288 if (an[i].getPropertyCount() > 0)
3290 for (jalview.schemabinding.version2.Property prop : an[i]
3293 jaa.setProperty(prop.getName(), prop.getValue());
3296 if (jaa.autoCalculated)
3298 autoAlan.add(new JvAnnotRow(i, jaa));
3301 // if (!autoForView)
3303 // add autocalculated group annotation and any user created annotation
3305 al.addAnnotation(jaa);
3309 // ///////////////////////
3311 // Create alignment markup and styles for this view
3312 if (jms.getJGroupCount() > 0)
3314 JGroup[] groups = jms.getJGroup();
3315 boolean addAnnotSchemeGroup = false;
3316 for (int i = 0; i < groups.length; i++)
3318 JGroup jGroup = groups[i];
3319 ColourSchemeI cs = null;
3320 if (jGroup.getColour() != null)
3322 if (jGroup.getColour().startsWith("ucs"))
3324 cs = getUserColourScheme(jms, jGroup.getColour());
3326 else if (jGroup.getColour().equals("AnnotationColourGradient")
3327 && jGroup.getAnnotationColours() != null)
3329 addAnnotSchemeGroup = true;
3334 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3339 cs.setThreshold(jGroup.getPidThreshold(), true);
3343 Vector<SequenceI> seqs = new Vector<SequenceI>();
3345 for (int s = 0; s < jGroup.getSeqCount(); s++)
3347 String seqId = jGroup.getSeq(s) + "";
3348 SequenceI ts = seqRefIds.get(seqId);
3352 seqs.addElement(ts);
3356 if (seqs.size() < 1)
3361 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3362 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3363 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3365 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3367 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3368 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3369 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3370 .isShowUnconserved() : false);
3371 sg.thresholdTextColour = jGroup.getTextColThreshold();
3372 if (jGroup.hasShowConsensusHistogram())
3374 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3377 if (jGroup.hasShowSequenceLogo())
3379 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3381 if (jGroup.hasNormaliseSequenceLogo())
3383 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3385 if (jGroup.hasIgnoreGapsinConsensus())
3387 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3389 if (jGroup.getConsThreshold() != 0)
3391 Conservation c = new Conservation("All", 3,
3392 sg.getSequences(null), 0, sg.getWidth() - 1);
3394 c.verdict(false, 25);
3395 sg.cs.setConservation(c);
3398 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3400 // re-instate unique group/annotation row reference
3401 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3405 for (AlignmentAnnotation jaa : jaal)
3408 if (jaa.autoCalculated)
3410 // match up and try to set group autocalc alignment row for this
3412 if (jaa.label.startsWith("Consensus for "))
3414 sg.setConsensus(jaa);
3416 // match up and try to set group autocalc alignment row for this
3418 if (jaa.label.startsWith("Conservation for "))
3420 sg.setConservationRow(jaa);
3427 if (addAnnotSchemeGroup)
3429 // reconstruct the annotation colourscheme
3430 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3431 null, al, jms, false);
3437 // only dataset in this model, so just return.
3440 // ///////////////////////////////
3443 // If we just load in the same jar file again, the sequenceSetId
3444 // will be the same, and we end up with multiple references
3445 // to the same sequenceSet. We must modify this id on load
3446 // so that each load of the file gives a unique id
3447 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3448 String viewId = (view.getId() == null ? null : view.getId()
3450 AlignFrame af = null;
3451 AlignViewport av = null;
3452 // now check to see if we really need to create a new viewport.
3453 if (multipleView && viewportsAdded.size() == 0)
3455 // We recovered an alignment for which a viewport already exists.
3456 // TODO: fix up any settings necessary for overlaying stored state onto
3457 // state recovered from another document. (may not be necessary).
3458 // we may need a binding from a viewport in memory to one recovered from
3460 // and then recover its containing af to allow the settings to be applied.
3461 // TODO: fix for vamsas demo
3463 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3465 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3466 if (seqsetobj != null)
3468 if (seqsetobj instanceof String)
3470 uniqueSeqSetId = (String) seqsetobj;
3472 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3478 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3484 * indicate that annotation colours are applied across all groups (pre
3485 * Jalview 2.8.1 behaviour)
3487 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3488 "2.8.1", object.getVersion());
3490 AlignmentPanel ap = null;
3491 boolean isnewview = true;
3494 // Check to see if this alignment already has a view id == viewId
3495 jalview.gui.AlignmentPanel views[] = Desktop
3496 .getAlignmentPanels(uniqueSeqSetId);
3497 if (views != null && views.length > 0)
3499 for (int v = 0; v < views.length; v++)
3501 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3503 // recover the existing alignpanel, alignframe, viewport
3504 af = views[v].alignFrame;
3507 // TODO: could even skip resetting view settings if we don't want to
3508 // change the local settings from other jalview processes
3517 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3518 uniqueSeqSetId, viewId, autoAlan);
3524 * Load any trees, PDB structures and viewers
3526 * Not done if flag is false (when this method is used for New View)
3528 if (loadTreesAndStructures)
3530 loadTrees(jms, view, af, av, ap);
3531 loadPDBStructures(jprovider, jseqs, af, ap);
3532 loadRnaViewers(jprovider, jseqs, ap);
3534 // and finally return.
3539 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3540 * panel is restored from separate jar entries, two (gapped and trimmed) per
3541 * sequence and secondary structure.
3543 * Currently each viewer shows just one sequence and structure (gapped and
3544 * trimmed), however this method is designed to support multiple sequences or
3545 * structures in viewers if wanted in future.
3551 private void loadRnaViewers(jarInputStreamProvider jprovider,
3552 JSeq[] jseqs, AlignmentPanel ap)
3555 * scan the sequences for references to viewers; create each one the first
3556 * time it is referenced, add Rna models to existing viewers
3558 for (JSeq jseq : jseqs)
3560 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3562 RnaViewer viewer = jseq.getRnaViewer(i);
3563 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3564 uniqueSetSuffix, ap);
3566 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3568 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3569 SequenceI seq = seqRefIds.get(jseq.getId());
3570 AlignmentAnnotation ann = this.annotationIds.get(ss
3571 .getAnnotationId());
3574 * add the structure to the Varna display (with session state copied
3575 * from the jar to a temporary file)
3577 boolean gapped = ss.isGapped();
3578 String rnaTitle = ss.getTitle();
3579 String sessionState = ss.getViewerState();
3580 String tempStateFile = copyJarEntry(jprovider, sessionState,
3582 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3583 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3585 appVarna.setInitialSelection(viewer.getSelectedRna());
3591 * Locate and return an already instantiated matching AppVarna, or create one
3595 * @param viewIdSuffix
3599 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3600 String viewIdSuffix, AlignmentPanel ap)
3603 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3604 * if load is repeated
3606 String postLoadId = viewer.getViewId() + viewIdSuffix;
3607 for (JInternalFrame frame : getAllFrames())
3609 if (frame instanceof AppVarna)
3611 AppVarna varna = (AppVarna) frame;
3612 if (postLoadId.equals(varna.getViewId()))
3614 // this viewer is already instantiated
3615 // could in future here add ap as another 'parent' of the
3616 // AppVarna window; currently just 1-to-many
3623 * viewer not found - make it
3625 RnaViewerModel model = new RnaViewerModel(postLoadId,
3626 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3627 viewer.getWidth(), viewer.getHeight(),
3628 viewer.getDividerLocation());
3629 AppVarna varna = new AppVarna(model, ap);
3635 * Load any saved trees
3643 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3644 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3646 // TODO result of automated refactoring - are all these parameters needed?
3649 for (int t = 0; t < jms.getTreeCount(); t++)
3652 Tree tree = jms.getTree(t);
3654 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3657 tp = af.ShowNewickTree(
3658 new jalview.io.NewickFile(tree.getNewick()),
3659 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3660 tree.getXpos(), tree.getYpos());
3661 if (tree.getId() != null)
3663 // perhaps bind the tree id to something ?
3668 // update local tree attributes ?
3669 // TODO: should check if tp has been manipulated by user - if so its
3670 // settings shouldn't be modified
3671 tp.setTitle(tree.getTitle());
3672 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3673 .getWidth(), tree.getHeight()));
3674 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3677 tp.treeCanvas.av = av; // af.viewport;
3678 tp.treeCanvas.ap = ap; // af.alignPanel;
3683 warn("There was a problem recovering stored Newick tree: \n"
3684 + tree.getNewick());
3688 tp.fitToWindow.setState(tree.getFitToWindow());
3689 tp.fitToWindow_actionPerformed(null);
3691 if (tree.getFontName() != null)
3693 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3694 .getFontStyle(), tree.getFontSize()));
3698 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3699 .getFontStyle(), tree.getFontSize()));
3702 tp.showPlaceholders(tree.getMarkUnlinked());
3703 tp.showBootstrap(tree.getShowBootstrap());
3704 tp.showDistances(tree.getShowDistances());
3706 tp.treeCanvas.threshold = tree.getThreshold();
3708 if (tree.getCurrentTree())
3710 af.viewport.setCurrentTree(tp.getTree());
3714 } catch (Exception ex)
3716 ex.printStackTrace();
3721 * Load and link any saved structure viewers.
3728 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3729 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3732 * Run through all PDB ids on the alignment, and collect mappings between
3733 * distinct view ids and all sequences referring to that view.
3735 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3737 for (int i = 0; i < jseqs.length; i++)
3739 if (jseqs[i].getPdbidsCount() > 0)
3741 Pdbids[] ids = jseqs[i].getPdbids();
3742 for (int p = 0; p < ids.length; p++)
3744 final int structureStateCount = ids[p].getStructureStateCount();
3745 for (int s = 0; s < structureStateCount; s++)
3747 // check to see if we haven't already created this structure view
3748 final StructureState structureState = ids[p]
3749 .getStructureState(s);
3750 String sviewid = (structureState.getViewId() == null) ? null
3751 : structureState.getViewId() + uniqueSetSuffix;
3752 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3753 // Originally : ids[p].getFile()
3754 // : TODO: verify external PDB file recovery still works in normal
3755 // jalview project load
3756 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3758 jpdb.setId(ids[p].getId());
3760 int x = structureState.getXpos();
3761 int y = structureState.getYpos();
3762 int width = structureState.getWidth();
3763 int height = structureState.getHeight();
3765 // Probably don't need to do this anymore...
3766 // Desktop.desktop.getComponentAt(x, y);
3767 // TODO: NOW: check that this recovers the PDB file correctly.
3768 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3770 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3772 if (sviewid == null)
3774 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3777 if (!structureViewers.containsKey(sviewid))
3779 structureViewers.put(sviewid,
3780 new StructureViewerModel(x, y, width, height, false,
3781 false, true, structureState.getViewId(),
3782 structureState.getType()));
3783 // Legacy pre-2.7 conversion JAL-823 :
3784 // do not assume any view has to be linked for colour by
3788 // assemble String[] { pdb files }, String[] { id for each
3789 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3790 // seqs_file 2}, boolean[] {
3791 // linkAlignPanel,superposeWithAlignpanel}} from hash
3792 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3793 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3794 | (structureState.hasAlignwithAlignPanel() ? structureState
3795 .getAlignwithAlignPanel() : false));
3798 * Default colour by linked panel to false if not specified (e.g.
3799 * for pre-2.7 projects)
3801 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3802 colourWithAlignPanel |= (structureState
3803 .hasColourwithAlignPanel() ? structureState
3804 .getColourwithAlignPanel() : false);
3805 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3808 * Default colour by viewer to true if not specified (e.g. for
3811 boolean colourByViewer = jmoldat.isColourByViewer();
3812 colourByViewer &= structureState.hasColourByJmol() ? structureState
3813 .getColourByJmol() : true;
3814 jmoldat.setColourByViewer(colourByViewer);
3816 if (jmoldat.getStateData().length() < structureState
3817 .getContent().length())
3820 jmoldat.setStateData(structureState.getContent());
3823 if (ids[p].getFile() != null)
3825 File mapkey = new File(ids[p].getFile());
3826 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3827 if (seqstrmaps == null)
3829 jmoldat.getFileData().put(
3831 seqstrmaps = jmoldat.new StructureData(pdbFile,
3834 if (!seqstrmaps.getSeqList().contains(seq))
3836 seqstrmaps.getSeqList().add(seq);
3842 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");
3849 // Instantiate the associated structure views
3850 for (Entry<String, StructureViewerModel> entry : structureViewers
3855 createOrLinkStructureViewer(entry, af, ap, jprovider);
3856 } catch (Exception e)
3858 System.err.println("Error loading structure viewer: "
3860 // failed - try the next one
3872 protected void createOrLinkStructureViewer(
3873 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3874 AlignmentPanel ap, jarInputStreamProvider jprovider)
3876 final StructureViewerModel stateData = viewerData.getValue();
3879 * Search for any viewer windows already open from other alignment views
3880 * that exactly match the stored structure state
3882 StructureViewerBase comp = findMatchingViewer(viewerData);
3886 linkStructureViewer(ap, comp, stateData);
3891 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3892 * "viewer_"+stateData.viewId
3894 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3896 createChimeraViewer(viewerData, af, jprovider);
3901 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3903 createJmolViewer(viewerData, af, jprovider);
3908 * Create a new Chimera viewer.
3914 protected void createChimeraViewer(
3915 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3916 jarInputStreamProvider jprovider)
3918 StructureViewerModel data = viewerData.getValue();
3919 String chimeraSessionFile = data.getStateData();
3922 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3924 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3925 * 'uniquified' sviewid used to reconstruct the viewer here
3927 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3928 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3931 Set<Entry<File, StructureData>> fileData = data.getFileData()
3933 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3934 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3935 for (Entry<File, StructureData> pdb : fileData)
3937 String filePath = pdb.getValue().getFilePath();
3938 String pdbId = pdb.getValue().getPdbId();
3939 // pdbs.add(new PDBEntry(filePath, pdbId));
3940 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3941 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3942 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3946 boolean colourByChimera = data.isColourByViewer();
3947 boolean colourBySequence = data.isColourWithAlignPanel();
3949 // TODO use StructureViewer as a factory here, see JAL-1761
3950 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3951 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3953 String newViewId = viewerData.getKey();
3955 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3956 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3957 colourBySequence, newViewId);
3958 cvf.setSize(data.getWidth(), data.getHeight());
3959 cvf.setLocation(data.getX(), data.getY());
3963 * Create a new Jmol window. First parse the Jmol state to translate filenames
3964 * loaded into the view, and record the order in which files are shown in the
3965 * Jmol view, so we can add the sequence mappings in same order.
3971 protected void createJmolViewer(
3972 final Entry<String, StructureViewerModel> viewerData,
3973 AlignFrame af, jarInputStreamProvider jprovider)
3975 final StructureViewerModel svattrib = viewerData.getValue();
3976 String state = svattrib.getStateData();
3979 * Pre-2.9: state element value is the Jmol state string
3981 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3984 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3986 state = readJarEntry(jprovider,
3987 getViewerJarEntryName(svattrib.getViewId()));
3990 List<String> pdbfilenames = new ArrayList<String>();
3991 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3992 List<String> pdbids = new ArrayList<String>();
3993 StringBuilder newFileLoc = new StringBuilder(64);
3994 int cp = 0, ncp, ecp;
3995 Map<File, StructureData> oldFiles = svattrib.getFileData();
3996 while ((ncp = state.indexOf("load ", cp)) > -1)
4000 // look for next filename in load statement
4001 newFileLoc.append(state.substring(cp,
4002 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4003 String oldfilenam = state.substring(ncp,
4004 ecp = state.indexOf("\"", ncp));
4005 // recover the new mapping data for this old filename
4006 // have to normalize filename - since Jmol and jalview do
4008 // translation differently.
4009 StructureData filedat = oldFiles.get(new File(oldfilenam));
4010 if (filedat == null)
4012 String reformatedOldFilename = oldfilenam.replaceAll("/",
4014 filedat = oldFiles.get(new File(reformatedOldFilename));
4016 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4017 pdbfilenames.add(filedat.getFilePath());
4018 pdbids.add(filedat.getPdbId());
4019 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4020 newFileLoc.append("\"");
4021 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4022 // look for next file statement.
4023 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4027 // just append rest of state
4028 newFileLoc.append(state.substring(cp));
4032 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4033 newFileLoc = new StringBuilder(state);
4034 newFileLoc.append("; load append ");
4035 for (File id : oldFiles.keySet())
4037 // add this and any other pdb files that should be present in
4039 StructureData filedat = oldFiles.get(id);
4040 newFileLoc.append(filedat.getFilePath());
4041 pdbfilenames.add(filedat.getFilePath());
4042 pdbids.add(filedat.getPdbId());
4043 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4044 newFileLoc.append(" \"");
4045 newFileLoc.append(filedat.getFilePath());
4046 newFileLoc.append("\"");
4049 newFileLoc.append(";");
4052 if (newFileLoc.length() == 0)
4056 int histbug = newFileLoc.indexOf("history = ");
4060 * change "history = [true|false];" to "history = [1|0];"
4063 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4064 String val = (diff == -1) ? null : newFileLoc
4065 .substring(histbug, diff);
4066 if (val != null && val.length() >= 4)
4068 if (val.contains("e")) // eh? what can it be?
4070 if (val.trim().equals("true"))
4078 newFileLoc.replace(histbug, diff, val);
4083 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4085 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4086 final SequenceI[][] sq = seqmaps
4087 .toArray(new SequenceI[seqmaps.size()][]);
4088 final String fileloc = newFileLoc.toString();
4089 final String sviewid = viewerData.getKey();
4090 final AlignFrame alf = af;
4091 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4092 svattrib.getWidth(), svattrib.getHeight());
4095 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4100 JalviewStructureDisplayI sview = null;
4103 sview = new StructureViewer(alf.alignPanel
4104 .getStructureSelectionManager()).createView(
4105 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4106 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4107 addNewStructureViewer(sview);
4108 } catch (OutOfMemoryError ex)
4110 new OOMWarning("restoring structure view for PDB id " + id,
4111 (OutOfMemoryError) ex.getCause());
4112 if (sview != null && sview.isVisible())
4114 sview.closeViewer(false);
4115 sview.setVisible(false);
4121 } catch (InvocationTargetException ex)
4123 warn("Unexpected error when opening Jmol view.", ex);
4125 } catch (InterruptedException e)
4127 // e.printStackTrace();
4133 * Generates a name for the entry in the project jar file to hold state
4134 * information for a structure viewer
4139 protected String getViewerJarEntryName(String viewId)
4141 return VIEWER_PREFIX + viewId;
4145 * Returns any open frame that matches given structure viewer data. The match
4146 * is based on the unique viewId, or (for older project versions) the frame's
4152 protected StructureViewerBase findMatchingViewer(
4153 Entry<String, StructureViewerModel> viewerData)
4155 final String sviewid = viewerData.getKey();
4156 final StructureViewerModel svattrib = viewerData.getValue();
4157 StructureViewerBase comp = null;
4158 JInternalFrame[] frames = getAllFrames();
4159 for (JInternalFrame frame : frames)
4161 if (frame instanceof StructureViewerBase)
4164 * Post jalview 2.4 schema includes structure view id
4167 && ((StructureViewerBase) frame).getViewId()
4170 comp = (StructureViewerBase) frame;
4171 break; // break added in 2.9
4174 * Otherwise test for matching position and size of viewer frame
4176 else if (frame.getX() == svattrib.getX()
4177 && frame.getY() == svattrib.getY()
4178 && frame.getHeight() == svattrib.getHeight()
4179 && frame.getWidth() == svattrib.getWidth())
4181 comp = (StructureViewerBase) frame;
4182 // no break in faint hope of an exact match on viewId
4190 * Link an AlignmentPanel to an existing structure viewer.
4195 * @param useinViewerSuperpos
4196 * @param usetoColourbyseq
4197 * @param viewerColouring
4199 protected void linkStructureViewer(AlignmentPanel ap,
4200 StructureViewerBase viewer, StructureViewerModel stateData)
4202 // NOTE: if the jalview project is part of a shared session then
4203 // view synchronization should/could be done here.
4205 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4206 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4207 final boolean viewerColouring = stateData.isColourByViewer();
4208 Map<File, StructureData> oldFiles = stateData.getFileData();
4211 * Add mapping for sequences in this view to an already open viewer
4213 final AAStructureBindingModel binding = viewer.getBinding();
4214 for (File id : oldFiles.keySet())
4216 // add this and any other pdb files that should be present in the
4218 StructureData filedat = oldFiles.get(id);
4219 String pdbFile = filedat.getFilePath();
4220 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4221 binding.getSsm().setMapping(seq, null, pdbFile,
4222 jalview.io.AppletFormatAdapter.FILE);
4223 binding.addSequenceForStructFile(pdbFile, seq);
4225 // and add the AlignmentPanel's reference to the view panel
4226 viewer.addAlignmentPanel(ap);
4227 if (useinViewerSuperpos)
4229 viewer.useAlignmentPanelForSuperposition(ap);
4233 viewer.excludeAlignmentPanelForSuperposition(ap);
4235 if (usetoColourbyseq)
4237 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4241 viewer.excludeAlignmentPanelForColourbyseq(ap);
4246 * Get all frames within the Desktop.
4250 protected JInternalFrame[] getAllFrames()
4252 JInternalFrame[] frames = null;
4253 // TODO is this necessary - is it safe - risk of hanging?
4258 frames = Desktop.desktop.getAllFrames();
4259 } catch (ArrayIndexOutOfBoundsException e)
4261 // occasional No such child exceptions are thrown here...
4265 } catch (InterruptedException f)
4269 } while (frames == null);
4274 * Answers true if 'version' is equal to or later than 'supported', where each
4275 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4276 * changes. Development and test values for 'version' are leniently treated
4280 * - minimum version we are comparing against
4282 * - version of data being processsed
4285 public static boolean isVersionStringLaterThan(String supported,
4288 if (supported == null || version == null
4289 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4290 || version.equalsIgnoreCase("Test")
4291 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4293 System.err.println("Assuming project file with "
4294 + (version == null ? "null" : version)
4295 + " is compatible with Jalview version " + supported);
4300 return StringUtils.compareVersions(version, supported, "b") >= 0;
4304 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4306 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4308 if (newStructureViewers != null)
4310 sview.getBinding().setFinishedLoadingFromArchive(false);
4311 newStructureViewers.add(sview);
4315 protected void setLoadingFinishedForNewStructureViewers()
4317 if (newStructureViewers != null)
4319 for (JalviewStructureDisplayI sview : newStructureViewers)
4321 sview.getBinding().setFinishedLoadingFromArchive(true);
4323 newStructureViewers.clear();
4324 newStructureViewers = null;
4328 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4329 List<SequenceI> hiddenSeqs, AlignmentI al,
4330 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4331 String viewId, List<JvAnnotRow> autoAlan)
4333 AlignFrame af = null;
4334 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4335 uniqueSeqSetId, viewId);
4337 af.setFileName(file, "Jalview");
4339 for (int i = 0; i < JSEQ.length; i++)
4341 af.viewport.setSequenceColour(af.viewport.getAlignment()
4342 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4347 af.getViewport().setColourByReferenceSeq(true);
4348 af.getViewport().setDisplayReferenceSeq(true);
4351 af.viewport.setGatherViewsHere(view.getGatheredViews());
4353 if (view.getSequenceSetId() != null)
4355 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4357 af.viewport.setSequenceSetId(uniqueSeqSetId);
4360 // propagate shared settings to this new view
4361 af.viewport.setHistoryList(av.getHistoryList());
4362 af.viewport.setRedoList(av.getRedoList());
4366 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4368 // TODO: check if this method can be called repeatedly without
4369 // side-effects if alignpanel already registered.
4370 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4372 // apply Hidden regions to view.
4373 if (hiddenSeqs != null)
4375 for (int s = 0; s < JSEQ.length; s++)
4377 SequenceGroup hidden = new SequenceGroup();
4378 boolean isRepresentative = false;
4379 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4381 isRepresentative = true;
4382 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4383 .getHiddenSequences(r));
4384 hidden.addSequence(sequenceToHide, false);
4385 // remove from hiddenSeqs list so we don't try to hide it twice
4386 hiddenSeqs.remove(sequenceToHide);
4388 if (isRepresentative)
4390 SequenceI representativeSequence = al.getSequenceAt(s);
4391 hidden.addSequence(representativeSequence, false);
4392 af.viewport.hideRepSequences(representativeSequence, hidden);
4396 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4398 af.viewport.hideSequence(hseqs);
4401 // recover view properties and display parameters
4402 if (view.getViewName() != null)
4404 af.viewport.viewName = view.getViewName();
4405 af.setInitialTabVisible();
4407 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4410 af.viewport.setShowAnnotation(view.getShowAnnotation());
4411 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4413 af.viewport.setColourText(view.getShowColourText());
4415 af.viewport.setConservationSelected(view.getConservationSelected());
4416 af.viewport.setShowJVSuffix(view.getShowFullId());
4417 af.viewport.setRightAlignIds(view.getRightAlignIds());
4418 af.viewport.setFont(
4419 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4420 .getFontSize()), true);
4421 ViewStyleI vs = af.viewport.getViewStyle();
4422 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4423 af.viewport.setViewStyle(vs);
4424 // TODO: allow custom charWidth/Heights to be restored by updating them
4425 // after setting font - which means set above to false
4426 af.viewport.setRenderGaps(view.getRenderGaps());
4427 af.viewport.setWrapAlignment(view.getWrapAlignment());
4428 af.viewport.setShowAnnotation(view.getShowAnnotation());
4430 af.viewport.setShowBoxes(view.getShowBoxes());
4432 af.viewport.setShowText(view.getShowText());
4434 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4435 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4436 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4437 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4438 .isShowUnconserved() : false);
4439 af.viewport.setStartRes(view.getStartRes());
4440 af.viewport.setStartSeq(view.getStartSeq());
4441 af.alignPanel.updateLayout();
4442 ColourSchemeI cs = null;
4443 // apply colourschemes
4444 if (view.getBgColour() != null)
4446 if (view.getBgColour().startsWith("ucs"))
4448 cs = getUserColourScheme(jms, view.getBgColour());
4450 else if (view.getBgColour().startsWith("Annotation"))
4452 AnnotationColours viewAnnColour = view.getAnnotationColours();
4453 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4460 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4465 cs.setThreshold(view.getPidThreshold(), true);
4466 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4470 af.viewport.setGlobalColourScheme(cs);
4471 af.viewport.setColourAppliesToAllGroups(false);
4473 if (view.getConservationSelected() && cs != null)
4475 cs.setConservationInc(view.getConsThreshold());
4478 af.changeColour(cs);
4480 af.viewport.setColourAppliesToAllGroups(true);
4482 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4484 if (view.hasCentreColumnLabels())
4486 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4488 if (view.hasIgnoreGapsinConsensus())
4490 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4493 if (view.hasFollowHighlight())
4495 af.viewport.setFollowHighlight(view.getFollowHighlight());
4497 if (view.hasFollowSelection())
4499 af.viewport.followSelection = view.getFollowSelection();
4501 if (view.hasShowConsensusHistogram())
4503 af.viewport.setShowConsensusHistogram(view
4504 .getShowConsensusHistogram());
4508 af.viewport.setShowConsensusHistogram(true);
4510 if (view.hasShowSequenceLogo())
4512 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4516 af.viewport.setShowSequenceLogo(false);
4518 if (view.hasNormaliseSequenceLogo())
4520 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4522 if (view.hasShowDbRefTooltip())
4524 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4526 if (view.hasShowNPfeatureTooltip())
4528 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4530 if (view.hasShowGroupConsensus())
4532 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4536 af.viewport.setShowGroupConsensus(false);
4538 if (view.hasShowGroupConservation())
4540 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4544 af.viewport.setShowGroupConservation(false);
4547 // recover featre settings
4548 if (jms.getFeatureSettings() != null)
4550 FeaturesDisplayed fdi;
4551 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4552 String[] renderOrder = new String[jms.getFeatureSettings()
4553 .getSettingCount()];
4554 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4555 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4557 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4559 Setting setting = jms.getFeatureSettings().getSetting(fs);
4560 if (setting.hasMincolour())
4562 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4563 new Color(setting.getMincolour()), new Color(
4564 setting.getColour()), setting.getMin(),
4565 setting.getMax()) : new FeatureColour(new Color(
4566 setting.getMincolour()), new Color(setting.getColour()),
4568 if (setting.hasThreshold())
4570 gc.setThreshold(setting.getThreshold());
4571 int threshstate = setting.getThreshstate();
4572 // -1 = None, 0 = Below, 1 = Above threshold
4573 if (threshstate == 0)
4575 gc.setBelowThreshold(true);
4577 else if (threshstate == 1)
4579 gc.setAboveThreshold(true);
4582 gc.setAutoScaled(true); // default
4583 if (setting.hasAutoScale())
4585 gc.setAutoScaled(setting.getAutoScale());
4587 if (setting.hasColourByLabel())
4589 gc.setColourByLabel(setting.getColourByLabel());
4591 // and put in the feature colour table.
4592 featureColours.put(setting.getType(), gc);
4596 featureColours.put(setting.getType(), new FeatureColour(
4597 new Color(setting.getColour())));
4599 renderOrder[fs] = setting.getType();
4600 if (setting.hasOrder())
4602 featureOrder.put(setting.getType(), setting.getOrder());
4606 featureOrder.put(setting.getType(), new Float(fs
4607 / jms.getFeatureSettings().getSettingCount()));
4609 if (setting.getDisplay())
4611 fdi.setVisible(setting.getType());
4614 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4615 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4617 Group grp = jms.getFeatureSettings().getGroup(gs);
4618 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4620 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4621 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4622 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4623 FeatureRendererSettings frs = new FeatureRendererSettings(
4624 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4625 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4626 .transferSettings(frs);
4630 if (view.getHiddenColumnsCount() > 0)
4632 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4634 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4635 .getHiddenColumns(c).getEnd() // +1
4639 if (view.getCalcIdParam() != null)
4641 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4643 if (calcIdParam != null)
4645 if (recoverCalcIdParam(calcIdParam, af.viewport))
4650 warn("Couldn't recover parameters for "
4651 + calcIdParam.getCalcId());
4656 af.setMenusFromViewport(af.viewport);
4657 af.setTitle(view.getTitle());
4658 // TODO: we don't need to do this if the viewport is aready visible.
4660 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4661 * has a 'cdna/protein complement' view, in which case save it in order to
4662 * populate a SplitFrame once all views have been read in.
4664 String complementaryViewId = view.getComplementId();
4665 if (complementaryViewId == null)
4667 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4669 // recompute any autoannotation
4670 af.alignPanel.updateAnnotation(false, true);
4671 reorderAutoannotation(af, al, autoAlan);
4672 af.alignPanel.alignmentChanged();
4676 splitFrameCandidates.put(view, af);
4681 private ColourSchemeI constructAnnotationColour(
4682 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4683 JalviewModelSequence jms, boolean checkGroupAnnColour)
4685 boolean propagateAnnColour = false;
4686 ColourSchemeI cs = null;
4687 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4688 if (checkGroupAnnColour && al.getGroups() != null
4689 && al.getGroups().size() > 0)
4691 // pre 2.8.1 behaviour
4692 // check to see if we should transfer annotation colours
4693 propagateAnnColour = true;
4694 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4696 if (sg.cs instanceof AnnotationColourGradient)
4698 propagateAnnColour = false;
4702 // int find annotation
4703 if (annAlignment.getAlignmentAnnotation() != null)
4705 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4707 if (annAlignment.getAlignmentAnnotation()[i].label
4708 .equals(viewAnnColour.getAnnotation()))
4710 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4712 annAlignment.getAlignmentAnnotation()[i]
4713 .setThreshold(new jalview.datamodel.GraphLine(
4714 viewAnnColour.getThreshold(), "Threshold",
4715 java.awt.Color.black)
4720 if (viewAnnColour.getColourScheme().equals("None"))
4722 cs = new AnnotationColourGradient(
4723 annAlignment.getAlignmentAnnotation()[i],
4724 new java.awt.Color(viewAnnColour.getMinColour()),
4725 new java.awt.Color(viewAnnColour.getMaxColour()),
4726 viewAnnColour.getAboveThreshold());
4728 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4730 cs = new AnnotationColourGradient(
4731 annAlignment.getAlignmentAnnotation()[i],
4732 getUserColourScheme(jms,
4733 viewAnnColour.getColourScheme()),
4734 viewAnnColour.getAboveThreshold());
4738 cs = new AnnotationColourGradient(
4739 annAlignment.getAlignmentAnnotation()[i],
4740 ColourSchemeProperty.getColour(al,
4741 viewAnnColour.getColourScheme()),
4742 viewAnnColour.getAboveThreshold());
4744 if (viewAnnColour.hasPerSequence())
4746 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4749 if (viewAnnColour.hasPredefinedColours())
4751 ((AnnotationColourGradient) cs)
4752 .setPredefinedColours(viewAnnColour
4753 .isPredefinedColours());
4755 if (propagateAnnColour && al.getGroups() != null)
4757 // Also use these settings for all the groups
4758 for (int g = 0; g < al.getGroups().size(); g++)
4760 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4768 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4769 * new AnnotationColourGradient(
4770 * annAlignment.getAlignmentAnnotation()[i], new
4771 * java.awt.Color(viewAnnColour. getMinColour()), new
4772 * java.awt.Color(viewAnnColour. getMaxColour()),
4773 * viewAnnColour.getAboveThreshold()); } else
4776 sg.cs = new AnnotationColourGradient(
4777 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4778 viewAnnColour.getAboveThreshold());
4779 if (cs instanceof AnnotationColourGradient)
4781 if (viewAnnColour.hasPerSequence())
4783 ((AnnotationColourGradient) cs)
4784 .setSeqAssociated(viewAnnColour.isPerSequence());
4786 if (viewAnnColour.hasPredefinedColours())
4788 ((AnnotationColourGradient) cs)
4789 .setPredefinedColours(viewAnnColour
4790 .isPredefinedColours());
4806 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4807 List<JvAnnotRow> autoAlan)
4809 // copy over visualization settings for autocalculated annotation in the
4811 if (al.getAlignmentAnnotation() != null)
4814 * Kludge for magic autoannotation names (see JAL-811)
4816 String[] magicNames = new String[] { "Consensus", "Quality",
4818 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4819 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4820 for (String nm : magicNames)
4822 visan.put(nm, nullAnnot);
4824 for (JvAnnotRow auan : autoAlan)
4826 visan.put(auan.template.label
4827 + (auan.template.getCalcId() == null ? "" : "\t"
4828 + auan.template.getCalcId()), auan);
4830 int hSize = al.getAlignmentAnnotation().length;
4831 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4832 // work through any autoCalculated annotation already on the view
4833 // removing it if it should be placed in a different location on the
4834 // annotation panel.
4835 List<String> remains = new ArrayList<String>(visan.keySet());
4836 for (int h = 0; h < hSize; h++)
4838 jalview.datamodel.AlignmentAnnotation jalan = al
4839 .getAlignmentAnnotation()[h];
4840 if (jalan.autoCalculated)
4843 JvAnnotRow valan = visan.get(k = jalan.label);
4844 if (jalan.getCalcId() != null)
4846 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4851 // delete the auto calculated row from the alignment
4852 al.deleteAnnotation(jalan, false);
4856 if (valan != nullAnnot)
4858 if (jalan != valan.template)
4860 // newly created autoannotation row instance
4861 // so keep a reference to the visible annotation row
4862 // and copy over all relevant attributes
4863 if (valan.template.graphHeight >= 0)
4866 jalan.graphHeight = valan.template.graphHeight;
4868 jalan.visible = valan.template.visible;
4870 reorder.add(new JvAnnotRow(valan.order, jalan));
4875 // Add any (possibly stale) autocalculated rows that were not appended to
4876 // the view during construction
4877 for (String other : remains)
4879 JvAnnotRow othera = visan.get(other);
4880 if (othera != nullAnnot && othera.template.getCalcId() != null
4881 && othera.template.getCalcId().length() > 0)
4883 reorder.add(othera);
4886 // now put the automatic annotation in its correct place
4887 int s = 0, srt[] = new int[reorder.size()];
4888 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4889 for (JvAnnotRow jvar : reorder)
4892 srt[s++] = jvar.order;
4895 jalview.util.QuickSort.sort(srt, rws);
4896 // and re-insert the annotation at its correct position
4897 for (JvAnnotRow jvar : rws)
4899 al.addAnnotation(jvar.template, jvar.order);
4901 af.alignPanel.adjustAnnotationHeight();
4905 Hashtable skipList = null;
4908 * TODO remove this method
4911 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4912 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4913 * throw new Error("Implementation Error. No skipList defined for this
4914 * Jalview2XML instance."); } return (AlignFrame)
4915 * skipList.get(view.getSequenceSetId()); }
4919 * Check if the Jalview view contained in object should be skipped or not.
4922 * @return true if view's sequenceSetId is a key in skipList
4924 private boolean skipViewport(JalviewModel object)
4926 if (skipList == null)
4931 if (skipList.containsKey(id = object.getJalviewModelSequence()
4932 .getViewport()[0].getSequenceSetId()))
4934 if (Cache.log != null && Cache.log.isDebugEnabled())
4936 Cache.log.debug("Skipping seuqence set id " + id);
4943 public void addToSkipList(AlignFrame af)
4945 if (skipList == null)
4947 skipList = new Hashtable();
4949 skipList.put(af.getViewport().getSequenceSetId(), af);
4952 public void clearSkipList()
4954 if (skipList != null)
4961 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4962 boolean ignoreUnrefed)
4964 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4966 Vector dseqs = null;
4969 // create a list of new dataset sequences
4970 dseqs = new Vector();
4972 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4974 Sequence vamsasSeq = vamsasSet.getSequence(i);
4975 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4977 // create a new dataset
4980 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4981 dseqs.copyInto(dsseqs);
4982 ds = new jalview.datamodel.Alignment(dsseqs);
4983 debug("Created new dataset " + vamsasSet.getDatasetId()
4984 + " for alignment " + System.identityHashCode(al));
4985 addDatasetRef(vamsasSet.getDatasetId(), ds);
4987 // set the dataset for the newly imported alignment.
4988 if (al.getDataset() == null && !ignoreUnrefed)
4997 * sequence definition to create/merge dataset sequence for
5001 * vector to add new dataset sequence to
5002 * @param ignoreUnrefed
5003 * - when true, don't create new sequences from vamsasSeq if it's id
5004 * doesn't already have an asssociated Jalview sequence.
5006 * - used to reorder the sequence in the alignment according to the
5007 * vamsasSeq array ordering, to preserve ordering of dataset
5009 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5010 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5012 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5014 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5015 boolean reorder = false;
5016 SequenceI dsq = null;
5017 if (sq != null && sq.getDatasetSequence() != null)
5019 dsq = sq.getDatasetSequence();
5025 if (sq == null && ignoreUnrefed)
5029 String sqid = vamsasSeq.getDsseqid();
5032 // need to create or add a new dataset sequence reference to this sequence
5035 dsq = seqRefIds.get(sqid);
5040 // make a new dataset sequence
5041 dsq = sq.createDatasetSequence();
5044 // make up a new dataset reference for this sequence
5045 sqid = seqHash(dsq);
5047 dsq.setVamsasId(uniqueSetSuffix + sqid);
5048 seqRefIds.put(sqid, dsq);
5053 dseqs.addElement(dsq);
5058 ds.addSequence(dsq);
5064 { // make this dataset sequence sq's dataset sequence
5065 sq.setDatasetSequence(dsq);
5066 // and update the current dataset alignment
5071 if (!dseqs.contains(dsq))
5078 if (ds.findIndex(dsq) < 0)
5080 ds.addSequence(dsq);
5087 // TODO: refactor this as a merge dataset sequence function
5088 // now check that sq (the dataset sequence) sequence really is the union of
5089 // all references to it
5090 // boolean pre = sq.getStart() < dsq.getStart();
5091 // boolean post = sq.getEnd() > dsq.getEnd();
5095 // StringBuffer sb = new StringBuffer();
5096 String newres = jalview.analysis.AlignSeq.extractGaps(
5097 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5098 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5099 && newres.length() > dsq.getLength())
5101 // Update with the longer sequence.
5105 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5106 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5107 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5108 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5110 dsq.setSequence(newres);
5112 // TODO: merges will never happen if we 'know' we have the real dataset
5113 // sequence - this should be detected when id==dssid
5115 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5116 // + (pre ? "prepended" : "") + " "
5117 // + (post ? "appended" : ""));
5122 // sequence refs are identical. We may need to update the existing dataset
5123 // alignment with this one, though.
5124 if (ds != null && dseqs == null)
5126 int opos = ds.findIndex(dsq);
5127 SequenceI tseq = null;
5128 if (opos != -1 && vseqpos != opos)
5130 // remove from old position
5131 ds.deleteSequence(dsq);
5133 if (vseqpos < ds.getHeight())
5135 if (vseqpos != opos)
5137 // save sequence at destination position
5138 tseq = ds.getSequenceAt(vseqpos);
5139 ds.replaceSequenceAt(vseqpos, dsq);
5140 ds.addSequence(tseq);
5145 ds.addSequence(dsq);
5152 * TODO use AlignmentI here and in related methods - needs
5153 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5155 Hashtable<String, AlignmentI> datasetIds = null;
5157 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5159 private AlignmentI getDatasetFor(String datasetId)
5161 if (datasetIds == null)
5163 datasetIds = new Hashtable<String, AlignmentI>();
5166 if (datasetIds.containsKey(datasetId))
5168 return datasetIds.get(datasetId);
5173 private void addDatasetRef(String datasetId, AlignmentI dataset)
5175 if (datasetIds == null)
5177 datasetIds = new Hashtable<String, AlignmentI>();
5179 datasetIds.put(datasetId, dataset);
5183 * make a new dataset ID for this jalview dataset alignment
5188 private String getDatasetIdRef(AlignmentI dataset)
5190 if (dataset.getDataset() != null)
5192 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5194 String datasetId = makeHashCode(dataset, null);
5195 if (datasetId == null)
5197 // make a new datasetId and record it
5198 if (dataset2Ids == null)
5200 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5204 datasetId = dataset2Ids.get(dataset);
5206 if (datasetId == null)
5208 datasetId = "ds" + dataset2Ids.size() + 1;
5209 dataset2Ids.put(dataset, datasetId);
5215 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5217 for (int d = 0; d < sequence.getDBRefCount(); d++)
5219 DBRef dr = sequence.getDBRef(d);
5220 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5221 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5222 .getVersion(), sequence.getDBRef(d).getAccessionId());
5223 if (dr.getMapping() != null)
5225 entry.setMap(addMapping(dr.getMapping()));
5227 datasetSequence.addDBRef(entry);
5231 private jalview.datamodel.Mapping addMapping(Mapping m)
5233 SequenceI dsto = null;
5234 // Mapping m = dr.getMapping();
5235 int fr[] = new int[m.getMapListFromCount() * 2];
5236 Enumeration f = m.enumerateMapListFrom();
5237 for (int _i = 0; f.hasMoreElements(); _i += 2)
5239 MapListFrom mf = (MapListFrom) f.nextElement();
5240 fr[_i] = mf.getStart();
5241 fr[_i + 1] = mf.getEnd();
5243 int fto[] = new int[m.getMapListToCount() * 2];
5244 f = m.enumerateMapListTo();
5245 for (int _i = 0; f.hasMoreElements(); _i += 2)
5247 MapListTo mf = (MapListTo) f.nextElement();
5248 fto[_i] = mf.getStart();
5249 fto[_i + 1] = mf.getEnd();
5251 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5252 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5253 if (m.getMappingChoice() != null)
5255 MappingChoice mc = m.getMappingChoice();
5256 if (mc.getDseqFor() != null)
5258 String dsfor = "" + mc.getDseqFor();
5259 if (seqRefIds.containsKey(dsfor))
5264 jmap.setTo(seqRefIds.get(dsfor));
5268 frefedSequence.add(newMappingRef(dsfor, jmap));
5274 * local sequence definition
5276 Sequence ms = mc.getSequence();
5277 SequenceI djs = null;
5278 String sqid = ms.getDsseqid();
5279 if (sqid != null && sqid.length() > 0)
5282 * recover dataset sequence
5284 djs = seqRefIds.get(sqid);
5289 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5290 sqid = ((Object) ms).toString(); // make up a new hascode for
5291 // undefined dataset sequence hash
5292 // (unlikely to happen)
5298 * make a new dataset sequence and add it to refIds hash
5300 djs = new jalview.datamodel.Sequence(ms.getName(),
5302 djs.setStart(jmap.getMap().getToLowest());
5303 djs.setEnd(jmap.getMap().getToHighest());
5304 djs.setVamsasId(uniqueSetSuffix + sqid);
5306 incompleteSeqs.put(sqid, djs);
5307 seqRefIds.put(sqid, djs);
5310 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5319 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5320 boolean keepSeqRefs)
5323 JalviewModel jm = saveState(ap, null, null, null);
5328 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5332 uniqueSetSuffix = "";
5333 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5338 if (this.frefedSequence == null)
5340 frefedSequence = new Vector();
5343 viewportsAdded.clear();
5345 AlignFrame af = loadFromObject(jm, null, false, null);
5346 af.alignPanels.clear();
5347 af.closeMenuItem_actionPerformed(true);
5350 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5351 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5352 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5353 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5354 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5357 return af.alignPanel;
5361 * flag indicating if hashtables should be cleared on finalization TODO this
5362 * flag may not be necessary
5364 private final boolean _cleartables = true;
5366 private Hashtable jvids2vobj;
5371 * @see java.lang.Object#finalize()
5374 protected void finalize() throws Throwable
5376 // really make sure we have no buried refs left.
5381 this.seqRefIds = null;
5382 this.seqsToIds = null;
5386 private void warn(String msg)
5391 private void warn(String msg, Exception e)
5393 if (Cache.log != null)
5397 Cache.log.warn(msg, e);
5401 Cache.log.warn(msg);
5406 System.err.println("Warning: " + msg);
5409 e.printStackTrace();
5414 private void debug(String string)
5416 debug(string, null);
5419 private void debug(String msg, Exception e)
5421 if (Cache.log != null)
5425 Cache.log.debug(msg, e);
5429 Cache.log.debug(msg);
5434 System.err.println("Warning: " + msg);
5437 e.printStackTrace();
5443 * set the object to ID mapping tables used to write/recover objects and XML
5444 * ID strings for the jalview project. If external tables are provided then
5445 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5446 * object goes out of scope. - also populates the datasetIds hashtable with
5447 * alignment objects containing dataset sequences
5450 * Map from ID strings to jalview datamodel
5452 * Map from jalview datamodel to ID strings
5456 public void setObjectMappingTables(Hashtable vobj2jv,
5457 IdentityHashMap jv2vobj)
5459 this.jv2vobj = jv2vobj;
5460 this.vobj2jv = vobj2jv;
5461 Iterator ds = jv2vobj.keySet().iterator();
5463 while (ds.hasNext())
5465 Object jvobj = ds.next();
5466 id = jv2vobj.get(jvobj).toString();
5467 if (jvobj instanceof jalview.datamodel.Alignment)
5469 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5471 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5474 else if (jvobj instanceof jalview.datamodel.Sequence)
5476 // register sequence object so the XML parser can recover it.
5477 if (seqRefIds == null)
5479 seqRefIds = new HashMap<String, SequenceI>();
5481 if (seqsToIds == null)
5483 seqsToIds = new IdentityHashMap<SequenceI, String>();
5485 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5486 seqsToIds.put((SequenceI) jvobj, id);
5488 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5491 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5492 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5493 if (jvann.annotationId == null)
5495 jvann.annotationId = anid;
5497 if (!jvann.annotationId.equals(anid))
5499 // TODO verify that this is the correct behaviour
5500 this.warn("Overriding Annotation ID for " + anid
5501 + " from different id : " + jvann.annotationId);
5502 jvann.annotationId = anid;
5505 else if (jvobj instanceof String)
5507 if (jvids2vobj == null)
5509 jvids2vobj = new Hashtable();
5510 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5515 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5521 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5522 * objects created from the project archive. If string is null (default for
5523 * construction) then suffix will be set automatically.
5527 public void setUniqueSetSuffix(String string)
5529 uniqueSetSuffix = string;
5534 * uses skipList2 as the skipList for skipping views on sequence sets
5535 * associated with keys in the skipList
5539 public void setSkipList(Hashtable skipList2)
5541 skipList = skipList2;
5545 * Reads the jar entry of given name and returns its contents, or null if the
5546 * entry is not found.
5549 * @param jarEntryName
5552 protected String readJarEntry(jarInputStreamProvider jprovider,
5553 String jarEntryName)
5555 String result = null;
5556 BufferedReader in = null;
5561 * Reopen the jar input stream and traverse its entries to find a matching
5564 JarInputStream jin = jprovider.getJarInputStream();
5565 JarEntry entry = null;
5568 entry = jin.getNextJarEntry();
5569 } while (entry != null && !entry.getName().equals(jarEntryName));
5573 StringBuilder out = new StringBuilder(256);
5574 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5577 while ((data = in.readLine()) != null)
5581 result = out.toString();
5585 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5587 } catch (Exception ex)
5589 ex.printStackTrace();
5597 } catch (IOException e)
5608 * Returns an incrementing counter (0, 1, 2...)
5612 private synchronized int nextCounter()