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.api.FeatureColourI;
24 import jalview.api.ViewStyleI;
25 import jalview.api.structures.JalviewStructureDisplayI;
26 import jalview.bin.Cache;
27 import jalview.datamodel.AlignedCodonFrame;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.PDBEntry;
32 import jalview.datamodel.RnaViewerModel;
33 import jalview.datamodel.SequenceGroup;
34 import jalview.datamodel.SequenceI;
35 import jalview.datamodel.StructureViewerModel;
36 import jalview.datamodel.StructureViewerModel.StructureData;
37 import jalview.ext.varna.RnaModel;
38 import jalview.gui.StructureViewer.ViewerType;
39 import jalview.schemabinding.version2.AlcodMap;
40 import jalview.schemabinding.version2.AlcodonFrame;
41 import jalview.schemabinding.version2.Annotation;
42 import jalview.schemabinding.version2.AnnotationColours;
43 import jalview.schemabinding.version2.AnnotationElement;
44 import jalview.schemabinding.version2.CalcIdParam;
45 import jalview.schemabinding.version2.DBRef;
46 import jalview.schemabinding.version2.Features;
47 import jalview.schemabinding.version2.Group;
48 import jalview.schemabinding.version2.HiddenColumns;
49 import jalview.schemabinding.version2.JGroup;
50 import jalview.schemabinding.version2.JSeq;
51 import jalview.schemabinding.version2.JalviewModel;
52 import jalview.schemabinding.version2.JalviewModelSequence;
53 import jalview.schemabinding.version2.MapListFrom;
54 import jalview.schemabinding.version2.MapListTo;
55 import jalview.schemabinding.version2.Mapping;
56 import jalview.schemabinding.version2.MappingChoice;
57 import jalview.schemabinding.version2.OtherData;
58 import jalview.schemabinding.version2.PdbentryItem;
59 import jalview.schemabinding.version2.Pdbids;
60 import jalview.schemabinding.version2.Property;
61 import jalview.schemabinding.version2.RnaViewer;
62 import jalview.schemabinding.version2.SecondaryStructure;
63 import jalview.schemabinding.version2.Sequence;
64 import jalview.schemabinding.version2.SequenceSet;
65 import jalview.schemabinding.version2.SequenceSetProperties;
66 import jalview.schemabinding.version2.Setting;
67 import jalview.schemabinding.version2.StructureState;
68 import jalview.schemabinding.version2.ThresholdLine;
69 import jalview.schemabinding.version2.Tree;
70 import jalview.schemabinding.version2.UserColours;
71 import jalview.schemabinding.version2.Viewport;
72 import jalview.schemes.AnnotationColourGradient;
73 import jalview.schemes.Colour;
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 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
988 PdbentryItem item = new PdbentryItem();
989 Hashtable properties = entry.getProperty();
990 Enumeration en2 = properties.keys();
991 while (en2.hasMoreElements())
993 Property prop = new Property();
994 String key = en2.nextElement().toString();
996 prop.setValue(properties.get(key).toString());
997 item.addProperty(prop);
999 pdb.addPdbentryItem(item);
1002 jseq.addPdbids(pdb);
1006 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
1011 if (!storeDS && av.hasHiddenRows())
1013 jal = av.getAlignment();
1017 if (storeDS && jal.getCodonFrames() != null)
1019 List<AlignedCodonFrame> jac = jal.getCodonFrames();
1020 for (AlignedCodonFrame acf : jac)
1022 AlcodonFrame alc = new AlcodonFrame();
1023 if (acf.getProtMappings() != null
1024 && acf.getProtMappings().length > 0)
1026 boolean hasMap = false;
1027 SequenceI[] dnas = acf.getdnaSeqs();
1028 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1029 for (int m = 0; m < pmaps.length; m++)
1031 AlcodMap alcmap = new AlcodMap();
1032 alcmap.setDnasq(seqHash(dnas[m]));
1033 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1035 alc.addAlcodMap(alcmap);
1040 vamsasSet.addAlcodonFrame(alc);
1043 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1045 // AlcodonFrame alc = new AlcodonFrame();
1046 // vamsasSet.addAlcodonFrame(alc);
1047 // for (int p = 0; p < acf.aaWidth; p++)
1049 // Alcodon cmap = new Alcodon();
1050 // if (acf.codons[p] != null)
1052 // // Null codons indicate a gapped column in the translated peptide
1054 // cmap.setPos1(acf.codons[p][0]);
1055 // cmap.setPos2(acf.codons[p][1]);
1056 // cmap.setPos3(acf.codons[p][2]);
1058 // alc.addAlcodon(cmap);
1060 // if (acf.getProtMappings() != null
1061 // && acf.getProtMappings().length > 0)
1063 // SequenceI[] dnas = acf.getdnaSeqs();
1064 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1065 // for (int m = 0; m < pmaps.length; m++)
1067 // AlcodMap alcmap = new AlcodMap();
1068 // alcmap.setDnasq(seqHash(dnas[m]));
1069 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1071 // alc.addAlcodMap(alcmap);
1078 // /////////////////////////////////
1079 if (!storeDS && av.currentTree != null)
1081 // FIND ANY ASSOCIATED TREES
1082 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1083 if (Desktop.desktop != null)
1085 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1087 for (int t = 0; t < frames.length; t++)
1089 if (frames[t] instanceof TreePanel)
1091 TreePanel tp = (TreePanel) frames[t];
1093 if (tp.treeCanvas.av.getAlignment() == jal)
1095 Tree tree = new Tree();
1096 tree.setTitle(tp.getTitle());
1097 tree.setCurrentTree((av.currentTree == tp.getTree()));
1098 tree.setNewick(tp.getTree().toString());
1099 tree.setThreshold(tp.treeCanvas.threshold);
1101 tree.setFitToWindow(tp.fitToWindow.getState());
1102 tree.setFontName(tp.getTreeFont().getName());
1103 tree.setFontSize(tp.getTreeFont().getSize());
1104 tree.setFontStyle(tp.getTreeFont().getStyle());
1105 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1107 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1108 tree.setShowDistances(tp.distanceMenu.getState());
1110 tree.setHeight(tp.getHeight());
1111 tree.setWidth(tp.getWidth());
1112 tree.setXpos(tp.getX());
1113 tree.setYpos(tp.getY());
1114 tree.setId(makeHashCode(tp, null));
1124 * store forward refs from an annotationRow to any groups
1126 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1129 for (SequenceI sq : jal.getSequences())
1131 // Store annotation on dataset sequences only
1132 AlignmentAnnotation[] aa = sq.getAnnotation();
1133 if (aa != null && aa.length > 0)
1135 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1142 if (jal.getAlignmentAnnotation() != null)
1144 // Store the annotation shown on the alignment.
1145 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1146 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1151 if (jal.getGroups() != null)
1153 JGroup[] groups = new JGroup[jal.getGroups().size()];
1155 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1157 JGroup jGroup = new JGroup();
1158 groups[++i] = jGroup;
1160 jGroup.setStart(sg.getStartRes());
1161 jGroup.setEnd(sg.getEndRes());
1162 jGroup.setName(sg.getName());
1163 if (groupRefs.containsKey(sg))
1165 // group has references so set its ID field
1166 jGroup.setId(groupRefs.get(sg));
1170 if (sg.cs.conservationApplied())
1172 jGroup.setConsThreshold(sg.cs.getConservationInc());
1174 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1176 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1180 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1183 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1185 jGroup.setColour("AnnotationColourGradient");
1186 jGroup.setAnnotationColours(constructAnnotationColours(
1187 (jalview.schemes.AnnotationColourGradient) sg.cs,
1190 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1192 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1196 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1199 jGroup.setPidThreshold(sg.cs.getThreshold());
1202 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1203 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1204 jGroup.setDisplayText(sg.getDisplayText());
1205 jGroup.setColourText(sg.getColourText());
1206 jGroup.setTextCol1(sg.textColour.getRGB());
1207 jGroup.setTextCol2(sg.textColour2.getRGB());
1208 jGroup.setTextColThreshold(sg.thresholdTextColour);
1209 jGroup.setShowUnconserved(sg.getShowNonconserved());
1210 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1211 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1212 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1213 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1214 for (SequenceI seq : sg.getSequences())
1216 jGroup.addSeq(seqHash(seq));
1220 jms.setJGroup(groups);
1224 // /////////SAVE VIEWPORT
1225 Viewport view = new Viewport();
1226 view.setTitle(ap.alignFrame.getTitle());
1227 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1228 av.getSequenceSetId()));
1229 view.setId(av.getViewId());
1230 if (av.getCodingComplement() != null)
1232 view.setComplementId(av.getCodingComplement().getViewId());
1234 view.setViewName(av.viewName);
1235 view.setGatheredViews(av.isGatherViewsHere());
1237 Rectangle size = ap.av.getExplodedGeometry();
1238 Rectangle position = size;
1241 size = ap.alignFrame.getBounds();
1242 if (av.getCodingComplement() != null)
1244 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1252 view.setXpos(position.x);
1253 view.setYpos(position.y);
1255 view.setWidth(size.width);
1256 view.setHeight(size.height);
1258 view.setStartRes(av.startRes);
1259 view.setStartSeq(av.startSeq);
1261 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1263 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1266 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1268 AnnotationColours ac = constructAnnotationColours(
1269 (jalview.schemes.AnnotationColourGradient) av
1270 .getGlobalColourScheme(),
1273 view.setAnnotationColours(ac);
1274 view.setBgColour("AnnotationColourGradient");
1278 view.setBgColour(ColourSchemeProperty.getColourName(av
1279 .getGlobalColourScheme()));
1282 ColourSchemeI cs = av.getGlobalColourScheme();
1286 if (cs.conservationApplied())
1288 view.setConsThreshold(cs.getConservationInc());
1289 if (cs instanceof jalview.schemes.UserColourScheme)
1291 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1295 if (cs instanceof ResidueColourScheme)
1297 view.setPidThreshold(cs.getThreshold());
1301 view.setConservationSelected(av.getConservationSelected());
1302 view.setPidSelected(av.getAbovePIDThreshold());
1303 view.setFontName(av.font.getName());
1304 view.setFontSize(av.font.getSize());
1305 view.setFontStyle(av.font.getStyle());
1306 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1307 view.setRenderGaps(av.isRenderGaps());
1308 view.setShowAnnotation(av.isShowAnnotation());
1309 view.setShowBoxes(av.getShowBoxes());
1310 view.setShowColourText(av.getColourText());
1311 view.setShowFullId(av.getShowJVSuffix());
1312 view.setRightAlignIds(av.isRightAlignIds());
1313 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1314 view.setShowText(av.getShowText());
1315 view.setShowUnconserved(av.getShowUnconserved());
1316 view.setWrapAlignment(av.getWrapAlignment());
1317 view.setTextCol1(av.getTextColour().getRGB());
1318 view.setTextCol2(av.getTextColour2().getRGB());
1319 view.setTextColThreshold(av.getThresholdTextColour());
1320 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1321 view.setShowSequenceLogo(av.isShowSequenceLogo());
1322 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1323 view.setShowGroupConsensus(av.isShowGroupConsensus());
1324 view.setShowGroupConservation(av.isShowGroupConservation());
1325 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1326 view.setShowDbRefTooltip(av.isShowDBRefs());
1327 view.setFollowHighlight(av.isFollowHighlight());
1328 view.setFollowSelection(av.followSelection);
1329 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1330 if (av.getFeaturesDisplayed() != null)
1332 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1334 String[] renderOrder = ap.getSeqPanel().seqCanvas
1335 .getFeatureRenderer().getRenderOrder()
1336 .toArray(new String[0]);
1338 Vector<String> settingsAdded = new Vector<String>();
1339 if (renderOrder != null)
1341 for (String featureType : renderOrder)
1343 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1344 .getFeatureRenderer()
1345 .getFeatureStyle(featureType);
1346 Setting setting = new Setting();
1347 setting.setType(featureType);
1348 if (!fcol.isSimpleColour())
1350 setting.setColour(fcol.getMaxColour().getRGB());
1351 setting.setMincolour(fcol.getMinColour().getRGB());
1352 setting.setMin(fcol.getMin());
1353 setting.setMax(fcol.getMax());
1354 setting.setColourByLabel(fcol.isColourByLabel());
1355 setting.setAutoScale(fcol.isAutoScaled());
1356 setting.setThreshold(fcol.getThreshold());
1357 // -1 = No threshold, 0 = Below, 1 = Above
1358 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1359 : (fcol.isBelowThreshold() ? 0 : -1));
1363 setting.setColour(fcol.getColour().getRGB());
1366 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1368 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1369 .getOrder(featureType);
1372 setting.setOrder(rorder);
1374 fs.addSetting(setting);
1375 settingsAdded.addElement(featureType);
1379 // is groups actually supposed to be a map here ?
1380 Iterator<String> en = ap.getSeqPanel().seqCanvas
1381 .getFeatureRenderer()
1382 .getFeatureGroups().iterator();
1383 Vector<String> groupsAdded = new Vector<String>();
1384 while (en.hasNext())
1386 String grp = en.next();
1387 if (groupsAdded.contains(grp))
1391 Group g = new Group();
1393 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1394 .getFeatureRenderer().checkGroupVisibility(grp, false))
1397 groupsAdded.addElement(grp);
1399 jms.setFeatureSettings(fs);
1402 if (av.hasHiddenColumns())
1404 if (av.getColumnSelection() == null
1405 || av.getColumnSelection().getHiddenColumns() == null)
1407 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1411 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1414 int[] region = av.getColumnSelection().getHiddenColumns()
1416 HiddenColumns hc = new HiddenColumns();
1417 hc.setStart(region[0]);
1418 hc.setEnd(region[1]);
1419 view.addHiddenColumns(hc);
1423 if (calcIdSet.size() > 0)
1425 for (String calcId : calcIdSet)
1427 if (calcId.trim().length() > 0)
1429 CalcIdParam cidp = createCalcIdParam(calcId, av);
1430 // Some calcIds have no parameters.
1433 view.addCalcIdParam(cidp);
1439 jms.addViewport(view);
1441 object.setJalviewModelSequence(jms);
1442 object.getVamsasModel().addSequenceSet(vamsasSet);
1444 if (jout != null && fileName != null)
1446 // We may not want to write the object to disk,
1447 // eg we can copy the alignViewport to a new view object
1448 // using save and then load
1451 System.out.println("Writing jar entry " + fileName);
1452 JarEntry entry = new JarEntry(fileName);
1453 jout.putNextEntry(entry);
1454 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1456 Marshaller marshaller = new Marshaller(pout);
1457 marshaller.marshal(object);
1460 } catch (Exception ex)
1462 // TODO: raise error in GUI if marshalling failed.
1463 ex.printStackTrace();
1470 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1471 * for each viewer, with
1473 * <li>viewer geometry (position, size, split pane divider location)</li>
1474 * <li>index of the selected structure in the viewer (currently shows gapped
1476 * <li>the id of the annotation holding RNA secondary structure</li>
1477 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1479 * Varna viewer state is also written out (in native Varna XML) to separate
1480 * project jar entries. A separate entry is written for each RNA structure
1481 * displayed, with the naming convention
1483 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1491 * @param storeDataset
1493 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1494 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1495 boolean storeDataset)
1497 if (Desktop.desktop == null)
1501 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1502 for (int f = frames.length - 1; f > -1; f--)
1504 if (frames[f] instanceof AppVarna)
1506 AppVarna varna = (AppVarna) frames[f];
1508 * link the sequence to every viewer that is showing it and is linked to
1509 * its alignment panel
1511 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1513 String viewId = varna.getViewId();
1514 RnaViewer rna = new RnaViewer();
1515 rna.setViewId(viewId);
1516 rna.setTitle(varna.getTitle());
1517 rna.setXpos(varna.getX());
1518 rna.setYpos(varna.getY());
1519 rna.setWidth(varna.getWidth());
1520 rna.setHeight(varna.getHeight());
1521 rna.setDividerLocation(varna.getDividerLocation());
1522 rna.setSelectedRna(varna.getSelectedIndex());
1523 jseq.addRnaViewer(rna);
1526 * Store each Varna panel's state once in the project per sequence.
1527 * First time through only (storeDataset==false)
1529 // boolean storeSessions = false;
1530 // String sequenceViewId = viewId + seqsToIds.get(jds);
1531 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1533 // viewIds.add(sequenceViewId);
1534 // storeSessions = true;
1536 for (RnaModel model : varna.getModels())
1538 if (model.seq == jds)
1541 * VARNA saves each view (sequence or alignment secondary
1542 * structure, gapped or trimmed) as a separate XML file
1544 String jarEntryName = rnaSessions.get(model);
1545 if (jarEntryName == null)
1548 String varnaStateFile = varna.getStateInfo(model.rna);
1549 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1550 copyFileToJar(jout, varnaStateFile, jarEntryName);
1551 rnaSessions.put(model, jarEntryName);
1553 SecondaryStructure ss = new SecondaryStructure();
1554 String annotationId = varna.getAnnotation(jds).annotationId;
1555 ss.setAnnotationId(annotationId);
1556 ss.setViewerState(jarEntryName);
1557 ss.setGapped(model.gapped);
1558 ss.setTitle(model.title);
1559 rna.addSecondaryStructure(ss);
1568 * Copy the contents of a file to a new entry added to the output jar
1572 * @param jarEntryName
1574 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1575 String jarEntryName)
1577 DataInputStream dis = null;
1580 File file = new File(infilePath);
1581 if (file.exists() && jout != null)
1583 dis = new DataInputStream(new FileInputStream(file));
1584 byte[] data = new byte[(int) file.length()];
1585 dis.readFully(data);
1586 writeJarEntry(jout, jarEntryName, data);
1588 } catch (Exception ex)
1590 ex.printStackTrace();
1598 } catch (IOException e)
1607 * Write the data to a new entry of given name in the output jar file
1610 * @param jarEntryName
1612 * @throws IOException
1614 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1615 byte[] data) throws IOException
1619 System.out.println("Writing jar entry " + jarEntryName);
1620 jout.putNextEntry(new JarEntry(jarEntryName));
1621 DataOutputStream dout = new DataOutputStream(jout);
1622 dout.write(data, 0, data.length);
1629 * Save the state of a structure viewer
1634 * the archive XML element under which to save the state
1637 * @param matchedFile
1641 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1642 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1643 String matchedFile, StructureViewerBase viewFrame)
1645 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1648 * Look for any bindings for this viewer to the PDB file of interest
1649 * (including part matches excluding chain id)
1651 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1653 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1654 final String pdbId = pdbentry.getId();
1655 if (!pdbId.equals(entry.getId())
1656 && !(entry.getId().length() > 4 && entry.getId()
1657 .toLowerCase().startsWith(pdbId.toLowerCase())))
1660 * not interested in a binding to a different PDB entry here
1664 if (matchedFile == null)
1666 matchedFile = pdbentry.getFile();
1668 else if (!matchedFile.equals(pdbentry.getFile()))
1671 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1672 + pdbentry.getFile());
1676 // can get at it if the ID
1677 // match is ambiguous (e.g.
1680 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1682 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1683 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1685 StructureState state = new StructureState();
1686 state.setVisible(true);
1687 state.setXpos(viewFrame.getX());
1688 state.setYpos(viewFrame.getY());
1689 state.setWidth(viewFrame.getWidth());
1690 state.setHeight(viewFrame.getHeight());
1691 final String viewId = viewFrame.getViewId();
1692 state.setViewId(viewId);
1693 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1694 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1695 state.setColourByJmol(viewFrame.isColouredByViewer());
1696 state.setType(viewFrame.getViewerType().toString());
1697 pdb.addStructureState(state);
1704 private AnnotationColours constructAnnotationColours(
1705 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1706 JalviewModelSequence jms)
1708 AnnotationColours ac = new AnnotationColours();
1709 ac.setAboveThreshold(acg.getAboveThreshold());
1710 ac.setThreshold(acg.getAnnotationThreshold());
1711 ac.setAnnotation(acg.getAnnotation());
1712 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1714 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1719 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1723 ac.setMaxColour(acg.getMaxColour().getRGB());
1724 ac.setMinColour(acg.getMinColour().getRGB());
1725 ac.setPerSequence(acg.isSeqAssociated());
1726 ac.setPredefinedColours(acg.isPredefinedColours());
1730 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1731 IdentityHashMap<SequenceGroup, String> groupRefs,
1732 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1733 SequenceSet vamsasSet)
1736 for (int i = 0; i < aa.length; i++)
1738 Annotation an = new Annotation();
1740 AlignmentAnnotation annotation = aa[i];
1741 if (annotation.annotationId != null)
1743 annotationIds.put(annotation.annotationId, annotation);
1746 an.setId(annotation.annotationId);
1748 an.setVisible(annotation.visible);
1750 an.setDescription(annotation.description);
1752 if (annotation.sequenceRef != null)
1754 // 2.9 JAL-1781 xref on sequence id rather than name
1755 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1757 if (annotation.groupRef != null)
1759 String groupIdr = groupRefs.get(annotation.groupRef);
1760 if (groupIdr == null)
1762 // make a locally unique String
1764 annotation.groupRef,
1765 groupIdr = ("" + System.currentTimeMillis()
1766 + annotation.groupRef.getName() + groupRefs
1769 an.setGroupRef(groupIdr.toString());
1772 // store all visualization attributes for annotation
1773 an.setGraphHeight(annotation.graphHeight);
1774 an.setCentreColLabels(annotation.centreColLabels);
1775 an.setScaleColLabels(annotation.scaleColLabel);
1776 an.setShowAllColLabels(annotation.showAllColLabels);
1777 an.setBelowAlignment(annotation.belowAlignment);
1779 if (annotation.graph > 0)
1782 an.setGraphType(annotation.graph);
1783 an.setGraphGroup(annotation.graphGroup);
1784 if (annotation.getThreshold() != null)
1786 ThresholdLine line = new ThresholdLine();
1787 line.setLabel(annotation.getThreshold().label);
1788 line.setValue(annotation.getThreshold().value);
1789 line.setColour(annotation.getThreshold().colour.getRGB());
1790 an.setThresholdLine(line);
1798 an.setLabel(annotation.label);
1800 if (annotation == av.getAlignmentQualityAnnot()
1801 || annotation == av.getAlignmentConservationAnnotation()
1802 || annotation == av.getAlignmentConsensusAnnotation()
1803 || annotation.autoCalculated)
1805 // new way of indicating autocalculated annotation -
1806 an.setAutoCalculated(annotation.autoCalculated);
1808 if (annotation.hasScore())
1810 an.setScore(annotation.getScore());
1813 if (annotation.getCalcId() != null)
1815 calcIdSet.add(annotation.getCalcId());
1816 an.setCalcId(annotation.getCalcId());
1818 if (annotation.hasProperties())
1820 for (String pr : annotation.getProperties())
1822 Property prop = new Property();
1824 prop.setValue(annotation.getProperty(pr));
1825 an.addProperty(prop);
1829 AnnotationElement ae;
1830 if (annotation.annotations != null)
1832 an.setScoreOnly(false);
1833 for (int a = 0; a < annotation.annotations.length; a++)
1835 if ((annotation == null) || (annotation.annotations[a] == null))
1840 ae = new AnnotationElement();
1841 if (annotation.annotations[a].description != null)
1843 ae.setDescription(annotation.annotations[a].description);
1845 if (annotation.annotations[a].displayCharacter != null)
1847 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1850 if (!Float.isNaN(annotation.annotations[a].value))
1852 ae.setValue(annotation.annotations[a].value);
1856 if (annotation.annotations[a].secondaryStructure > ' ')
1858 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1862 if (annotation.annotations[a].colour != null
1863 && annotation.annotations[a].colour != java.awt.Color.black)
1865 ae.setColour(annotation.annotations[a].colour.getRGB());
1868 an.addAnnotationElement(ae);
1869 if (annotation.autoCalculated)
1871 // only write one non-null entry into the annotation row -
1872 // sufficient to get the visualization attributes necessary to
1880 an.setScoreOnly(true);
1882 if (!storeDS || (storeDS && !annotation.autoCalculated))
1884 // skip autocalculated annotation - these are only provided for
1886 vamsasSet.addAnnotation(an);
1892 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1894 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1895 if (settings != null)
1897 CalcIdParam vCalcIdParam = new CalcIdParam();
1898 vCalcIdParam.setCalcId(calcId);
1899 vCalcIdParam.addServiceURL(settings.getServiceURI());
1900 // generic URI allowing a third party to resolve another instance of the
1901 // service used for this calculation
1902 for (String urls : settings.getServiceURLs())
1904 vCalcIdParam.addServiceURL(urls);
1906 vCalcIdParam.setVersion("1.0");
1907 if (settings.getPreset() != null)
1909 WsParamSetI setting = settings.getPreset();
1910 vCalcIdParam.setName(setting.getName());
1911 vCalcIdParam.setDescription(setting.getDescription());
1915 vCalcIdParam.setName("");
1916 vCalcIdParam.setDescription("Last used parameters");
1918 // need to be able to recover 1) settings 2) user-defined presets or
1919 // recreate settings from preset 3) predefined settings provided by
1920 // service - or settings that can be transferred (or discarded)
1921 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1923 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1924 // todo - decide if updateImmediately is needed for any projects.
1926 return vCalcIdParam;
1931 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1934 if (calcIdParam.getVersion().equals("1.0"))
1936 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1937 .getPreferredServiceFor(calcIdParam.getServiceURL());
1938 if (service != null)
1940 WsParamSetI parmSet = null;
1943 parmSet = service.getParamStore().parseServiceParameterFile(
1944 calcIdParam.getName(), calcIdParam.getDescription(),
1945 calcIdParam.getServiceURL(),
1946 calcIdParam.getParameters().replace("|\\n|", "\n"));
1947 } catch (IOException x)
1949 warn("Couldn't parse parameter data for "
1950 + calcIdParam.getCalcId(), x);
1953 List<ArgumentI> argList = null;
1954 if (calcIdParam.getName().length() > 0)
1956 parmSet = service.getParamStore()
1957 .getPreset(calcIdParam.getName());
1958 if (parmSet != null)
1960 // TODO : check we have a good match with settings in AACon -
1961 // otherwise we'll need to create a new preset
1966 argList = parmSet.getArguments();
1969 AAConSettings settings = new AAConSettings(
1970 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1971 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1972 calcIdParam.isNeedsUpdate());
1977 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1981 throw new Error(MessageManager.formatMessage(
1982 "error.unsupported_version_calcIdparam",
1983 new Object[] { calcIdParam.toString() }));
1987 * External mapping between jalview objects and objects yielding a valid and
1988 * unique object ID string. This is null for normal Jalview project IO, but
1989 * non-null when a jalview project is being read or written as part of a
1992 IdentityHashMap jv2vobj = null;
1995 * Construct a unique ID for jvobj using either existing bindings or if none
1996 * exist, the result of the hashcode call for the object.
1999 * jalview data object
2000 * @return unique ID for referring to jvobj
2002 private String makeHashCode(Object jvobj, String altCode)
2004 if (jv2vobj != null)
2006 Object id = jv2vobj.get(jvobj);
2009 return id.toString();
2011 // check string ID mappings
2012 if (jvids2vobj != null && jvobj instanceof String)
2014 id = jvids2vobj.get(jvobj);
2018 return id.toString();
2020 // give up and warn that something has gone wrong
2021 warn("Cannot find ID for object in external mapping : " + jvobj);
2027 * return local jalview object mapped to ID, if it exists
2031 * @return null or object bound to idcode
2033 private Object retrieveExistingObj(String idcode)
2035 if (idcode != null && vobj2jv != null)
2037 return vobj2jv.get(idcode);
2043 * binding from ID strings from external mapping table to jalview data model
2046 private Hashtable vobj2jv;
2048 private Sequence createVamsasSequence(String id, SequenceI jds)
2050 return createVamsasSequence(true, id, jds, null);
2053 private Sequence createVamsasSequence(boolean recurse, String id,
2054 SequenceI jds, SequenceI parentseq)
2056 Sequence vamsasSeq = new Sequence();
2057 vamsasSeq.setId(id);
2058 vamsasSeq.setName(jds.getName());
2059 vamsasSeq.setSequence(jds.getSequenceAsString());
2060 vamsasSeq.setDescription(jds.getDescription());
2061 jalview.datamodel.DBRefEntry[] dbrefs = null;
2062 if (jds.getDatasetSequence() != null)
2064 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2068 // seqId==dsseqid so we can tell which sequences really are
2069 // dataset sequences only
2070 vamsasSeq.setDsseqid(id);
2071 dbrefs = jds.getDBRefs();
2072 if (parentseq == null)
2079 for (int d = 0; d < dbrefs.length; d++)
2081 DBRef dbref = new DBRef();
2082 dbref.setSource(dbrefs[d].getSource());
2083 dbref.setVersion(dbrefs[d].getVersion());
2084 dbref.setAccessionId(dbrefs[d].getAccessionId());
2085 if (dbrefs[d].hasMap())
2087 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2089 dbref.setMapping(mp);
2091 vamsasSeq.addDBRef(dbref);
2097 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2098 SequenceI parentseq, SequenceI jds, boolean recurse)
2101 if (jmp.getMap() != null)
2105 jalview.util.MapList mlst = jmp.getMap();
2106 List<int[]> r = mlst.getFromRanges();
2107 for (int[] range : r)
2109 MapListFrom mfrom = new MapListFrom();
2110 mfrom.setStart(range[0]);
2111 mfrom.setEnd(range[1]);
2112 mp.addMapListFrom(mfrom);
2114 r = mlst.getToRanges();
2115 for (int[] range : r)
2117 MapListTo mto = new MapListTo();
2118 mto.setStart(range[0]);
2119 mto.setEnd(range[1]);
2120 mp.addMapListTo(mto);
2122 mp.setMapFromUnit(mlst.getFromRatio());
2123 mp.setMapToUnit(mlst.getToRatio());
2124 if (jmp.getTo() != null)
2126 MappingChoice mpc = new MappingChoice();
2128 // check/create ID for the sequence referenced by getTo()
2131 SequenceI ps = null;
2132 if (parentseq != jmp.getTo()
2133 && parentseq.getDatasetSequence() != jmp.getTo())
2135 // chaining dbref rather than a handshaking one
2136 jmpid = seqHash(ps = jmp.getTo());
2140 jmpid = seqHash(ps = parentseq);
2142 mpc.setDseqFor(jmpid);
2143 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2145 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2146 seqRefIds.put(mpc.getDseqFor(), ps);
2150 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2153 mp.setMappingChoice(mpc);
2159 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2160 List<UserColourScheme> userColours, JalviewModelSequence jms)
2163 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2164 boolean newucs = false;
2165 if (!userColours.contains(ucs))
2167 userColours.add(ucs);
2170 id = "ucs" + userColours.indexOf(ucs);
2173 // actually create the scheme's entry in the XML model
2174 java.awt.Color[] colours = ucs.getColours();
2175 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2176 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2178 for (int i = 0; i < colours.length; i++)
2180 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2181 col.setName(ResidueProperties.aa[i]);
2182 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2183 jbucs.addColour(col);
2185 if (ucs.getLowerCaseColours() != null)
2187 colours = ucs.getLowerCaseColours();
2188 for (int i = 0; i < colours.length; i++)
2190 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2191 col.setName(ResidueProperties.aa[i].toLowerCase());
2192 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2193 jbucs.addColour(col);
2198 uc.setUserColourScheme(jbucs);
2199 jms.addUserColours(uc);
2205 jalview.schemes.UserColourScheme getUserColourScheme(
2206 JalviewModelSequence jms, String id)
2208 UserColours[] uc = jms.getUserColours();
2209 UserColours colours = null;
2211 for (int i = 0; i < uc.length; i++)
2213 if (uc[i].getId().equals(id))
2221 java.awt.Color[] newColours = new java.awt.Color[24];
2223 for (int i = 0; i < 24; i++)
2225 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2226 .getUserColourScheme().getColour(i).getRGB(), 16));
2229 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2232 if (colours.getUserColourScheme().getColourCount() > 24)
2234 newColours = new java.awt.Color[23];
2235 for (int i = 0; i < 23; i++)
2237 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2238 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2240 ucs.setLowerCaseColours(newColours);
2247 * contains last error message (if any) encountered by XML loader.
2249 String errorMessage = null;
2252 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2253 * exceptions are raised during project XML parsing
2255 public boolean attemptversion1parse = true;
2258 * Load a jalview project archive from a jar file
2261 * - HTTP URL or filename
2263 public AlignFrame loadJalviewAlign(final String file)
2266 jalview.gui.AlignFrame af = null;
2270 // create list to store references for any new Jmol viewers created
2271 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2272 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2273 // Workaround is to make sure caller implements the JarInputStreamProvider
2275 // so we can re-open the jar input stream for each entry.
2277 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2278 af = loadJalviewAlign(jprovider);
2280 } catch (MalformedURLException e)
2282 errorMessage = "Invalid URL format for '" + file + "'";
2288 SwingUtilities.invokeAndWait(new Runnable()
2293 setLoadingFinishedForNewStructureViewers();
2296 } catch (Exception x)
2298 System.err.println("Error loading alignment: " + x.getMessage());
2304 private jarInputStreamProvider createjarInputStreamProvider(
2305 final String file) throws MalformedURLException
2308 errorMessage = null;
2309 uniqueSetSuffix = null;
2311 viewportsAdded.clear();
2312 frefedSequence = null;
2314 if (file.startsWith("http://"))
2316 url = new URL(file);
2318 final URL _url = url;
2319 return new jarInputStreamProvider()
2323 public JarInputStream getJarInputStream() throws IOException
2327 return new JarInputStream(_url.openStream());
2331 return new JarInputStream(new FileInputStream(file));
2336 public String getFilename()
2344 * Recover jalview session from a jalview project archive. Caller may
2345 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2346 * themselves. Any null fields will be initialised with default values,
2347 * non-null fields are left alone.
2352 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2354 errorMessage = null;
2355 if (uniqueSetSuffix == null)
2357 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2359 if (seqRefIds == null)
2363 AlignFrame af = null, _af = null;
2364 IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
2365 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2366 final String file = jprovider.getFilename();
2369 JarInputStream jin = null;
2370 JarEntry jarentry = null;
2375 jin = jprovider.getJarInputStream();
2376 for (int i = 0; i < entryCount; i++)
2378 jarentry = jin.getNextJarEntry();
2381 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2383 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2384 JalviewModel object = new JalviewModel();
2386 Unmarshaller unmar = new Unmarshaller(object);
2387 unmar.setValidation(false);
2388 object = (JalviewModel) unmar.unmarshal(in);
2389 if (true) // !skipViewport(object))
2391 _af = loadFromObject(object, file, true, jprovider);
2393 && object.getJalviewModelSequence().getViewportCount() > 0)
2397 // store a reference to the first view
2400 if (_af.viewport.isGatherViewsHere())
2402 // if this is a gathered view, keep its reference since
2403 // after gathering views, only this frame will remain
2405 gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
2407 // Save dataset to register mappings once all resolved
2408 importedDatasets.put(af.viewport.getAlignment().getDataset(),
2409 af.viewport.getAlignment().getDataset());
2414 else if (jarentry != null)
2416 // Some other file here.
2419 } while (jarentry != null);
2420 resolveFrefedSequences();
2421 } catch (IOException ex)
2423 ex.printStackTrace();
2424 errorMessage = "Couldn't locate Jalview XML file : " + file;
2425 System.err.println("Exception whilst loading jalview XML file : "
2427 } catch (Exception ex)
2429 System.err.println("Parsing as Jalview Version 2 file failed.");
2430 ex.printStackTrace(System.err);
2431 if (attemptversion1parse)
2433 // Is Version 1 Jar file?
2436 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2437 } catch (Exception ex2)
2439 System.err.println("Exception whilst loading as jalviewXMLV1:");
2440 ex2.printStackTrace();
2444 if (Desktop.instance != null)
2446 Desktop.instance.stopLoading();
2450 System.out.println("Successfully loaded archive file");
2453 ex.printStackTrace();
2455 System.err.println("Exception whilst loading jalview XML file : "
2457 } catch (OutOfMemoryError e)
2459 // Don't use the OOM Window here
2460 errorMessage = "Out of memory loading jalview XML file";
2461 System.err.println("Out of memory whilst loading jalview XML file");
2462 e.printStackTrace();
2466 * Regather multiple views (with the same sequence set id) to the frame (if
2467 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2468 * views instead of separate frames. Note this doesn't restore a state where
2469 * some expanded views in turn have tabbed views - the last "first tab" read
2470 * in will play the role of gatherer for all.
2472 for (AlignFrame fr : gatherToThisFrame.values())
2474 Desktop.instance.gatherViews(fr);
2477 restoreSplitFrames();
2478 for (AlignmentI ds : importedDatasets.keySet())
2480 if (ds.getCodonFrames() != null)
2482 StructureSelectionManager.getStructureSelectionManager(
2483 Desktop.instance).registerMappings(ds.getCodonFrames());
2486 if (errorMessage != null)
2491 if (Desktop.instance != null)
2493 Desktop.instance.stopLoading();
2500 * Try to reconstruct and display SplitFrame windows, where each contains
2501 * complementary dna and protein alignments. Done by pairing up AlignFrame
2502 * objects (created earlier) which have complementary viewport ids associated.
2504 protected void restoreSplitFrames()
2506 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2507 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2508 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2511 * Identify the DNA alignments
2513 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2516 AlignFrame af = candidate.getValue();
2517 if (af.getViewport().getAlignment().isNucleotide())
2519 dna.put(candidate.getKey().getId(), af);
2524 * Try to match up the protein complements
2526 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2529 AlignFrame af = candidate.getValue();
2530 if (!af.getViewport().getAlignment().isNucleotide())
2532 String complementId = candidate.getKey().getComplementId();
2533 // only non-null complements should be in the Map
2534 if (complementId != null && dna.containsKey(complementId))
2536 final AlignFrame dnaFrame = dna.get(complementId);
2537 SplitFrame sf = createSplitFrame(dnaFrame, af);
2538 addedToSplitFrames.add(dnaFrame);
2539 addedToSplitFrames.add(af);
2540 if (af.viewport.isGatherViewsHere())
2549 * Open any that we failed to pair up (which shouldn't happen!) as
2550 * standalone AlignFrame's.
2552 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2555 AlignFrame af = candidate.getValue();
2556 if (!addedToSplitFrames.contains(af))
2558 Viewport view = candidate.getKey();
2559 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2561 System.err.println("Failed to restore view " + view.getTitle()
2562 + " to split frame");
2567 * Gather back into tabbed views as flagged.
2569 for (SplitFrame sf : gatherTo)
2571 Desktop.instance.gatherViews(sf);
2574 splitFrameCandidates.clear();
2578 * Construct and display one SplitFrame holding DNA and protein alignments.
2581 * @param proteinFrame
2584 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2585 AlignFrame proteinFrame)
2587 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2588 String title = MessageManager.getString("label.linked_view_title");
2589 int width = (int) dnaFrame.getBounds().getWidth();
2590 int height = (int) (dnaFrame.getBounds().getHeight()
2591 + proteinFrame.getBounds().getHeight() + 50);
2594 * SplitFrame location is saved to both enclosed frames
2596 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2597 Desktop.addInternalFrame(splitFrame, title, width, height);
2600 * And compute cDNA consensus (couldn't do earlier with consensus as
2601 * mappings were not yet present)
2603 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2609 * check errorMessage for a valid error message and raise an error box in the
2610 * GUI or write the current errorMessage to stderr and then clear the error
2613 protected void reportErrors()
2615 reportErrors(false);
2618 protected void reportErrors(final boolean saving)
2620 if (errorMessage != null)
2622 final String finalErrorMessage = errorMessage;
2625 javax.swing.SwingUtilities.invokeLater(new Runnable()
2630 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2631 finalErrorMessage, "Error "
2632 + (saving ? "saving" : "loading")
2633 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2639 System.err.println("Problem loading Jalview file: " + errorMessage);
2642 errorMessage = null;
2645 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2648 * when set, local views will be updated from view stored in JalviewXML
2649 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2650 * sync if this is set to true.
2652 private final boolean updateLocalViews = false;
2655 * Returns the path to a temporary file holding the PDB file for the given PDB
2656 * id. The first time of asking, searches for a file of that name in the
2657 * Jalview project jar, and copies it to a new temporary file. Any repeat
2658 * requests just return the path to the file previously created.
2664 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
2667 if (alreadyLoadedPDB.containsKey(pdbId))
2669 return alreadyLoadedPDB.get(pdbId).toString();
2672 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
2674 if (tempFile != null)
2676 alreadyLoadedPDB.put(pdbId, tempFile);
2682 * Copies the jar entry of given name to a new temporary file and returns the
2683 * path to the file, or null if the entry is not found.
2686 * @param jarEntryName
2688 * a prefix for the temporary file name, must be at least three
2691 * null or original file - so new file can be given the same suffix
2695 protected String copyJarEntry(jarInputStreamProvider jprovider,
2696 String jarEntryName, String prefix, String origFile)
2698 BufferedReader in = null;
2699 PrintWriter out = null;
2700 String suffix = ".tmp";
2701 if (origFile == null)
2703 origFile = jarEntryName;
2705 int sfpos = origFile.lastIndexOf(".");
2706 if (sfpos > -1 && sfpos < (origFile.length() - 3))
2708 suffix = "." + origFile.substring(sfpos + 1);
2712 JarInputStream jin = jprovider.getJarInputStream();
2714 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2715 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2716 * FileInputStream(jprovider)); }
2719 JarEntry entry = null;
2722 entry = jin.getNextJarEntry();
2723 } while (entry != null && !entry.getName().equals(jarEntryName));
2726 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2727 File outFile = File.createTempFile(prefix, suffix);
2728 outFile.deleteOnExit();
2729 out = new PrintWriter(new FileOutputStream(outFile));
2732 while ((data = in.readLine()) != null)
2737 String t = outFile.getAbsolutePath();
2742 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2744 } catch (Exception ex)
2746 ex.printStackTrace();
2754 } catch (IOException e)
2768 private class JvAnnotRow
2770 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2777 * persisted version of annotation row from which to take vis properties
2779 public jalview.datamodel.AlignmentAnnotation template;
2782 * original position of the annotation row in the alignment
2788 * Load alignment frame from jalview XML DOM object
2793 * filename source string
2794 * @param loadTreesAndStructures
2795 * when false only create Viewport
2797 * data source provider
2798 * @return alignment frame created from view stored in DOM
2800 AlignFrame loadFromObject(JalviewModel object, String file,
2801 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2803 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2804 Sequence[] vamsasSeq = vamsasSet.getSequence();
2806 JalviewModelSequence jms = object.getJalviewModelSequence();
2808 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2811 // ////////////////////////////////
2814 List<SequenceI> hiddenSeqs = null;
2817 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2819 boolean multipleView = false;
2820 SequenceI referenceseqForView = null;
2821 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2822 int vi = 0; // counter in vamsasSeq array
2823 for (int i = 0; i < jseqs.length; i++)
2825 String seqId = jseqs[i].getId();
2827 SequenceI tmpSeq = seqRefIds.get(seqId);
2830 if (!incompleteSeqs.containsKey(seqId))
2832 // may not need this check, but keep it for at least 2.9,1 release
2833 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2836 .println("Warning JAL-2154 regression: updating start/end for sequence "
2837 + tmpSeq.toString() + " to " + jseqs[i]);
2840 incompleteSeqs.remove(seqId);
2842 if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
2844 // most likely we are reading a dataset XML document so
2845 // update from vamsasSeq section of XML for this sequence
2846 tmpSeq.setName(vamsasSeq[vi].getName());
2847 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2848 tmpSeq.setSequence(vamsasSeq[vi].getSequence());
2853 // reading multiple views, so vamsasSeq set is a subset of JSeq
2854 multipleView = true;
2856 tmpSeq.setStart(jseqs[i].getStart());
2857 tmpSeq.setEnd(jseqs[i].getEnd());
2858 tmpseqs.add(tmpSeq);
2862 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2863 vamsasSeq[vi].getSequence());
2864 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2865 tmpSeq.setStart(jseqs[i].getStart());
2866 tmpSeq.setEnd(jseqs[i].getEnd());
2867 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2868 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2869 tmpseqs.add(tmpSeq);
2873 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2875 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2878 if (jseqs[i].getHidden())
2880 if (hiddenSeqs == null)
2882 hiddenSeqs = new ArrayList<SequenceI>();
2885 hiddenSeqs.add(tmpSeq);
2890 // Create the alignment object from the sequence set
2891 // ///////////////////////////////
2892 SequenceI[] orderedSeqs = tmpseqs
2893 .toArray(new SequenceI[tmpseqs.size()]);
2895 AlignmentI al = null;
2896 // so we must create or recover the dataset alignment before going further
2897 // ///////////////////////////////
2898 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2900 // older jalview projects do not have a dataset - so creat alignment and
2902 al = new Alignment(orderedSeqs);
2903 al.setDataset(null);
2907 boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
2910 // we are importing a dataset record, so
2911 // recover reference to an alignment already materialsed as dataset
2912 al = getDatasetFor(vamsasSet.getDatasetId());
2916 // materialse the alignment
2917 al = new Alignment(orderedSeqs);
2921 addDatasetRef(vamsasSet.getDatasetId(), al);
2924 // finally, verify all data in vamsasSet is actually present in al
2925 // passing on flag indicating if it is actually a stored dataset
2926 recoverDatasetFor(vamsasSet, al, isdsal);
2929 if (referenceseqForView != null)
2931 al.setSeqrep(referenceseqForView);
2933 // / Add the alignment properties
2934 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2936 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2937 al.setProperty(ssp.getKey(), ssp.getValue());
2940 // ///////////////////////////////
2942 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2945 // load sequence features, database references and any associated PDB
2946 // structures for the alignment
2948 // prior to 2.10, this part would only be executed the first time a
2949 // sequence was encountered, but not afterwards.
2950 // now, for 2.10 projects, this is also done if the xml doc includes
2951 // dataset sequences not actually present in any particular view.
2953 for (int i = 0; i < vamsasSeq.length; i++)
2955 if (jseqs[i].getFeaturesCount() > 0)
2957 Features[] features = jseqs[i].getFeatures();
2958 for (int f = 0; f < features.length; f++)
2960 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2961 features[f].getType(), features[f].getDescription(),
2962 features[f].getStatus(), features[f].getBegin(),
2963 features[f].getEnd(), features[f].getFeatureGroup());
2965 sf.setScore(features[f].getScore());
2966 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2968 OtherData keyValue = features[f].getOtherData(od);
2969 if (keyValue.getKey().startsWith("LINK"))
2971 sf.addLink(keyValue.getValue());
2975 sf.setValue(keyValue.getKey(), keyValue.getValue());
2979 // adds feature to datasequence's feature set (since Jalview 2.10)
2980 al.getSequenceAt(i).addSequenceFeature(sf);
2983 if (vamsasSeq[i].getDBRefCount() > 0)
2985 // adds dbrefs to datasequence's set (since Jalview 2.10)
2987 al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
2988 : al.getSequenceAt(i).getDatasetSequence(),
2991 if (jseqs[i].getPdbidsCount() > 0)
2993 Pdbids[] ids = jseqs[i].getPdbids();
2994 for (int p = 0; p < ids.length; p++)
2996 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2997 entry.setId(ids[p].getId());
2998 if (ids[p].getType() != null)
3000 if (PDBEntry.Type.getType(ids[p].getType()) != null)
3002 entry.setType(PDBEntry.Type.getType(ids[p].getType()));
3006 entry.setType(PDBEntry.Type.FILE);
3009 if (ids[p].getFile() != null)
3011 if (!pdbloaded.containsKey(ids[p].getFile()))
3013 entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
3018 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
3021 if (ids[p].getPdbentryItem() != null)
3023 entry.setProperty(new Hashtable());
3024 for (PdbentryItem item : ids[p].getPdbentryItem())
3026 for (Property pr : item.getProperty())
3028 entry.getProperty().put(pr.getName(), pr.getValue());
3032 StructureSelectionManager.getStructureSelectionManager(
3033 Desktop.instance).registerPDBEntry(entry);
3034 // adds PDBEntry to datasequence's set (since Jalview 2.10)
3035 if (al.getSequenceAt(i).getDatasetSequence() != null)
3037 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
3041 al.getSequenceAt(i).addPDBId(entry);
3046 } // end !multipleview
3048 // ///////////////////////////////
3049 // LOAD SEQUENCE MAPPINGS
3051 if (vamsasSet.getAlcodonFrameCount() > 0)
3053 // TODO Potentially this should only be done once for all views of an
3055 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
3056 for (int i = 0; i < alc.length; i++)
3058 AlignedCodonFrame cf = new AlignedCodonFrame();
3059 if (alc[i].getAlcodMapCount() > 0)
3061 AlcodMap[] maps = alc[i].getAlcodMap();
3062 for (int m = 0; m < maps.length; m++)
3064 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
3066 jalview.datamodel.Mapping mapping = null;
3067 // attach to dna sequence reference.
3068 if (maps[m].getMapping() != null)
3070 mapping = addMapping(maps[m].getMapping());
3071 if (dnaseq != null && mapping.getTo() != null)
3073 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
3078 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
3083 al.addCodonFrame(cf);
3088 // ////////////////////////////////
3090 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
3093 * store any annotations which forward reference a group's ID
3095 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
3097 if (vamsasSet.getAnnotationCount() > 0)
3099 Annotation[] an = vamsasSet.getAnnotation();
3101 for (int i = 0; i < an.length; i++)
3103 Annotation annotation = an[i];
3106 * test if annotation is automatically calculated for this view only
3108 boolean autoForView = false;
3109 if (annotation.getLabel().equals("Quality")
3110 || annotation.getLabel().equals("Conservation")
3111 || annotation.getLabel().equals("Consensus"))
3113 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3115 if (!annotation.hasAutoCalculated())
3117 annotation.setAutoCalculated(true);
3121 || (annotation.hasAutoCalculated() && annotation
3122 .isAutoCalculated()))
3124 // remove ID - we don't recover annotation from other views for
3125 // view-specific annotation
3126 annotation.setId(null);
3129 // set visiblity for other annotation in this view
3130 String annotationId = annotation.getId();
3131 if (annotationId != null && annotationIds.containsKey(annotationId))
3133 AlignmentAnnotation jda = annotationIds.get(annotationId);
3134 // in principle Visible should always be true for annotation displayed
3135 // in multiple views
3136 if (annotation.hasVisible())
3138 jda.visible = annotation.getVisible();
3141 al.addAnnotation(jda);
3145 // Construct new annotation from model.
3146 AnnotationElement[] ae = annotation.getAnnotationElement();
3147 jalview.datamodel.Annotation[] anot = null;
3148 java.awt.Color firstColour = null;
3150 if (!annotation.getScoreOnly())
3152 anot = new jalview.datamodel.Annotation[al.getWidth()];
3153 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3155 anpos = ae[aa].getPosition();
3157 if (anpos >= anot.length)
3162 anot[anpos] = new jalview.datamodel.Annotation(
3164 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3165 (ae[aa].getSecondaryStructure() == null || ae[aa]
3166 .getSecondaryStructure().length() == 0) ? ' '
3167 : ae[aa].getSecondaryStructure().charAt(0),
3171 // JBPNote: Consider verifying dataflow for IO of secondary
3172 // structure annotation read from Stockholm files
3173 // this was added to try to ensure that
3174 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3176 // anot[ae[aa].getPosition()].displayCharacter = "";
3178 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3179 if (firstColour == null)
3181 firstColour = anot[anpos].colour;
3185 jalview.datamodel.AlignmentAnnotation jaa = null;
3187 if (annotation.getGraph())
3189 float llim = 0, hlim = 0;
3190 // if (autoForView || an[i].isAutoCalculated()) {
3193 jaa = new jalview.datamodel.AlignmentAnnotation(
3194 annotation.getLabel(), annotation.getDescription(), anot,
3195 llim, hlim, annotation.getGraphType());
3197 jaa.graphGroup = annotation.getGraphGroup();
3198 jaa._linecolour = firstColour;
3199 if (annotation.getThresholdLine() != null)
3201 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3202 .getThresholdLine().getValue(), annotation
3203 .getThresholdLine().getLabel(), new java.awt.Color(
3204 annotation.getThresholdLine().getColour())));
3207 if (autoForView || annotation.isAutoCalculated())
3209 // Hardwire the symbol display line to ensure that labels for
3210 // histograms are displayed
3216 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3217 an[i].getDescription(), anot);
3218 jaa._linecolour = firstColour;
3220 // register new annotation
3221 if (an[i].getId() != null)
3223 annotationIds.put(an[i].getId(), jaa);
3224 jaa.annotationId = an[i].getId();
3226 // recover sequence association
3227 String sequenceRef = an[i].getSequenceRef();
3228 if (sequenceRef != null)
3230 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3231 SequenceI sequence = seqRefIds.get(sequenceRef);
3232 if (sequence == null)
3234 // in pre-2.9 projects sequence ref is to sequence name
3235 sequence = al.findName(sequenceRef);
3237 if (sequence != null)
3239 jaa.createSequenceMapping(sequence, 1, true);
3240 sequence.addAlignmentAnnotation(jaa);
3243 // and make a note of any group association
3244 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3246 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3247 .get(an[i].getGroupRef());
3250 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3251 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3256 if (an[i].hasScore())
3258 jaa.setScore(an[i].getScore());
3260 if (an[i].hasVisible())
3262 jaa.visible = an[i].getVisible();
3265 if (an[i].hasCentreColLabels())
3267 jaa.centreColLabels = an[i].getCentreColLabels();
3270 if (an[i].hasScaleColLabels())
3272 jaa.scaleColLabel = an[i].getScaleColLabels();
3274 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3276 // newer files have an 'autoCalculated' flag and store calculation
3277 // state in viewport properties
3278 jaa.autoCalculated = true; // means annotation will be marked for
3279 // update at end of load.
3281 if (an[i].hasGraphHeight())
3283 jaa.graphHeight = an[i].getGraphHeight();
3285 if (an[i].hasBelowAlignment())
3287 jaa.belowAlignment = an[i].isBelowAlignment();
3289 jaa.setCalcId(an[i].getCalcId());
3290 if (an[i].getPropertyCount() > 0)
3292 for (jalview.schemabinding.version2.Property prop : an[i]
3295 jaa.setProperty(prop.getName(), prop.getValue());
3298 if (jaa.autoCalculated)
3300 autoAlan.add(new JvAnnotRow(i, jaa));
3303 // if (!autoForView)
3305 // add autocalculated group annotation and any user created annotation
3307 al.addAnnotation(jaa);
3311 // ///////////////////////
3313 // Create alignment markup and styles for this view
3314 if (jms.getJGroupCount() > 0)
3316 JGroup[] groups = jms.getJGroup();
3317 boolean addAnnotSchemeGroup = false;
3318 for (int i = 0; i < groups.length; i++)
3320 JGroup jGroup = groups[i];
3321 ColourSchemeI cs = null;
3322 if (jGroup.getColour() != null)
3324 if (jGroup.getColour().startsWith("ucs"))
3326 cs = getUserColourScheme(jms, jGroup.getColour());
3328 else if (jGroup.getColour().equals("AnnotationColourGradient")
3329 && jGroup.getAnnotationColours() != null)
3331 addAnnotSchemeGroup = true;
3336 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3341 cs.setThreshold(jGroup.getPidThreshold(), true);
3345 Vector<SequenceI> seqs = new Vector<SequenceI>();
3347 for (int s = 0; s < jGroup.getSeqCount(); s++)
3349 String seqId = jGroup.getSeq(s) + "";
3350 SequenceI ts = seqRefIds.get(seqId);
3354 seqs.addElement(ts);
3358 if (seqs.size() < 1)
3363 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3364 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3365 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3367 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3369 sg.textColour = new Colour(jGroup.getTextCol1());
3370 sg.textColour2 = new Colour(jGroup.getTextCol2());
3371 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3372 .isShowUnconserved() : false);
3373 sg.thresholdTextColour = jGroup.getTextColThreshold();
3374 if (jGroup.hasShowConsensusHistogram())
3376 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3379 if (jGroup.hasShowSequenceLogo())
3381 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3383 if (jGroup.hasNormaliseSequenceLogo())
3385 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3387 if (jGroup.hasIgnoreGapsinConsensus())
3389 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3391 if (jGroup.getConsThreshold() != 0)
3393 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3394 "All", ResidueProperties.propHash, 3,
3395 sg.getSequences(null), 0, sg.getWidth() - 1);
3397 c.verdict(false, 25);
3398 sg.cs.setConservation(c);
3401 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3403 // re-instate unique group/annotation row reference
3404 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3408 for (AlignmentAnnotation jaa : jaal)
3411 if (jaa.autoCalculated)
3413 // match up and try to set group autocalc alignment row for this
3415 if (jaa.label.startsWith("Consensus for "))
3417 sg.setConsensus(jaa);
3419 // match up and try to set group autocalc alignment row for this
3421 if (jaa.label.startsWith("Conservation for "))
3423 sg.setConservationRow(jaa);
3430 if (addAnnotSchemeGroup)
3432 // reconstruct the annotation colourscheme
3433 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3434 null, al, jms, false);
3440 // only dataset in this model, so just return.
3443 // ///////////////////////////////
3446 // If we just load in the same jar file again, the sequenceSetId
3447 // will be the same, and we end up with multiple references
3448 // to the same sequenceSet. We must modify this id on load
3449 // so that each load of the file gives a unique id
3450 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3451 String viewId = (view.getId() == null ? null : view.getId()
3453 AlignFrame af = null;
3454 AlignViewport av = null;
3455 // now check to see if we really need to create a new viewport.
3456 if (multipleView && viewportsAdded.size() == 0)
3458 // We recovered an alignment for which a viewport already exists.
3459 // TODO: fix up any settings necessary for overlaying stored state onto
3460 // state recovered from another document. (may not be necessary).
3461 // we may need a binding from a viewport in memory to one recovered from
3463 // and then recover its containing af to allow the settings to be applied.
3464 // TODO: fix for vamsas demo
3466 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3468 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3469 if (seqsetobj != null)
3471 if (seqsetobj instanceof String)
3473 uniqueSeqSetId = (String) seqsetobj;
3475 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3481 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3487 * indicate that annotation colours are applied across all groups (pre
3488 * Jalview 2.8.1 behaviour)
3490 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3491 "2.8.1", object.getVersion());
3493 AlignmentPanel ap = null;
3494 boolean isnewview = true;
3497 // Check to see if this alignment already has a view id == viewId
3498 jalview.gui.AlignmentPanel views[] = Desktop
3499 .getAlignmentPanels(uniqueSeqSetId);
3500 if (views != null && views.length > 0)
3502 for (int v = 0; v < views.length; v++)
3504 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3506 // recover the existing alignpanel, alignframe, viewport
3507 af = views[v].alignFrame;
3510 // TODO: could even skip resetting view settings if we don't want to
3511 // change the local settings from other jalview processes
3520 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3521 uniqueSeqSetId, viewId, autoAlan);
3527 * Load any trees, PDB structures and viewers
3529 * Not done if flag is false (when this method is used for New View)
3531 if (loadTreesAndStructures)
3533 loadTrees(jms, view, af, av, ap);
3534 loadPDBStructures(jprovider, jseqs, af, ap);
3535 loadRnaViewers(jprovider, jseqs, ap);
3537 // and finally return.
3542 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3543 * panel is restored from separate jar entries, two (gapped and trimmed) per
3544 * sequence and secondary structure.
3546 * Currently each viewer shows just one sequence and structure (gapped and
3547 * trimmed), however this method is designed to support multiple sequences or
3548 * structures in viewers if wanted in future.
3554 private void loadRnaViewers(jarInputStreamProvider jprovider,
3555 JSeq[] jseqs, AlignmentPanel ap)
3558 * scan the sequences for references to viewers; create each one the first
3559 * time it is referenced, add Rna models to existing viewers
3561 for (JSeq jseq : jseqs)
3563 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3565 RnaViewer viewer = jseq.getRnaViewer(i);
3566 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3567 uniqueSetSuffix, ap);
3569 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3571 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3572 SequenceI seq = seqRefIds.get(jseq.getId());
3573 AlignmentAnnotation ann = this.annotationIds.get(ss
3574 .getAnnotationId());
3577 * add the structure to the Varna display (with session state copied
3578 * from the jar to a temporary file)
3580 boolean gapped = ss.isGapped();
3581 String rnaTitle = ss.getTitle();
3582 String sessionState = ss.getViewerState();
3583 String tempStateFile = copyJarEntry(jprovider, sessionState,
3585 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3586 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3588 appVarna.setInitialSelection(viewer.getSelectedRna());
3594 * Locate and return an already instantiated matching AppVarna, or create one
3598 * @param viewIdSuffix
3602 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3603 String viewIdSuffix, AlignmentPanel ap)
3606 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3607 * if load is repeated
3609 String postLoadId = viewer.getViewId() + viewIdSuffix;
3610 for (JInternalFrame frame : getAllFrames())
3612 if (frame instanceof AppVarna)
3614 AppVarna varna = (AppVarna) frame;
3615 if (postLoadId.equals(varna.getViewId()))
3617 // this viewer is already instantiated
3618 // could in future here add ap as another 'parent' of the
3619 // AppVarna window; currently just 1-to-many
3626 * viewer not found - make it
3628 RnaViewerModel model = new RnaViewerModel(postLoadId,
3629 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3630 viewer.getWidth(), viewer.getHeight(),
3631 viewer.getDividerLocation());
3632 AppVarna varna = new AppVarna(model, ap);
3638 * Load any saved trees
3646 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3647 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3649 // TODO result of automated refactoring - are all these parameters needed?
3652 for (int t = 0; t < jms.getTreeCount(); t++)
3655 Tree tree = jms.getTree(t);
3657 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3660 tp = af.ShowNewickTree(
3661 new jalview.io.NewickFile(tree.getNewick()),
3662 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3663 tree.getXpos(), tree.getYpos());
3664 if (tree.getId() != null)
3666 // perhaps bind the tree id to something ?
3671 // update local tree attributes ?
3672 // TODO: should check if tp has been manipulated by user - if so its
3673 // settings shouldn't be modified
3674 tp.setTitle(tree.getTitle());
3675 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3676 .getWidth(), tree.getHeight()));
3677 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3680 tp.treeCanvas.av = av; // af.viewport;
3681 tp.treeCanvas.ap = ap; // af.alignPanel;
3686 warn("There was a problem recovering stored Newick tree: \n"
3687 + tree.getNewick());
3691 tp.fitToWindow.setState(tree.getFitToWindow());
3692 tp.fitToWindow_actionPerformed(null);
3694 if (tree.getFontName() != null)
3696 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3697 .getFontStyle(), tree.getFontSize()));
3701 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3702 .getFontStyle(), tree.getFontSize()));
3705 tp.showPlaceholders(tree.getMarkUnlinked());
3706 tp.showBootstrap(tree.getShowBootstrap());
3707 tp.showDistances(tree.getShowDistances());
3709 tp.treeCanvas.threshold = tree.getThreshold();
3711 if (tree.getCurrentTree())
3713 af.viewport.setCurrentTree(tp.getTree());
3717 } catch (Exception ex)
3719 ex.printStackTrace();
3724 * Load and link any saved structure viewers.
3731 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3732 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3735 * Run through all PDB ids on the alignment, and collect mappings between
3736 * distinct view ids and all sequences referring to that view.
3738 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3740 for (int i = 0; i < jseqs.length; i++)
3742 if (jseqs[i].getPdbidsCount() > 0)
3744 Pdbids[] ids = jseqs[i].getPdbids();
3745 for (int p = 0; p < ids.length; p++)
3747 final int structureStateCount = ids[p].getStructureStateCount();
3748 for (int s = 0; s < structureStateCount; s++)
3750 // check to see if we haven't already created this structure view
3751 final StructureState structureState = ids[p]
3752 .getStructureState(s);
3753 String sviewid = (structureState.getViewId() == null) ? null
3754 : structureState.getViewId() + uniqueSetSuffix;
3755 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3756 // Originally : ids[p].getFile()
3757 // : TODO: verify external PDB file recovery still works in normal
3758 // jalview project load
3759 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
3761 jpdb.setId(ids[p].getId());
3763 int x = structureState.getXpos();
3764 int y = structureState.getYpos();
3765 int width = structureState.getWidth();
3766 int height = structureState.getHeight();
3768 // Probably don't need to do this anymore...
3769 // Desktop.desktop.getComponentAt(x, y);
3770 // TODO: NOW: check that this recovers the PDB file correctly.
3771 String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
3773 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3775 if (sviewid == null)
3777 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3780 if (!structureViewers.containsKey(sviewid))
3782 structureViewers.put(sviewid,
3783 new StructureViewerModel(x, y, width, height, false,
3784 false, true, structureState.getViewId(),
3785 structureState.getType()));
3786 // Legacy pre-2.7 conversion JAL-823 :
3787 // do not assume any view has to be linked for colour by
3791 // assemble String[] { pdb files }, String[] { id for each
3792 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3793 // seqs_file 2}, boolean[] {
3794 // linkAlignPanel,superposeWithAlignpanel}} from hash
3795 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3796 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3797 | (structureState.hasAlignwithAlignPanel() ? structureState
3798 .getAlignwithAlignPanel() : false));
3801 * Default colour by linked panel to false if not specified (e.g.
3802 * for pre-2.7 projects)
3804 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3805 colourWithAlignPanel |= (structureState
3806 .hasColourwithAlignPanel() ? structureState
3807 .getColourwithAlignPanel() : false);
3808 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3811 * Default colour by viewer to true if not specified (e.g. for
3814 boolean colourByViewer = jmoldat.isColourByViewer();
3815 colourByViewer &= structureState.hasColourByJmol() ? structureState
3816 .getColourByJmol() : true;
3817 jmoldat.setColourByViewer(colourByViewer);
3819 if (jmoldat.getStateData().length() < structureState
3820 .getContent().length())
3823 jmoldat.setStateData(structureState.getContent());
3826 if (ids[p].getFile() != null)
3828 File mapkey = new File(ids[p].getFile());
3829 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3830 if (seqstrmaps == null)
3832 jmoldat.getFileData().put(
3834 seqstrmaps = jmoldat.new StructureData(pdbFile,
3837 if (!seqstrmaps.getSeqList().contains(seq))
3839 seqstrmaps.getSeqList().add(seq);
3845 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");
3852 // Instantiate the associated structure views
3853 for (Entry<String, StructureViewerModel> entry : structureViewers
3858 createOrLinkStructureViewer(entry, af, ap, jprovider);
3859 } catch (Exception e)
3861 System.err.println("Error loading structure viewer: "
3863 // failed - try the next one
3875 protected void createOrLinkStructureViewer(
3876 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3877 AlignmentPanel ap, jarInputStreamProvider jprovider)
3879 final StructureViewerModel stateData = viewerData.getValue();
3882 * Search for any viewer windows already open from other alignment views
3883 * that exactly match the stored structure state
3885 StructureViewerBase comp = findMatchingViewer(viewerData);
3889 linkStructureViewer(ap, comp, stateData);
3894 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3895 * "viewer_"+stateData.viewId
3897 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3899 createChimeraViewer(viewerData, af, jprovider);
3904 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3906 createJmolViewer(viewerData, af, jprovider);
3911 * Create a new Chimera viewer.
3917 protected void createChimeraViewer(
3918 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3919 jarInputStreamProvider jprovider)
3921 StructureViewerModel data = viewerData.getValue();
3922 String chimeraSessionFile = data.getStateData();
3925 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3927 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3928 * 'uniquified' sviewid used to reconstruct the viewer here
3930 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3931 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3934 Set<Entry<File, StructureData>> fileData = data.getFileData()
3936 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3937 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3938 for (Entry<File, StructureData> pdb : fileData)
3940 String filePath = pdb.getValue().getFilePath();
3941 String pdbId = pdb.getValue().getPdbId();
3942 // pdbs.add(new PDBEntry(filePath, pdbId));
3943 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3944 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3945 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3949 boolean colourByChimera = data.isColourByViewer();
3950 boolean colourBySequence = data.isColourWithAlignPanel();
3952 // TODO use StructureViewer as a factory here, see JAL-1761
3953 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3954 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3956 String newViewId = viewerData.getKey();
3958 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3959 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3960 colourBySequence, newViewId);
3961 cvf.setSize(data.getWidth(), data.getHeight());
3962 cvf.setLocation(data.getX(), data.getY());
3966 * Create a new Jmol window. First parse the Jmol state to translate filenames
3967 * loaded into the view, and record the order in which files are shown in the
3968 * Jmol view, so we can add the sequence mappings in same order.
3974 protected void createJmolViewer(
3975 final Entry<String, StructureViewerModel> viewerData,
3976 AlignFrame af, jarInputStreamProvider jprovider)
3978 final StructureViewerModel svattrib = viewerData.getValue();
3979 String state = svattrib.getStateData();
3982 * Pre-2.9: state element value is the Jmol state string
3984 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3987 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3989 state = readJarEntry(jprovider,
3990 getViewerJarEntryName(svattrib.getViewId()));
3993 List<String> pdbfilenames = new ArrayList<String>();
3994 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3995 List<String> pdbids = new ArrayList<String>();
3996 StringBuilder newFileLoc = new StringBuilder(64);
3997 int cp = 0, ncp, ecp;
3998 Map<File, StructureData> oldFiles = svattrib.getFileData();
3999 while ((ncp = state.indexOf("load ", cp)) > -1)
4003 // look for next filename in load statement
4004 newFileLoc.append(state.substring(cp,
4005 ncp = (state.indexOf("\"", ncp + 1) + 1)));
4006 String oldfilenam = state.substring(ncp,
4007 ecp = state.indexOf("\"", ncp));
4008 // recover the new mapping data for this old filename
4009 // have to normalize filename - since Jmol and jalview do
4011 // translation differently.
4012 StructureData filedat = oldFiles.get(new File(oldfilenam));
4013 if (filedat == null)
4015 String reformatedOldFilename = oldfilenam.replaceAll("/",
4017 filedat = oldFiles.get(new File(reformatedOldFilename));
4019 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
4020 pdbfilenames.add(filedat.getFilePath());
4021 pdbids.add(filedat.getPdbId());
4022 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4023 newFileLoc.append("\"");
4024 cp = ecp + 1; // advance beyond last \" and set cursor so we can
4025 // look for next file statement.
4026 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
4030 // just append rest of state
4031 newFileLoc.append(state.substring(cp));
4035 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
4036 newFileLoc = new StringBuilder(state);
4037 newFileLoc.append("; load append ");
4038 for (File id : oldFiles.keySet())
4040 // add this and any other pdb files that should be present in
4042 StructureData filedat = oldFiles.get(id);
4043 newFileLoc.append(filedat.getFilePath());
4044 pdbfilenames.add(filedat.getFilePath());
4045 pdbids.add(filedat.getPdbId());
4046 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
4047 newFileLoc.append(" \"");
4048 newFileLoc.append(filedat.getFilePath());
4049 newFileLoc.append("\"");
4052 newFileLoc.append(";");
4055 if (newFileLoc.length() == 0)
4059 int histbug = newFileLoc.indexOf("history = ");
4063 * change "history = [true|false];" to "history = [1|0];"
4066 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
4067 String val = (diff == -1) ? null : newFileLoc
4068 .substring(histbug, diff);
4069 if (val != null && val.length() >= 4)
4071 if (val.contains("e")) // eh? what can it be?
4073 if (val.trim().equals("true"))
4081 newFileLoc.replace(histbug, diff, val);
4086 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
4088 final String[] id = pdbids.toArray(new String[pdbids.size()]);
4089 final SequenceI[][] sq = seqmaps
4090 .toArray(new SequenceI[seqmaps.size()][]);
4091 final String fileloc = newFileLoc.toString();
4092 final String sviewid = viewerData.getKey();
4093 final AlignFrame alf = af;
4094 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
4095 svattrib.getWidth(), svattrib.getHeight());
4098 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
4103 JalviewStructureDisplayI sview = null;
4106 sview = new StructureViewer(alf.alignPanel
4107 .getStructureSelectionManager()).createView(
4108 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
4109 alf.alignPanel, svattrib, fileloc, rect, sviewid);
4110 addNewStructureViewer(sview);
4111 } catch (OutOfMemoryError ex)
4113 new OOMWarning("restoring structure view for PDB id " + id,
4114 (OutOfMemoryError) ex.getCause());
4115 if (sview != null && sview.isVisible())
4117 sview.closeViewer(false);
4118 sview.setVisible(false);
4124 } catch (InvocationTargetException ex)
4126 warn("Unexpected error when opening Jmol view.", ex);
4128 } catch (InterruptedException e)
4130 // e.printStackTrace();
4136 * Generates a name for the entry in the project jar file to hold state
4137 * information for a structure viewer
4142 protected String getViewerJarEntryName(String viewId)
4144 return VIEWER_PREFIX + viewId;
4148 * Returns any open frame that matches given structure viewer data. The match
4149 * is based on the unique viewId, or (for older project versions) the frame's
4155 protected StructureViewerBase findMatchingViewer(
4156 Entry<String, StructureViewerModel> viewerData)
4158 final String sviewid = viewerData.getKey();
4159 final StructureViewerModel svattrib = viewerData.getValue();
4160 StructureViewerBase comp = null;
4161 JInternalFrame[] frames = getAllFrames();
4162 for (JInternalFrame frame : frames)
4164 if (frame instanceof StructureViewerBase)
4167 * Post jalview 2.4 schema includes structure view id
4170 && ((StructureViewerBase) frame).getViewId()
4173 comp = (StructureViewerBase) frame;
4174 break; // break added in 2.9
4177 * Otherwise test for matching position and size of viewer frame
4179 else if (frame.getX() == svattrib.getX()
4180 && frame.getY() == svattrib.getY()
4181 && frame.getHeight() == svattrib.getHeight()
4182 && frame.getWidth() == svattrib.getWidth())
4184 comp = (StructureViewerBase) frame;
4185 // no break in faint hope of an exact match on viewId
4193 * Link an AlignmentPanel to an existing structure viewer.
4198 * @param useinViewerSuperpos
4199 * @param usetoColourbyseq
4200 * @param viewerColouring
4202 protected void linkStructureViewer(AlignmentPanel ap,
4203 StructureViewerBase viewer, StructureViewerModel stateData)
4205 // NOTE: if the jalview project is part of a shared session then
4206 // view synchronization should/could be done here.
4208 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4209 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4210 final boolean viewerColouring = stateData.isColourByViewer();
4211 Map<File, StructureData> oldFiles = stateData.getFileData();
4214 * Add mapping for sequences in this view to an already open viewer
4216 final AAStructureBindingModel binding = viewer.getBinding();
4217 for (File id : oldFiles.keySet())
4219 // add this and any other pdb files that should be present in the
4221 StructureData filedat = oldFiles.get(id);
4222 String pdbFile = filedat.getFilePath();
4223 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4224 binding.getSsm().setMapping(seq, null, pdbFile,
4225 jalview.io.AppletFormatAdapter.FILE);
4226 binding.addSequenceForStructFile(pdbFile, seq);
4228 // and add the AlignmentPanel's reference to the view panel
4229 viewer.addAlignmentPanel(ap);
4230 if (useinViewerSuperpos)
4232 viewer.useAlignmentPanelForSuperposition(ap);
4236 viewer.excludeAlignmentPanelForSuperposition(ap);
4238 if (usetoColourbyseq)
4240 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4244 viewer.excludeAlignmentPanelForColourbyseq(ap);
4249 * Get all frames within the Desktop.
4253 protected JInternalFrame[] getAllFrames()
4255 JInternalFrame[] frames = null;
4256 // TODO is this necessary - is it safe - risk of hanging?
4261 frames = Desktop.desktop.getAllFrames();
4262 } catch (ArrayIndexOutOfBoundsException e)
4264 // occasional No such child exceptions are thrown here...
4268 } catch (InterruptedException f)
4272 } while (frames == null);
4277 * Answers true if 'version' is equal to or later than 'supported', where each
4278 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4279 * changes. Development and test values for 'version' are leniently treated
4283 * - minimum version we are comparing against
4285 * - version of data being processsed
4288 public static boolean isVersionStringLaterThan(String supported,
4291 if (supported == null || version == null
4292 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4293 || version.equalsIgnoreCase("Test")
4294 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4296 System.err.println("Assuming project file with "
4297 + (version == null ? "null" : version)
4298 + " is compatible with Jalview version " + supported);
4303 return StringUtils.compareVersions(version, supported, "b") >= 0;
4307 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4309 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4311 if (newStructureViewers != null)
4313 sview.getBinding().setFinishedLoadingFromArchive(false);
4314 newStructureViewers.add(sview);
4318 protected void setLoadingFinishedForNewStructureViewers()
4320 if (newStructureViewers != null)
4322 for (JalviewStructureDisplayI sview : newStructureViewers)
4324 sview.getBinding().setFinishedLoadingFromArchive(true);
4326 newStructureViewers.clear();
4327 newStructureViewers = null;
4331 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4332 List<SequenceI> hiddenSeqs, AlignmentI al,
4333 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4334 String viewId, List<JvAnnotRow> autoAlan)
4336 AlignFrame af = null;
4337 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4338 uniqueSeqSetId, viewId);
4340 af.setFileName(file, "Jalview");
4342 for (int i = 0; i < JSEQ.length; i++)
4344 af.viewport.setSequenceColour(af.viewport.getAlignment()
4345 .getSequenceAt(i), new Colour(JSEQ[i].getColour()));
4350 af.getViewport().setColourByReferenceSeq(true);
4351 af.getViewport().setDisplayReferenceSeq(true);
4354 af.viewport.setGatherViewsHere(view.getGatheredViews());
4356 if (view.getSequenceSetId() != null)
4358 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4360 af.viewport.setSequenceSetId(uniqueSeqSetId);
4363 // propagate shared settings to this new view
4364 af.viewport.setHistoryList(av.getHistoryList());
4365 af.viewport.setRedoList(av.getRedoList());
4369 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4371 // TODO: check if this method can be called repeatedly without
4372 // side-effects if alignpanel already registered.
4373 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4375 // apply Hidden regions to view.
4376 if (hiddenSeqs != null)
4378 for (int s = 0; s < JSEQ.length; s++)
4380 SequenceGroup hidden = new SequenceGroup();
4381 boolean isRepresentative = false;
4382 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4384 isRepresentative = true;
4385 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4386 .getHiddenSequences(r));
4387 hidden.addSequence(sequenceToHide, false);
4388 // remove from hiddenSeqs list so we don't try to hide it twice
4389 hiddenSeqs.remove(sequenceToHide);
4391 if (isRepresentative)
4393 SequenceI representativeSequence = al.getSequenceAt(s);
4394 hidden.addSequence(representativeSequence, false);
4395 af.viewport.hideRepSequences(representativeSequence, hidden);
4399 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4401 af.viewport.hideSequence(hseqs);
4404 // recover view properties and display parameters
4405 if (view.getViewName() != null)
4407 af.viewport.viewName = view.getViewName();
4408 af.setInitialTabVisible();
4410 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4413 af.viewport.setShowAnnotation(view.getShowAnnotation());
4414 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4416 af.viewport.setColourText(view.getShowColourText());
4418 af.viewport.setConservationSelected(view.getConservationSelected());
4419 af.viewport.setShowJVSuffix(view.getShowFullId());
4420 af.viewport.setRightAlignIds(view.getRightAlignIds());
4421 af.viewport.setFont(
4422 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4423 .getFontSize()), true);
4424 ViewStyleI vs = af.viewport.getViewStyle();
4425 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4426 af.viewport.setViewStyle(vs);
4427 // TODO: allow custom charWidth/Heights to be restored by updating them
4428 // after setting font - which means set above to false
4429 af.viewport.setRenderGaps(view.getRenderGaps());
4430 af.viewport.setWrapAlignment(view.getWrapAlignment());
4431 af.viewport.setShowAnnotation(view.getShowAnnotation());
4433 af.viewport.setShowBoxes(view.getShowBoxes());
4435 af.viewport.setShowText(view.getShowText());
4437 af.viewport.setTextColour(new Colour(view.getTextCol1()));
4438 af.viewport.setTextColour2(new Colour(view.getTextCol2()));
4439 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4440 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4441 .isShowUnconserved() : false);
4442 af.viewport.setStartRes(view.getStartRes());
4443 af.viewport.setStartSeq(view.getStartSeq());
4444 af.alignPanel.updateLayout();
4445 ColourSchemeI cs = null;
4446 // apply colourschemes
4447 if (view.getBgColour() != null)
4449 if (view.getBgColour().startsWith("ucs"))
4451 cs = getUserColourScheme(jms, view.getBgColour());
4453 else if (view.getBgColour().startsWith("Annotation"))
4455 AnnotationColours viewAnnColour = view.getAnnotationColours();
4456 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4463 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4468 cs.setThreshold(view.getPidThreshold(), true);
4469 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4473 af.viewport.setGlobalColourScheme(cs);
4474 af.viewport.setColourAppliesToAllGroups(false);
4476 if (view.getConservationSelected() && cs != null)
4478 cs.setConservationInc(view.getConsThreshold());
4481 af.changeColour(cs);
4483 af.viewport.setColourAppliesToAllGroups(true);
4485 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4487 if (view.hasCentreColumnLabels())
4489 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4491 if (view.hasIgnoreGapsinConsensus())
4493 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4496 if (view.hasFollowHighlight())
4498 af.viewport.setFollowHighlight(view.getFollowHighlight());
4500 if (view.hasFollowSelection())
4502 af.viewport.followSelection = view.getFollowSelection();
4504 if (view.hasShowConsensusHistogram())
4506 af.viewport.setShowConsensusHistogram(view
4507 .getShowConsensusHistogram());
4511 af.viewport.setShowConsensusHistogram(true);
4513 if (view.hasShowSequenceLogo())
4515 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4519 af.viewport.setShowSequenceLogo(false);
4521 if (view.hasNormaliseSequenceLogo())
4523 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4525 if (view.hasShowDbRefTooltip())
4527 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4529 if (view.hasShowNPfeatureTooltip())
4531 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4533 if (view.hasShowGroupConsensus())
4535 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4539 af.viewport.setShowGroupConsensus(false);
4541 if (view.hasShowGroupConservation())
4543 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4547 af.viewport.setShowGroupConservation(false);
4550 // recover featre settings
4551 if (jms.getFeatureSettings() != null)
4553 FeaturesDisplayed fdi;
4554 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4555 String[] renderOrder = new String[jms.getFeatureSettings()
4556 .getSettingCount()];
4557 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4558 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4560 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4562 Setting setting = jms.getFeatureSettings().getSetting(fs);
4563 if (setting.hasMincolour())
4565 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4566 new Colour(new Color(setting.getMincolour())),
4567 new Colour(new Color(setting.getColour())),
4568 setting.getMin(), setting.getMax()) : new FeatureColour(
4569 new Colour(new Color(setting.getMincolour())),
4570 new Colour(new Color(setting.getColour())),
4572 if (setting.hasThreshold())
4574 gc.setThreshold(setting.getThreshold());
4575 int threshstate = setting.getThreshstate();
4576 // -1 = None, 0 = Below, 1 = Above threshold
4577 if (threshstate == 0)
4579 gc.setBelowThreshold(true);
4581 else if (threshstate == 1)
4583 gc.setAboveThreshold(true);
4586 gc.setAutoScaled(true); // default
4587 if (setting.hasAutoScale())
4589 gc.setAutoScaled(setting.getAutoScale());
4591 if (setting.hasColourByLabel())
4593 gc.setColourByLabel(setting.getColourByLabel());
4595 // and put in the feature colour table.
4596 featureColours.put(setting.getType(), gc);
4600 featureColours.put(setting.getType(), new FeatureColour(
4601 new Colour(new Color(setting.getColour()))));
4603 renderOrder[fs] = setting.getType();
4604 if (setting.hasOrder())
4606 featureOrder.put(setting.getType(), setting.getOrder());
4610 featureOrder.put(setting.getType(), new Float(fs
4611 / jms.getFeatureSettings().getSettingCount()));
4613 if (setting.getDisplay())
4615 fdi.setVisible(setting.getType());
4618 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4619 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4621 Group grp = jms.getFeatureSettings().getGroup(gs);
4622 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4624 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4625 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4626 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4627 FeatureRendererSettings frs = new FeatureRendererSettings(
4628 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4629 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4630 .transferSettings(frs);
4634 if (view.getHiddenColumnsCount() > 0)
4636 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4638 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4639 .getHiddenColumns(c).getEnd() // +1
4643 if (view.getCalcIdParam() != null)
4645 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4647 if (calcIdParam != null)
4649 if (recoverCalcIdParam(calcIdParam, af.viewport))
4654 warn("Couldn't recover parameters for "
4655 + calcIdParam.getCalcId());
4660 af.setMenusFromViewport(af.viewport);
4661 af.setTitle(view.getTitle());
4662 // TODO: we don't need to do this if the viewport is aready visible.
4664 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4665 * has a 'cdna/protein complement' view, in which case save it in order to
4666 * populate a SplitFrame once all views have been read in.
4668 String complementaryViewId = view.getComplementId();
4669 if (complementaryViewId == null)
4671 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4673 // recompute any autoannotation
4674 af.alignPanel.updateAnnotation(false, true);
4675 reorderAutoannotation(af, al, autoAlan);
4676 af.alignPanel.alignmentChanged();
4680 splitFrameCandidates.put(view, af);
4685 private ColourSchemeI constructAnnotationColour(
4686 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4687 JalviewModelSequence jms, boolean checkGroupAnnColour)
4689 boolean propagateAnnColour = false;
4690 ColourSchemeI cs = null;
4691 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4692 if (checkGroupAnnColour && al.getGroups() != null
4693 && al.getGroups().size() > 0)
4695 // pre 2.8.1 behaviour
4696 // check to see if we should transfer annotation colours
4697 propagateAnnColour = true;
4698 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4700 if (sg.cs instanceof AnnotationColourGradient)
4702 propagateAnnColour = false;
4706 // int find annotation
4707 if (annAlignment.getAlignmentAnnotation() != null)
4709 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4711 if (annAlignment.getAlignmentAnnotation()[i].label
4712 .equals(viewAnnColour.getAnnotation()))
4714 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4716 annAlignment.getAlignmentAnnotation()[i]
4717 .setThreshold(new jalview.datamodel.GraphLine(
4718 viewAnnColour.getThreshold(), "Threshold",
4719 java.awt.Color.black)
4724 if (viewAnnColour.getColourScheme().equals("None"))
4726 cs = new AnnotationColourGradient(
4727 annAlignment.getAlignmentAnnotation()[i],
4728 new java.awt.Color(viewAnnColour.getMinColour()),
4729 new java.awt.Color(viewAnnColour.getMaxColour()),
4730 viewAnnColour.getAboveThreshold());
4732 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4734 cs = new AnnotationColourGradient(
4735 annAlignment.getAlignmentAnnotation()[i],
4736 getUserColourScheme(jms,
4737 viewAnnColour.getColourScheme()),
4738 viewAnnColour.getAboveThreshold());
4742 cs = new AnnotationColourGradient(
4743 annAlignment.getAlignmentAnnotation()[i],
4744 ColourSchemeProperty.getColour(al,
4745 viewAnnColour.getColourScheme()),
4746 viewAnnColour.getAboveThreshold());
4748 if (viewAnnColour.hasPerSequence())
4750 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4753 if (viewAnnColour.hasPredefinedColours())
4755 ((AnnotationColourGradient) cs)
4756 .setPredefinedColours(viewAnnColour
4757 .isPredefinedColours());
4759 if (propagateAnnColour && al.getGroups() != null)
4761 // Also use these settings for all the groups
4762 for (int g = 0; g < al.getGroups().size(); g++)
4764 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4772 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4773 * new AnnotationColourGradient(
4774 * annAlignment.getAlignmentAnnotation()[i], new
4775 * java.awt.Color(viewAnnColour. getMinColour()), new
4776 * java.awt.Color(viewAnnColour. getMaxColour()),
4777 * viewAnnColour.getAboveThreshold()); } else
4780 sg.cs = new AnnotationColourGradient(
4781 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4782 viewAnnColour.getAboveThreshold());
4783 if (cs instanceof AnnotationColourGradient)
4785 if (viewAnnColour.hasPerSequence())
4787 ((AnnotationColourGradient) cs)
4788 .setSeqAssociated(viewAnnColour.isPerSequence());
4790 if (viewAnnColour.hasPredefinedColours())
4792 ((AnnotationColourGradient) cs)
4793 .setPredefinedColours(viewAnnColour
4794 .isPredefinedColours());
4810 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4811 List<JvAnnotRow> autoAlan)
4813 // copy over visualization settings for autocalculated annotation in the
4815 if (al.getAlignmentAnnotation() != null)
4818 * Kludge for magic autoannotation names (see JAL-811)
4820 String[] magicNames = new String[] { "Consensus", "Quality",
4822 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4823 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4824 for (String nm : magicNames)
4826 visan.put(nm, nullAnnot);
4828 for (JvAnnotRow auan : autoAlan)
4830 visan.put(auan.template.label
4831 + (auan.template.getCalcId() == null ? "" : "\t"
4832 + auan.template.getCalcId()), auan);
4834 int hSize = al.getAlignmentAnnotation().length;
4835 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4836 // work through any autoCalculated annotation already on the view
4837 // removing it if it should be placed in a different location on the
4838 // annotation panel.
4839 List<String> remains = new ArrayList<String>(visan.keySet());
4840 for (int h = 0; h < hSize; h++)
4842 jalview.datamodel.AlignmentAnnotation jalan = al
4843 .getAlignmentAnnotation()[h];
4844 if (jalan.autoCalculated)
4847 JvAnnotRow valan = visan.get(k = jalan.label);
4848 if (jalan.getCalcId() != null)
4850 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4855 // delete the auto calculated row from the alignment
4856 al.deleteAnnotation(jalan, false);
4860 if (valan != nullAnnot)
4862 if (jalan != valan.template)
4864 // newly created autoannotation row instance
4865 // so keep a reference to the visible annotation row
4866 // and copy over all relevant attributes
4867 if (valan.template.graphHeight >= 0)
4870 jalan.graphHeight = valan.template.graphHeight;
4872 jalan.visible = valan.template.visible;
4874 reorder.add(new JvAnnotRow(valan.order, jalan));
4879 // Add any (possibly stale) autocalculated rows that were not appended to
4880 // the view during construction
4881 for (String other : remains)
4883 JvAnnotRow othera = visan.get(other);
4884 if (othera != nullAnnot && othera.template.getCalcId() != null
4885 && othera.template.getCalcId().length() > 0)
4887 reorder.add(othera);
4890 // now put the automatic annotation in its correct place
4891 int s = 0, srt[] = new int[reorder.size()];
4892 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4893 for (JvAnnotRow jvar : reorder)
4896 srt[s++] = jvar.order;
4899 jalview.util.QuickSort.sort(srt, rws);
4900 // and re-insert the annotation at its correct position
4901 for (JvAnnotRow jvar : rws)
4903 al.addAnnotation(jvar.template, jvar.order);
4905 af.alignPanel.adjustAnnotationHeight();
4909 Hashtable skipList = null;
4912 * TODO remove this method
4915 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4916 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4917 * throw new Error("Implementation Error. No skipList defined for this
4918 * Jalview2XML instance."); } return (AlignFrame)
4919 * skipList.get(view.getSequenceSetId()); }
4923 * Check if the Jalview view contained in object should be skipped or not.
4926 * @return true if view's sequenceSetId is a key in skipList
4928 private boolean skipViewport(JalviewModel object)
4930 if (skipList == null)
4935 if (skipList.containsKey(id = object.getJalviewModelSequence()
4936 .getViewport()[0].getSequenceSetId()))
4938 if (Cache.log != null && Cache.log.isDebugEnabled())
4940 Cache.log.debug("Skipping seuqence set id " + id);
4947 public void addToSkipList(AlignFrame af)
4949 if (skipList == null)
4951 skipList = new Hashtable();
4953 skipList.put(af.getViewport().getSequenceSetId(), af);
4956 public void clearSkipList()
4958 if (skipList != null)
4965 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4966 boolean ignoreUnrefed)
4968 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4970 Vector dseqs = null;
4973 // create a list of new dataset sequences
4974 dseqs = new Vector();
4976 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4978 Sequence vamsasSeq = vamsasSet.getSequence(i);
4979 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
4981 // create a new dataset
4984 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4985 dseqs.copyInto(dsseqs);
4986 ds = new jalview.datamodel.Alignment(dsseqs);
4987 debug("Created new dataset " + vamsasSet.getDatasetId()
4988 + " for alignment " + System.identityHashCode(al));
4989 addDatasetRef(vamsasSet.getDatasetId(), ds);
4991 // set the dataset for the newly imported alignment.
4992 if (al.getDataset() == null && !ignoreUnrefed)
5001 * sequence definition to create/merge dataset sequence for
5005 * vector to add new dataset sequence to
5006 * @param ignoreUnrefed
5007 * - when true, don't create new sequences from vamsasSeq if it's id
5008 * doesn't already have an asssociated Jalview sequence.
5010 * - used to reorder the sequence in the alignment according to the
5011 * vamsasSeq array ordering, to preserve ordering of dataset
5013 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
5014 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
5016 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
5018 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
5019 boolean reorder = false;
5020 SequenceI dsq = null;
5021 if (sq != null && sq.getDatasetSequence() != null)
5023 dsq = sq.getDatasetSequence();
5029 if (sq == null && ignoreUnrefed)
5033 String sqid = vamsasSeq.getDsseqid();
5036 // need to create or add a new dataset sequence reference to this sequence
5039 dsq = seqRefIds.get(sqid);
5044 // make a new dataset sequence
5045 dsq = sq.createDatasetSequence();
5048 // make up a new dataset reference for this sequence
5049 sqid = seqHash(dsq);
5051 dsq.setVamsasId(uniqueSetSuffix + sqid);
5052 seqRefIds.put(sqid, dsq);
5057 dseqs.addElement(dsq);
5062 ds.addSequence(dsq);
5068 { // make this dataset sequence sq's dataset sequence
5069 sq.setDatasetSequence(dsq);
5070 // and update the current dataset alignment
5075 if (!dseqs.contains(dsq))
5082 if (ds.findIndex(dsq) < 0)
5084 ds.addSequence(dsq);
5091 // TODO: refactor this as a merge dataset sequence function
5092 // now check that sq (the dataset sequence) sequence really is the union of
5093 // all references to it
5094 // boolean pre = sq.getStart() < dsq.getStart();
5095 // boolean post = sq.getEnd() > dsq.getEnd();
5099 // StringBuffer sb = new StringBuffer();
5100 String newres = jalview.analysis.AlignSeq.extractGaps(
5101 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
5102 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
5103 && newres.length() > dsq.getLength())
5105 // Update with the longer sequence.
5109 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
5110 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
5111 * sb.append(newres.substring(newres.length() - sq.getEnd() -
5112 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
5114 dsq.setSequence(newres);
5116 // TODO: merges will never happen if we 'know' we have the real dataset
5117 // sequence - this should be detected when id==dssid
5119 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
5120 // + (pre ? "prepended" : "") + " "
5121 // + (post ? "appended" : ""));
5126 // sequence refs are identical. We may need to update the existing dataset
5127 // alignment with this one, though.
5128 if (ds != null && dseqs == null)
5130 int opos = ds.findIndex(dsq);
5131 SequenceI tseq = null;
5132 if (opos != -1 && vseqpos != opos)
5134 // remove from old position
5135 ds.deleteSequence(dsq);
5137 if (vseqpos < ds.getHeight())
5139 if (vseqpos != opos)
5141 // save sequence at destination position
5142 tseq = ds.getSequenceAt(vseqpos);
5143 ds.replaceSequenceAt(vseqpos, dsq);
5144 ds.addSequence(tseq);
5149 ds.addSequence(dsq);
5156 * TODO use AlignmentI here and in related methods - needs
5157 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
5159 Hashtable<String, AlignmentI> datasetIds = null;
5161 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
5163 private AlignmentI getDatasetFor(String datasetId)
5165 if (datasetIds == null)
5167 datasetIds = new Hashtable<String, AlignmentI>();
5170 if (datasetIds.containsKey(datasetId))
5172 return datasetIds.get(datasetId);
5177 private void addDatasetRef(String datasetId, AlignmentI dataset)
5179 if (datasetIds == null)
5181 datasetIds = new Hashtable<String, AlignmentI>();
5183 datasetIds.put(datasetId, dataset);
5187 * make a new dataset ID for this jalview dataset alignment
5192 private String getDatasetIdRef(AlignmentI dataset)
5194 if (dataset.getDataset() != null)
5196 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5198 String datasetId = makeHashCode(dataset, null);
5199 if (datasetId == null)
5201 // make a new datasetId and record it
5202 if (dataset2Ids == null)
5204 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5208 datasetId = dataset2Ids.get(dataset);
5210 if (datasetId == null)
5212 datasetId = "ds" + dataset2Ids.size() + 1;
5213 dataset2Ids.put(dataset, datasetId);
5219 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5221 for (int d = 0; d < sequence.getDBRefCount(); d++)
5223 DBRef dr = sequence.getDBRef(d);
5224 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5225 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5226 .getVersion(), sequence.getDBRef(d).getAccessionId());
5227 if (dr.getMapping() != null)
5229 entry.setMap(addMapping(dr.getMapping()));
5231 datasetSequence.addDBRef(entry);
5235 private jalview.datamodel.Mapping addMapping(Mapping m)
5237 SequenceI dsto = null;
5238 // Mapping m = dr.getMapping();
5239 int fr[] = new int[m.getMapListFromCount() * 2];
5240 Enumeration f = m.enumerateMapListFrom();
5241 for (int _i = 0; f.hasMoreElements(); _i += 2)
5243 MapListFrom mf = (MapListFrom) f.nextElement();
5244 fr[_i] = mf.getStart();
5245 fr[_i + 1] = mf.getEnd();
5247 int fto[] = new int[m.getMapListToCount() * 2];
5248 f = m.enumerateMapListTo();
5249 for (int _i = 0; f.hasMoreElements(); _i += 2)
5251 MapListTo mf = (MapListTo) f.nextElement();
5252 fto[_i] = mf.getStart();
5253 fto[_i + 1] = mf.getEnd();
5255 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5256 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5257 if (m.getMappingChoice() != null)
5259 MappingChoice mc = m.getMappingChoice();
5260 if (mc.getDseqFor() != null)
5262 String dsfor = "" + mc.getDseqFor();
5263 if (seqRefIds.containsKey(dsfor))
5268 jmap.setTo(seqRefIds.get(dsfor));
5272 frefedSequence.add(newMappingRef(dsfor, jmap));
5278 * local sequence definition
5280 Sequence ms = mc.getSequence();
5281 SequenceI djs = null;
5282 String sqid = ms.getDsseqid();
5283 if (sqid != null && sqid.length() > 0)
5286 * recover dataset sequence
5288 djs = seqRefIds.get(sqid);
5293 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5294 sqid = ((Object) ms).toString(); // make up a new hascode for
5295 // undefined dataset sequence hash
5296 // (unlikely to happen)
5302 * make a new dataset sequence and add it to refIds hash
5304 djs = new jalview.datamodel.Sequence(ms.getName(),
5306 djs.setStart(jmap.getMap().getToLowest());
5307 djs.setEnd(jmap.getMap().getToHighest());
5308 djs.setVamsasId(uniqueSetSuffix + sqid);
5310 incompleteSeqs.put(sqid, djs);
5311 seqRefIds.put(sqid, djs);
5314 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5323 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5324 boolean keepSeqRefs)
5327 JalviewModel jm = saveState(ap, null, null, null);
5332 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5336 uniqueSetSuffix = "";
5337 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5342 if (this.frefedSequence == null)
5344 frefedSequence = new Vector();
5347 viewportsAdded.clear();
5349 AlignFrame af = loadFromObject(jm, null, false, null);
5350 af.alignPanels.clear();
5351 af.closeMenuItem_actionPerformed(true);
5354 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5355 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5356 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5357 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5358 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5361 return af.alignPanel;
5365 * flag indicating if hashtables should be cleared on finalization TODO this
5366 * flag may not be necessary
5368 private final boolean _cleartables = true;
5370 private Hashtable jvids2vobj;
5375 * @see java.lang.Object#finalize()
5378 protected void finalize() throws Throwable
5380 // really make sure we have no buried refs left.
5385 this.seqRefIds = null;
5386 this.seqsToIds = null;
5390 private void warn(String msg)
5395 private void warn(String msg, Exception e)
5397 if (Cache.log != null)
5401 Cache.log.warn(msg, e);
5405 Cache.log.warn(msg);
5410 System.err.println("Warning: " + msg);
5413 e.printStackTrace();
5418 private void debug(String string)
5420 debug(string, null);
5423 private void debug(String msg, Exception e)
5425 if (Cache.log != null)
5429 Cache.log.debug(msg, e);
5433 Cache.log.debug(msg);
5438 System.err.println("Warning: " + msg);
5441 e.printStackTrace();
5447 * set the object to ID mapping tables used to write/recover objects and XML
5448 * ID strings for the jalview project. If external tables are provided then
5449 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5450 * object goes out of scope. - also populates the datasetIds hashtable with
5451 * alignment objects containing dataset sequences
5454 * Map from ID strings to jalview datamodel
5456 * Map from jalview datamodel to ID strings
5460 public void setObjectMappingTables(Hashtable vobj2jv,
5461 IdentityHashMap jv2vobj)
5463 this.jv2vobj = jv2vobj;
5464 this.vobj2jv = vobj2jv;
5465 Iterator ds = jv2vobj.keySet().iterator();
5467 while (ds.hasNext())
5469 Object jvobj = ds.next();
5470 id = jv2vobj.get(jvobj).toString();
5471 if (jvobj instanceof jalview.datamodel.Alignment)
5473 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5475 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5478 else if (jvobj instanceof jalview.datamodel.Sequence)
5480 // register sequence object so the XML parser can recover it.
5481 if (seqRefIds == null)
5483 seqRefIds = new HashMap<String, SequenceI>();
5485 if (seqsToIds == null)
5487 seqsToIds = new IdentityHashMap<SequenceI, String>();
5489 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5490 seqsToIds.put((SequenceI) jvobj, id);
5492 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5495 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5496 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5497 if (jvann.annotationId == null)
5499 jvann.annotationId = anid;
5501 if (!jvann.annotationId.equals(anid))
5503 // TODO verify that this is the correct behaviour
5504 this.warn("Overriding Annotation ID for " + anid
5505 + " from different id : " + jvann.annotationId);
5506 jvann.annotationId = anid;
5509 else if (jvobj instanceof String)
5511 if (jvids2vobj == null)
5513 jvids2vobj = new Hashtable();
5514 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5519 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5525 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5526 * objects created from the project archive. If string is null (default for
5527 * construction) then suffix will be set automatically.
5531 public void setUniqueSetSuffix(String string)
5533 uniqueSetSuffix = string;
5538 * uses skipList2 as the skipList for skipping views on sequence sets
5539 * associated with keys in the skipList
5543 public void setSkipList(Hashtable skipList2)
5545 skipList = skipList2;
5549 * Reads the jar entry of given name and returns its contents, or null if the
5550 * entry is not found.
5553 * @param jarEntryName
5556 protected String readJarEntry(jarInputStreamProvider jprovider,
5557 String jarEntryName)
5559 String result = null;
5560 BufferedReader in = null;
5565 * Reopen the jar input stream and traverse its entries to find a matching
5568 JarInputStream jin = jprovider.getJarInputStream();
5569 JarEntry entry = null;
5572 entry = jin.getNextJarEntry();
5573 } while (entry != null && !entry.getName().equals(jarEntryName));
5577 StringBuilder out = new StringBuilder(256);
5578 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5581 while ((data = in.readLine()) != null)
5585 result = out.toString();
5589 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5591 } catch (Exception ex)
5593 ex.printStackTrace();
5601 } catch (IOException e)
5612 * Returns an incrementing counter (0, 1, 2...)
5616 private synchronized int nextCounter()