2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 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.structures.JalviewStructureDisplayI;
24 import jalview.bin.Cache;
25 import jalview.datamodel.Alignment;
26 import jalview.datamodel.AlignmentAnnotation;
27 import jalview.datamodel.AlignmentI;
28 import jalview.datamodel.SequenceI;
29 import jalview.schemabinding.version2.AlcodMap;
30 import jalview.schemabinding.version2.Alcodon;
31 import jalview.schemabinding.version2.AlcodonFrame;
32 import jalview.schemabinding.version2.Annotation;
33 import jalview.schemabinding.version2.AnnotationColours;
34 import jalview.schemabinding.version2.AnnotationElement;
35 import jalview.schemabinding.version2.CalcIdParam;
36 import jalview.schemabinding.version2.DBRef;
37 import jalview.schemabinding.version2.Features;
38 import jalview.schemabinding.version2.Group;
39 import jalview.schemabinding.version2.HiddenColumns;
40 import jalview.schemabinding.version2.JGroup;
41 import jalview.schemabinding.version2.JSeq;
42 import jalview.schemabinding.version2.JalviewModel;
43 import jalview.schemabinding.version2.JalviewModelSequence;
44 import jalview.schemabinding.version2.MapListFrom;
45 import jalview.schemabinding.version2.MapListTo;
46 import jalview.schemabinding.version2.Mapping;
47 import jalview.schemabinding.version2.MappingChoice;
48 import jalview.schemabinding.version2.OtherData;
49 import jalview.schemabinding.version2.PdbentryItem;
50 import jalview.schemabinding.version2.Pdbids;
51 import jalview.schemabinding.version2.Property;
52 import jalview.schemabinding.version2.Sequence;
53 import jalview.schemabinding.version2.SequenceSet;
54 import jalview.schemabinding.version2.SequenceSetProperties;
55 import jalview.schemabinding.version2.Setting;
56 import jalview.schemabinding.version2.StructureState;
57 import jalview.schemabinding.version2.ThresholdLine;
58 import jalview.schemabinding.version2.Tree;
59 import jalview.schemabinding.version2.UserColours;
60 import jalview.schemabinding.version2.Viewport;
61 import jalview.schemes.AnnotationColourGradient;
62 import jalview.schemes.ColourSchemeI;
63 import jalview.schemes.ColourSchemeProperty;
64 import jalview.schemes.GraduatedColor;
65 import jalview.schemes.ResidueColourScheme;
66 import jalview.schemes.ResidueProperties;
67 import jalview.structure.StructureSelectionManager;
68 import jalview.util.MessageManager;
69 import jalview.util.Platform;
70 import jalview.util.jarInputStreamProvider;
71 import jalview.viewmodel.AlignmentViewport;
72 import jalview.ws.jws2.Jws2Discoverer;
73 import jalview.ws.jws2.dm.AAConSettings;
74 import jalview.ws.jws2.jabaws2.Jws2Instance;
75 import jalview.ws.params.ArgumentI;
76 import jalview.ws.params.AutoCalcSetting;
77 import jalview.ws.params.WsParamSetI;
79 import java.awt.Rectangle;
80 import java.io.BufferedReader;
81 import java.io.DataInputStream;
82 import java.io.DataOutputStream;
84 import java.io.FileInputStream;
85 import java.io.FileOutputStream;
86 import java.io.IOException;
87 import java.io.InputStreamReader;
88 import java.io.OutputStreamWriter;
89 import java.io.PrintWriter;
90 import java.lang.reflect.InvocationTargetException;
91 import java.net.MalformedURLException;
93 import java.util.ArrayList;
94 import java.util.Enumeration;
95 import java.util.HashSet;
96 import java.util.Hashtable;
97 import java.util.IdentityHashMap;
98 import java.util.Iterator;
99 import java.util.List;
100 import java.util.Map.Entry;
101 import java.util.Set;
102 import java.util.StringTokenizer;
103 import java.util.Vector;
104 import java.util.jar.JarEntry;
105 import java.util.jar.JarInputStream;
106 import java.util.jar.JarOutputStream;
108 import javax.swing.JInternalFrame;
109 import javax.swing.JOptionPane;
110 import javax.swing.SwingUtilities;
112 import org.exolab.castor.xml.Unmarshaller;
115 * Write out the current jalview desktop state as a Jalview XML stream.
117 * Note: the vamsas objects referred to here are primitive versions of the
118 * VAMSAS project schema elements - they are not the same and most likely never
122 * @version $Revision: 1.134 $
124 public class Jalview2XML
127 * create/return unique hash string for sq
130 * @return new or existing unique string for sq
132 String seqHash(SequenceI sq)
134 if (seqsToIds == null)
138 if (seqsToIds.containsKey(sq))
140 return (String) seqsToIds.get(sq);
144 // create sequential key
145 String key = "sq" + (seqsToIds.size() + 1);
146 key = makeHashCode(sq, key); // check we don't have an external reference
148 seqsToIds.put(sq, key);
157 if (seqRefIds != null)
161 if (seqsToIds != null)
171 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
172 // seqRefIds = new Hashtable();
173 // seqsToIds = new IdentityHashMap();
179 if (seqsToIds == null)
181 seqsToIds = new IdentityHashMap();
183 if (seqRefIds == null)
185 seqRefIds = new Hashtable();
190 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
191 * of sequence objects are created.
193 java.util.IdentityHashMap seqsToIds = null;
196 * jalview XML Sequence ID to jalview sequence object reference (both dataset
197 * and alignment sequences. Populated as XML reps of sequence objects are
200 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
202 Vector frefedSequence = null;
204 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
210 public Jalview2XML(boolean raiseGUI)
212 this.raiseGUI = raiseGUI;
215 public void resolveFrefedSequences()
217 if (frefedSequence.size() > 0)
219 int r = 0, rSize = frefedSequence.size();
222 Object[] ref = (Object[]) frefedSequence.elementAt(r);
225 String sref = (String) ref[0];
226 if (seqRefIds.containsKey(sref))
228 if (ref[1] instanceof jalview.datamodel.Mapping)
230 SequenceI seq = (SequenceI) seqRefIds.get(sref);
231 while (seq.getDatasetSequence() != null)
233 seq = seq.getDatasetSequence();
235 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
239 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
241 SequenceI seq = (SequenceI) seqRefIds.get(sref);
242 while (seq.getDatasetSequence() != null)
244 seq = seq.getDatasetSequence();
247 && ref[2] instanceof jalview.datamodel.Mapping)
249 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
250 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
251 seq, mp.getTo(), mp.getMap());
256 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
257 + ref[2].getClass() + " type objects.");
263 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
264 + ref[1].getClass() + " type objects.");
267 frefedSequence.remove(r);
273 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
275 + " with objecttype "
276 + ref[1].getClass());
283 frefedSequence.remove(r);
291 * This maintains a list of viewports, the key being the seqSetId. Important
292 * to set historyItem and redoList for multiple views
294 Hashtable viewportsAdded;
296 Hashtable annotationIds = new Hashtable();
298 String uniqueSetSuffix = "";
301 * List of pdbfiles added to Jar
303 Vector pdbfiles = null;
305 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
306 public void SaveState(File statefile)
310 FileOutputStream fos = new FileOutputStream(statefile);
311 JarOutputStream jout = new JarOutputStream(fos);
314 } catch (Exception e)
316 // TODO: inform user of the problem - they need to know if their data was
318 if (errorMessage == null)
320 errorMessage = "Couldn't write Jalview Archive to output file '"
321 + statefile + "' - See console error log for details";
325 errorMessage += "(output file was '" + statefile + "')";
333 * Writes a jalview project archive to the given Jar output stream.
337 public void SaveState(JarOutputStream jout)
339 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
346 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
351 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
352 // //////////////////////////////////////////////////
353 // NOTE ALSO new PrintWriter must be used for each new JarEntry
354 PrintWriter out = null;
356 Vector shortNames = new Vector();
359 for (int i = frames.length - 1; i > -1; i--)
361 if (frames[i] instanceof AlignFrame)
363 AlignFrame af = (AlignFrame) frames[i];
366 && skipList.containsKey(af.getViewport()
367 .getSequenceSetId()))
372 String shortName = af.getTitle();
374 if (shortName.indexOf(File.separatorChar) > -1)
376 shortName = shortName.substring(shortName
377 .lastIndexOf(File.separatorChar) + 1);
382 while (shortNames.contains(shortName))
384 if (shortName.endsWith("_" + (count - 1)))
386 shortName = shortName
387 .substring(0, shortName.lastIndexOf("_"));
390 shortName = shortName.concat("_" + count);
394 shortNames.addElement(shortName);
396 if (!shortName.endsWith(".xml"))
398 shortName = shortName + ".xml";
401 int ap, apSize = af.alignPanels.size();
403 for (ap = 0; ap < apSize; ap++)
405 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
407 String fileName = apSize == 1 ? shortName : ap + shortName;
408 if (!fileName.endsWith(".xml"))
410 fileName = fileName + ".xml";
413 SaveState(apanel, fileName, jout);
415 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
417 if (!dsses.containsKey(dssid))
419 dsses.put(dssid, af);
426 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
432 } catch (Exception foo)
437 } catch (Exception ex)
439 // TODO: inform user of the problem - they need to know if their data was
441 if (errorMessage == null)
443 errorMessage = "Couldn't write Jalview Archive - see error output for details";
445 ex.printStackTrace();
449 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
450 public boolean SaveAlignment(AlignFrame af, String jarFile,
455 int ap, apSize = af.alignPanels.size();
456 FileOutputStream fos = new FileOutputStream(jarFile);
457 JarOutputStream jout = new JarOutputStream(fos);
458 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
459 for (ap = 0; ap < apSize; ap++)
461 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
463 String jfileName = apSize == 1 ? fileName : fileName + ap;
464 if (!jfileName.endsWith(".xml"))
466 jfileName = jfileName + ".xml";
468 SaveState(apanel, jfileName, jout);
469 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
471 if (!dsses.containsKey(dssid))
473 dsses.put(dssid, af);
476 writeDatasetFor(dsses, fileName, jout);
480 } catch (Exception foo)
486 } catch (Exception ex)
488 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
489 ex.printStackTrace();
494 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
495 String fileName, JarOutputStream jout)
498 for (String dssids : dsses.keySet())
500 AlignFrame _af = dsses.get(dssids);
501 String jfileName = fileName + " Dataset for " + _af.getTitle();
502 if (!jfileName.endsWith(".xml"))
504 jfileName = jfileName + ".xml";
506 SaveState(_af.alignPanel, jfileName, true, jout);
511 * create a JalviewModel from an algnment view and marshall it to a
515 * panel to create jalview model for
517 * name of alignment panel written to output stream
523 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
524 JarOutputStream jout)
526 return SaveState(ap, fileName, false, jout);
530 * create a JalviewModel from an algnment view and marshall it to a
534 * panel to create jalview model for
536 * name of alignment panel written to output stream
538 * when true, only write the dataset for the alignment, not the data
539 * associated with the view.
545 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
546 boolean storeDS, JarOutputStream jout)
549 Vector jmolViewIds = new Vector(); //
550 Vector userColours = new Vector();
552 AlignViewport av = ap.av;
554 JalviewModel object = new JalviewModel();
555 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
557 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
558 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
559 "Development Build"));
561 jalview.datamodel.AlignmentI jal = av.getAlignment();
563 if (av.hasHiddenRows())
565 jal = jal.getHiddenSequences().getFullAlignment();
568 SequenceSet vamsasSet = new SequenceSet();
570 JalviewModelSequence jms = new JalviewModelSequence();
572 vamsasSet.setGapChar(jal.getGapCharacter() + "");
574 if (jal.getDataset() != null)
576 // dataset id is the dataset's hashcode
577 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
580 // switch jal and the dataset
581 jal = jal.getDataset();
584 if (jal.getProperties() != null)
586 Enumeration en = jal.getProperties().keys();
587 while (en.hasMoreElements())
589 String key = en.nextElement().toString();
590 SequenceSetProperties ssp = new SequenceSetProperties();
592 ssp.setValue(jal.getProperties().get(key).toString());
593 vamsasSet.addSequenceSetProperties(ssp);
598 Set<String> calcIdSet = new HashSet<String>();
602 jalview.datamodel.SequenceI jds, jdatasq;
603 for (int i = 0; i < jal.getHeight(); i++)
605 jds = jal.getSequenceAt(i);
606 jdatasq = jds.getDatasetSequence() == null ? jds : jds
607 .getDatasetSequence();
610 if (seqRefIds.get(id) != null)
612 // This happens for two reasons: 1. multiple views are being serialised.
613 // 2. the hashCode has collided with another sequence's code. This DOES
614 // HAPPEN! (PF00072.15.stk does this)
615 // JBPNote: Uncomment to debug writing out of files that do not read
616 // back in due to ArrayOutOfBoundExceptions.
617 // System.err.println("vamsasSeq backref: "+id+"");
618 // System.err.println(jds.getName()+"
619 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
620 // System.err.println("Hashcode: "+seqHash(jds));
621 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
622 // System.err.println(rsq.getName()+"
623 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
624 // System.err.println("Hashcode: "+seqHash(rsq));
628 vamsasSeq = createVamsasSequence(id, jds);
629 vamsasSet.addSequence(vamsasSeq);
630 seqRefIds.put(id, jds);
634 jseq.setStart(jds.getStart());
635 jseq.setEnd(jds.getEnd());
636 jseq.setColour(av.getSequenceColour(jds).getRGB());
638 jseq.setId(id); // jseq id should be a string not a number
641 // Store any sequences this sequence represents
642 if (av.hasHiddenRows())
644 jseq.setHidden(av.getAlignment().getHiddenSequences()
647 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
649 jalview.datamodel.SequenceI[] reps = av
650 .getRepresentedSequences(jal.getSequenceAt(i))
651 .getSequencesInOrder(jal);
653 for (int h = 0; h < reps.length; h++)
655 if (reps[h] != jal.getSequenceAt(i))
657 jseq.addHiddenSequences(jal.findIndex(reps[h]));
664 if (jdatasq.getSequenceFeatures() != null)
666 jalview.datamodel.SequenceFeature[] sf = jdatasq
667 .getSequenceFeatures();
669 while (index < sf.length)
671 Features features = new Features();
673 features.setBegin(sf[index].getBegin());
674 features.setEnd(sf[index].getEnd());
675 features.setDescription(sf[index].getDescription());
676 features.setType(sf[index].getType());
677 features.setFeatureGroup(sf[index].getFeatureGroup());
678 features.setScore(sf[index].getScore());
679 if (sf[index].links != null)
681 for (int l = 0; l < sf[index].links.size(); l++)
683 OtherData keyValue = new OtherData();
684 keyValue.setKey("LINK_" + l);
685 keyValue.setValue(sf[index].links.elementAt(l).toString());
686 features.addOtherData(keyValue);
689 if (sf[index].otherDetails != null)
692 Enumeration keys = sf[index].otherDetails.keys();
693 while (keys.hasMoreElements())
695 key = keys.nextElement().toString();
696 OtherData keyValue = new OtherData();
697 keyValue.setKey(key);
698 keyValue.setValue(sf[index].otherDetails.get(key).toString());
699 features.addOtherData(keyValue);
703 jseq.addFeatures(features);
708 if (jdatasq.getPDBId() != null)
710 Enumeration en = jdatasq.getPDBId().elements();
711 while (en.hasMoreElements())
713 Pdbids pdb = new Pdbids();
714 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
717 pdb.setId(entry.getId());
718 pdb.setType(entry.getType());
720 // store any JMol views associated with this seqeunce
721 // this section copes with duplicate entries in the project, so a
722 // dataset only view *should* be coped with sensibly
724 // This must have been loaded, is it still visible?
725 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
726 String matchedFile = null;
727 for (int f = frames.length - 1; f > -1; f--)
729 if (frames[f] instanceof AppJmol)
731 jmol = (AppJmol) frames[f];
732 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
734 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
735 && !(entry.getId().length() > 4 && entry
739 jmol.jmb.pdbentry[peid].getId()
744 if (matchedFile == null)
746 matchedFile = jmol.jmb.pdbentry[peid].getFile();
748 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
752 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
753 + jmol.jmb.pdbentry[peid].getFile());
757 // can get at it if the ID
758 // match is ambiguous (e.g.
760 String statestring = jmol.jmb.viewer.getStateInfo();
762 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
764 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
765 if (jds == jmol.jmb.sequence[peid][smap])
767 StructureState state = new StructureState();
768 state.setVisible(true);
769 state.setXpos(jmol.getX());
770 state.setYpos(jmol.getY());
771 state.setWidth(jmol.getWidth());
772 state.setHeight(jmol.getHeight());
773 state.setViewId(jmol.getViewId());
774 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
775 state.setColourwithAlignPanel(jmol
776 .isUsedforcolourby(ap));
777 state.setColourByJmol(jmol.isColouredByJmol());
778 if (!jmolViewIds.contains(state.getViewId()))
780 // Make sure we only store a Jmol state once in each XML
782 jmolViewIds.addElement(state.getViewId());
783 state.setContent(statestring.replaceAll("\n", ""));
787 state.setContent("# duplicate state");
789 pdb.addStructureState(state);
797 if (matchedFile != null || entry.getFile() != null)
799 if (entry.getFile() != null)
802 matchedFile = entry.getFile();
804 pdb.setFile(matchedFile); // entry.getFile());
805 if (pdbfiles == null)
807 pdbfiles = new Vector();
810 if (!pdbfiles.contains(entry.getId()))
812 pdbfiles.addElement(entry.getId());
815 File file = new File(matchedFile);
816 if (file.exists() && jout != null)
818 byte[] data = new byte[(int) file.length()];
819 jout.putNextEntry(new JarEntry(entry.getId()));
820 DataInputStream dis = new DataInputStream(
821 new FileInputStream(file));
824 DataOutputStream dout = new DataOutputStream(jout);
825 dout.write(data, 0, data.length);
829 } catch (Exception ex)
831 ex.printStackTrace();
837 if (entry.getProperty() != null)
839 PdbentryItem item = new PdbentryItem();
840 Hashtable properties = entry.getProperty();
841 Enumeration en2 = properties.keys();
842 while (en2.hasMoreElements())
844 Property prop = new Property();
845 String key = en2.nextElement().toString();
847 prop.setValue(properties.get(key).toString());
848 item.addProperty(prop);
850 pdb.addPdbentryItem(item);
860 if (!storeDS && av.hasHiddenRows())
862 jal = av.getAlignment();
865 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
867 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
868 for (int i = 0; i < jac.length; i++)
870 AlcodonFrame alc = new AlcodonFrame();
871 vamsasSet.addAlcodonFrame(alc);
872 for (int p = 0; p < jac[i].aaWidth; p++)
874 Alcodon cmap = new Alcodon();
875 if (jac[i].codons[p] != null)
877 // Null codons indicate a gapped column in the translated peptide
879 cmap.setPos1(jac[i].codons[p][0]);
880 cmap.setPos2(jac[i].codons[p][1]);
881 cmap.setPos3(jac[i].codons[p][2]);
883 alc.addAlcodon(cmap);
885 if (jac[i].getProtMappings() != null
886 && jac[i].getProtMappings().length > 0)
888 SequenceI[] dnas = jac[i].getdnaSeqs();
889 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
890 for (int m = 0; m < pmaps.length; m++)
892 AlcodMap alcmap = new AlcodMap();
893 alcmap.setDnasq(seqHash(dnas[m]));
894 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
896 alc.addAlcodMap(alcmap);
903 // /////////////////////////////////
904 if (!storeDS && av.currentTree != null)
906 // FIND ANY ASSOCIATED TREES
907 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
908 if (Desktop.desktop != null)
910 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
912 for (int t = 0; t < frames.length; t++)
914 if (frames[t] instanceof TreePanel)
916 TreePanel tp = (TreePanel) frames[t];
918 if (tp.treeCanvas.av.getAlignment() == jal)
920 Tree tree = new Tree();
921 tree.setTitle(tp.getTitle());
922 tree.setCurrentTree((av.currentTree == tp.getTree()));
923 tree.setNewick(tp.getTree().toString());
924 tree.setThreshold(tp.treeCanvas.threshold);
926 tree.setFitToWindow(tp.fitToWindow.getState());
927 tree.setFontName(tp.getTreeFont().getName());
928 tree.setFontSize(tp.getTreeFont().getSize());
929 tree.setFontStyle(tp.getTreeFont().getStyle());
930 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
932 tree.setShowBootstrap(tp.bootstrapMenu.getState());
933 tree.setShowDistances(tp.distanceMenu.getState());
935 tree.setHeight(tp.getHeight());
936 tree.setWidth(tp.getWidth());
937 tree.setXpos(tp.getX());
938 tree.setYpos(tp.getY());
939 tree.setId(makeHashCode(tp, null));
948 * store forward refs from an annotationRow to any groups
950 IdentityHashMap groupRefs = new IdentityHashMap();
953 for (SequenceI sq : jal.getSequences())
955 // Store annotation on dataset sequences only
956 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
957 if (aa != null && aa.length > 0)
959 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
966 if (jal.getAlignmentAnnotation() != null)
968 // Store the annotation shown on the alignment.
969 jalview.datamodel.AlignmentAnnotation[] aa = jal
970 .getAlignmentAnnotation();
971 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
976 if (jal.getGroups() != null)
978 JGroup[] groups = new JGroup[jal.getGroups().size()];
980 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
982 groups[++i] = new JGroup();
984 groups[i].setStart(sg.getStartRes());
985 groups[i].setEnd(sg.getEndRes());
986 groups[i].setName(sg.getName());
987 if (groupRefs.containsKey(sg))
989 // group has references so set it's ID field
990 groups[i].setId(groupRefs.get(sg).toString());
994 if (sg.cs.conservationApplied())
996 groups[i].setConsThreshold(sg.cs.getConservationInc());
998 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1000 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
1006 .setColour(ColourSchemeProperty.getColourName(sg.cs));
1009 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1011 groups[i].setColour("AnnotationColourGradient");
1012 groups[i].setAnnotationColours(constructAnnotationColours(
1013 (jalview.schemes.AnnotationColourGradient) sg.cs,
1016 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1019 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
1023 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1026 groups[i].setPidThreshold(sg.cs.getThreshold());
1029 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1030 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1031 groups[i].setDisplayText(sg.getDisplayText());
1032 groups[i].setColourText(sg.getColourText());
1033 groups[i].setTextCol1(sg.textColour.getRGB());
1034 groups[i].setTextCol2(sg.textColour2.getRGB());
1035 groups[i].setTextColThreshold(sg.thresholdTextColour);
1036 groups[i].setShowUnconserved(sg.getShowNonconserved());
1037 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1038 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1039 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1040 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1041 for (int s = 0; s < sg.getSize(); s++)
1043 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1045 groups[i].addSeq(seqHash(seq));
1049 jms.setJGroup(groups);
1053 // /////////SAVE VIEWPORT
1054 Viewport view = new Viewport();
1055 view.setTitle(ap.alignFrame.getTitle());
1056 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1057 av.getSequenceSetId()));
1058 view.setId(av.getViewId());
1059 view.setViewName(av.viewName);
1060 view.setGatheredViews(av.gatherViewsHere);
1062 if (ap.av.explodedPosition != null)
1064 view.setXpos(av.explodedPosition.x);
1065 view.setYpos(av.explodedPosition.y);
1066 view.setWidth(av.explodedPosition.width);
1067 view.setHeight(av.explodedPosition.height);
1071 view.setXpos(ap.alignFrame.getBounds().x);
1072 view.setYpos(ap.alignFrame.getBounds().y);
1073 view.setWidth(ap.alignFrame.getBounds().width);
1074 view.setHeight(ap.alignFrame.getBounds().height);
1077 view.setStartRes(av.startRes);
1078 view.setStartSeq(av.startSeq);
1080 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1082 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1085 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1087 AnnotationColours ac = constructAnnotationColours(
1088 (jalview.schemes.AnnotationColourGradient) av
1089 .getGlobalColourScheme(),
1092 view.setAnnotationColours(ac);
1093 view.setBgColour("AnnotationColourGradient");
1097 view.setBgColour(ColourSchemeProperty.getColourName(av
1098 .getGlobalColourScheme()));
1101 ColourSchemeI cs = av.getGlobalColourScheme();
1105 if (cs.conservationApplied())
1107 view.setConsThreshold(cs.getConservationInc());
1108 if (cs instanceof jalview.schemes.UserColourScheme)
1110 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1114 if (cs instanceof ResidueColourScheme)
1116 view.setPidThreshold(cs.getThreshold());
1120 view.setConservationSelected(av.getConservationSelected());
1121 view.setPidSelected(av.getAbovePIDThreshold());
1122 view.setFontName(av.font.getName());
1123 view.setFontSize(av.font.getSize());
1124 view.setFontStyle(av.font.getStyle());
1125 view.setRenderGaps(av.renderGaps);
1126 view.setShowAnnotation(av.getShowAnnotation());
1127 view.setShowBoxes(av.getShowBoxes());
1128 view.setShowColourText(av.getColourText());
1129 view.setShowFullId(av.getShowJVSuffix());
1130 view.setRightAlignIds(av.isRightAlignIds());
1131 view.setShowSequenceFeatures(av.showSequenceFeatures);
1132 view.setShowText(av.getShowText());
1133 view.setShowUnconserved(av.getShowUnconserved());
1134 view.setWrapAlignment(av.getWrapAlignment());
1135 view.setTextCol1(av.textColour.getRGB());
1136 view.setTextCol2(av.textColour2.getRGB());
1137 view.setTextColThreshold(av.thresholdTextColour);
1138 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1139 view.setShowSequenceLogo(av.isShowSequenceLogo());
1140 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1141 view.setShowGroupConsensus(av.isShowGroupConsensus());
1142 view.setShowGroupConservation(av.isShowGroupConservation());
1143 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1144 view.setShowDbRefTooltip(av.isShowDbRefs());
1145 view.setFollowHighlight(av.followHighlight);
1146 view.setFollowSelection(av.followSelection);
1147 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1148 if (av.getFeaturesDisplayed() != null)
1150 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1152 String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder;
1154 Vector settingsAdded = new Vector();
1155 Object gstyle = null;
1156 GraduatedColor gcol = null;
1157 if (renderOrder != null)
1159 for (int ro = 0; ro < renderOrder.length; ro++)
1161 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1162 .getFeatureStyle(renderOrder[ro]);
1163 Setting setting = new Setting();
1164 setting.setType(renderOrder[ro]);
1165 if (gstyle instanceof GraduatedColor)
1167 gcol = (GraduatedColor) gstyle;
1168 setting.setColour(gcol.getMaxColor().getRGB());
1169 setting.setMincolour(gcol.getMinColor().getRGB());
1170 setting.setMin(gcol.getMin());
1171 setting.setMax(gcol.getMax());
1172 setting.setColourByLabel(gcol.isColourByLabel());
1173 setting.setAutoScale(gcol.isAutoScale());
1174 setting.setThreshold(gcol.getThresh());
1175 setting.setThreshstate(gcol.getThreshType());
1179 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1180 .getColour(renderOrder[ro]).getRGB());
1183 setting.setDisplay(av.getFeaturesDisplayed()
1184 .containsKey(renderOrder[ro]));
1185 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1186 .getOrder(renderOrder[ro]);
1189 setting.setOrder(rorder);
1191 fs.addSetting(setting);
1192 settingsAdded.addElement(renderOrder[ro]);
1196 // Make sure we save none displayed feature settings
1197 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureColours
1198 .keySet().iterator();
1199 while (en.hasNext())
1201 String key = en.next().toString();
1202 if (settingsAdded.contains(key))
1207 Setting setting = new Setting();
1208 setting.setType(key);
1209 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1210 .getColour(key).getRGB());
1212 setting.setDisplay(false);
1213 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1217 setting.setOrder(rorder);
1219 fs.addSetting(setting);
1220 settingsAdded.addElement(key);
1222 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups
1223 .keySet().iterator();
1224 Vector groupsAdded = new Vector();
1225 while (en.hasNext())
1227 String grp = en.next().toString();
1228 if (groupsAdded.contains(grp))
1232 Group g = new Group();
1234 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1235 .getFeatureRenderer().featureGroups.get(grp))
1238 groupsAdded.addElement(grp);
1240 jms.setFeatureSettings(fs);
1244 if (av.hasHiddenColumns())
1246 if (av.getColumnSelection() == null
1247 || av.getColumnSelection().getHiddenColumns() == null)
1249 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1253 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1256 int[] region = (int[]) av.getColumnSelection()
1257 .getHiddenColumns().elementAt(c);
1258 HiddenColumns hc = new HiddenColumns();
1259 hc.setStart(region[0]);
1260 hc.setEnd(region[1]);
1261 view.addHiddenColumns(hc);
1265 if (calcIdSet.size() > 0)
1267 for (String calcId : calcIdSet)
1269 if (calcId.trim().length() > 0)
1271 CalcIdParam cidp = createCalcIdParam(calcId, av);
1272 // Some calcIds have no parameters.
1275 view.addCalcIdParam(cidp);
1281 jms.addViewport(view);
1283 object.setJalviewModelSequence(jms);
1284 object.getVamsasModel().addSequenceSet(vamsasSet);
1286 if (jout != null && fileName != null)
1288 // We may not want to write the object to disk,
1289 // eg we can copy the alignViewport to a new view object
1290 // using save and then load
1293 JarEntry entry = new JarEntry(fileName);
1294 jout.putNextEntry(entry);
1295 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1297 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1299 marshaller.marshal(object);
1302 } catch (Exception ex)
1304 // TODO: raise error in GUI if marshalling failed.
1305 ex.printStackTrace();
1311 private AnnotationColours constructAnnotationColours(
1312 AnnotationColourGradient acg, Vector userColours,
1313 JalviewModelSequence jms)
1315 AnnotationColours ac = new AnnotationColours();
1316 ac.setAboveThreshold(acg.getAboveThreshold());
1317 ac.setThreshold(acg.getAnnotationThreshold());
1318 ac.setAnnotation(acg.getAnnotation());
1319 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1321 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1326 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1330 ac.setMaxColour(acg.getMaxColour().getRGB());
1331 ac.setMinColour(acg.getMinColour().getRGB());
1332 ac.setPerSequence(acg.isSeqAssociated());
1333 ac.setPredefinedColours(acg.isPredefinedColours());
1337 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1338 IdentityHashMap groupRefs, AlignmentViewport av,
1339 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1342 for (int i = 0; i < aa.length; i++)
1344 Annotation an = new Annotation();
1346 if (aa[i].annotationId != null)
1348 annotationIds.put(aa[i].annotationId, aa[i]);
1351 an.setId(aa[i].annotationId);
1353 an.setVisible(aa[i].visible);
1355 an.setDescription(aa[i].description);
1357 if (aa[i].sequenceRef != null)
1359 // TODO later annotation sequenceRef should be the XML ID of the
1360 // sequence rather than its display name
1361 an.setSequenceRef(aa[i].sequenceRef.getName());
1363 if (aa[i].groupRef != null)
1365 Object groupIdr = groupRefs.get(aa[i].groupRef);
1366 if (groupIdr == null)
1368 // make a locally unique String
1369 groupRefs.put(aa[i].groupRef,
1370 groupIdr = ("" + System.currentTimeMillis()
1371 + aa[i].groupRef.getName() + groupRefs.size()));
1373 an.setGroupRef(groupIdr.toString());
1376 // store all visualization attributes for annotation
1377 an.setGraphHeight(aa[i].graphHeight);
1378 an.setCentreColLabels(aa[i].centreColLabels);
1379 an.setScaleColLabels(aa[i].scaleColLabel);
1380 an.setShowAllColLabels(aa[i].showAllColLabels);
1381 an.setBelowAlignment(aa[i].belowAlignment);
1383 if (aa[i].graph > 0)
1386 an.setGraphType(aa[i].graph);
1387 an.setGraphGroup(aa[i].graphGroup);
1388 if (aa[i].getThreshold() != null)
1390 ThresholdLine line = new ThresholdLine();
1391 line.setLabel(aa[i].getThreshold().label);
1392 line.setValue(aa[i].getThreshold().value);
1393 line.setColour(aa[i].getThreshold().colour.getRGB());
1394 an.setThresholdLine(line);
1402 an.setLabel(aa[i].label);
1404 if (aa[i] == av.getAlignmentQualityAnnot()
1405 || aa[i] == av.getAlignmentConservationAnnotation()
1406 || aa[i] == av.getAlignmentConsensusAnnotation()
1407 || aa[i].autoCalculated)
1409 // new way of indicating autocalculated annotation -
1410 an.setAutoCalculated(aa[i].autoCalculated);
1412 if (aa[i].hasScore())
1414 an.setScore(aa[i].getScore());
1417 if (aa[i].getCalcId() != null)
1419 calcIdSet.add(aa[i].getCalcId());
1420 an.setCalcId(aa[i].getCalcId());
1422 if (aa[i].hasProperties())
1424 for (String pr : aa[i].getProperties())
1426 Property prop = new Property();
1428 prop.setValue(aa[i].getProperty(pr));
1429 an.addProperty(prop);
1432 AnnotationElement ae;
1433 if (aa[i].annotations != null)
1435 an.setScoreOnly(false);
1436 for (int a = 0; a < aa[i].annotations.length; a++)
1438 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1443 ae = new AnnotationElement();
1444 if (aa[i].annotations[a].description != null)
1446 ae.setDescription(aa[i].annotations[a].description);
1448 if (aa[i].annotations[a].displayCharacter != null)
1450 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1453 if (!Float.isNaN(aa[i].annotations[a].value))
1455 ae.setValue(aa[i].annotations[a].value);
1459 if (aa[i].annotations[a].secondaryStructure > ' ')
1461 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1465 if (aa[i].annotations[a].colour != null
1466 && aa[i].annotations[a].colour != java.awt.Color.black)
1468 ae.setColour(aa[i].annotations[a].colour.getRGB());
1471 an.addAnnotationElement(ae);
1472 if (aa[i].autoCalculated)
1474 // only write one non-null entry into the annotation row -
1475 // sufficient to get the visualization attributes necessary to
1483 an.setScoreOnly(true);
1485 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1487 // skip autocalculated annotation - these are only provided for
1489 vamsasSet.addAnnotation(an);
1495 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1497 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1498 if (settings != null)
1500 CalcIdParam vCalcIdParam = new CalcIdParam();
1501 vCalcIdParam.setCalcId(calcId);
1502 vCalcIdParam.addServiceURL(settings.getServiceURI());
1503 // generic URI allowing a third party to resolve another instance of the
1504 // service used for this calculation
1505 for (String urls : settings.getServiceURLs())
1507 vCalcIdParam.addServiceURL(urls);
1509 vCalcIdParam.setVersion("1.0");
1510 if (settings.getPreset() != null)
1512 WsParamSetI setting = settings.getPreset();
1513 vCalcIdParam.setName(setting.getName());
1514 vCalcIdParam.setDescription(setting.getDescription());
1518 vCalcIdParam.setName("");
1519 vCalcIdParam.setDescription("Last used parameters");
1521 // need to be able to recover 1) settings 2) user-defined presets or
1522 // recreate settings from preset 3) predefined settings provided by
1523 // service - or settings that can be transferred (or discarded)
1524 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1526 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1527 // todo - decide if updateImmediately is needed for any projects.
1529 return vCalcIdParam;
1534 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1537 if (calcIdParam.getVersion().equals("1.0"))
1539 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1540 .getPreferredServiceFor(calcIdParam.getServiceURL());
1541 if (service != null)
1543 WsParamSetI parmSet = null;
1546 parmSet = service.getParamStore().parseServiceParameterFile(
1547 calcIdParam.getName(), calcIdParam.getDescription(),
1548 calcIdParam.getServiceURL(),
1549 calcIdParam.getParameters().replace("|\\n|", "\n"));
1550 } catch (IOException x)
1552 warn("Couldn't parse parameter data for "
1553 + calcIdParam.getCalcId(), x);
1556 List<ArgumentI> argList = null;
1557 if (calcIdParam.getName().length() > 0)
1559 parmSet = service.getParamStore()
1560 .getPreset(calcIdParam.getName());
1561 if (parmSet != null)
1563 // TODO : check we have a good match with settings in AACon -
1564 // otherwise we'll need to create a new preset
1569 argList = parmSet.getArguments();
1572 AAConSettings settings = new AAConSettings(
1573 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1574 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1575 calcIdParam.isNeedsUpdate());
1580 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1584 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1588 * External mapping between jalview objects and objects yielding a valid and
1589 * unique object ID string. This is null for normal Jalview project IO, but
1590 * non-null when a jalview project is being read or written as part of a
1593 IdentityHashMap jv2vobj = null;
1596 * Construct a unique ID for jvobj using either existing bindings or if none
1597 * exist, the result of the hashcode call for the object.
1600 * jalview data object
1601 * @return unique ID for referring to jvobj
1603 private String makeHashCode(Object jvobj, String altCode)
1605 if (jv2vobj != null)
1607 Object id = jv2vobj.get(jvobj);
1610 return id.toString();
1612 // check string ID mappings
1613 if (jvids2vobj != null && jvobj instanceof String)
1615 id = jvids2vobj.get(jvobj);
1619 return id.toString();
1621 // give up and warn that something has gone wrong
1622 warn("Cannot find ID for object in external mapping : " + jvobj);
1628 * return local jalview object mapped to ID, if it exists
1632 * @return null or object bound to idcode
1634 private Object retrieveExistingObj(String idcode)
1636 if (idcode != null && vobj2jv != null)
1638 return vobj2jv.get(idcode);
1644 * binding from ID strings from external mapping table to jalview data model
1647 private Hashtable vobj2jv;
1649 private Sequence createVamsasSequence(String id, SequenceI jds)
1651 return createVamsasSequence(true, id, jds, null);
1654 private Sequence createVamsasSequence(boolean recurse, String id,
1655 SequenceI jds, SequenceI parentseq)
1657 Sequence vamsasSeq = new Sequence();
1658 vamsasSeq.setId(id);
1659 vamsasSeq.setName(jds.getName());
1660 vamsasSeq.setSequence(jds.getSequenceAsString());
1661 vamsasSeq.setDescription(jds.getDescription());
1662 jalview.datamodel.DBRefEntry[] dbrefs = null;
1663 if (jds.getDatasetSequence() != null)
1665 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1666 if (jds.getDatasetSequence().getDBRef() != null)
1668 dbrefs = jds.getDatasetSequence().getDBRef();
1673 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1674 // dataset sequences only
1675 dbrefs = jds.getDBRef();
1679 for (int d = 0; d < dbrefs.length; d++)
1681 DBRef dbref = new DBRef();
1682 dbref.setSource(dbrefs[d].getSource());
1683 dbref.setVersion(dbrefs[d].getVersion());
1684 dbref.setAccessionId(dbrefs[d].getAccessionId());
1685 if (dbrefs[d].hasMap())
1687 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1689 dbref.setMapping(mp);
1691 vamsasSeq.addDBRef(dbref);
1697 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1698 SequenceI parentseq, SequenceI jds, boolean recurse)
1701 if (jmp.getMap() != null)
1705 jalview.util.MapList mlst = jmp.getMap();
1706 int r[] = mlst.getFromRanges();
1707 for (int s = 0; s < r.length; s += 2)
1709 MapListFrom mfrom = new MapListFrom();
1710 mfrom.setStart(r[s]);
1711 mfrom.setEnd(r[s + 1]);
1712 mp.addMapListFrom(mfrom);
1714 r = mlst.getToRanges();
1715 for (int s = 0; s < r.length; s += 2)
1717 MapListTo mto = new MapListTo();
1719 mto.setEnd(r[s + 1]);
1720 mp.addMapListTo(mto);
1722 mp.setMapFromUnit(mlst.getFromRatio());
1723 mp.setMapToUnit(mlst.getToRatio());
1724 if (jmp.getTo() != null)
1726 MappingChoice mpc = new MappingChoice();
1728 && (parentseq != jmp.getTo() || parentseq
1729 .getDatasetSequence() != jmp.getTo()))
1731 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1737 SequenceI ps = null;
1738 if (parentseq != jmp.getTo()
1739 && parentseq.getDatasetSequence() != jmp.getTo())
1741 // chaining dbref rather than a handshaking one
1742 jmpid = seqHash(ps = jmp.getTo());
1746 jmpid = seqHash(ps = parentseq);
1748 mpc.setDseqFor(jmpid);
1749 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1751 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1752 seqRefIds.put(mpc.getDseqFor(), ps);
1756 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1759 mp.setMappingChoice(mpc);
1765 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1766 Vector userColours, JalviewModelSequence jms)
1769 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1770 boolean newucs = false;
1771 if (!userColours.contains(ucs))
1773 userColours.add(ucs);
1776 id = "ucs" + userColours.indexOf(ucs);
1779 // actually create the scheme's entry in the XML model
1780 java.awt.Color[] colours = ucs.getColours();
1781 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1782 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1784 for (int i = 0; i < colours.length; i++)
1786 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1787 col.setName(ResidueProperties.aa[i]);
1788 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1789 jbucs.addColour(col);
1791 if (ucs.getLowerCaseColours() != null)
1793 colours = ucs.getLowerCaseColours();
1794 for (int i = 0; i < colours.length; i++)
1796 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1797 col.setName(ResidueProperties.aa[i].toLowerCase());
1798 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1799 jbucs.addColour(col);
1804 uc.setUserColourScheme(jbucs);
1805 jms.addUserColours(uc);
1811 jalview.schemes.UserColourScheme GetUserColourScheme(
1812 JalviewModelSequence jms, String id)
1814 UserColours[] uc = jms.getUserColours();
1815 UserColours colours = null;
1817 for (int i = 0; i < uc.length; i++)
1819 if (uc[i].getId().equals(id))
1827 java.awt.Color[] newColours = new java.awt.Color[24];
1829 for (int i = 0; i < 24; i++)
1831 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1832 .getUserColourScheme().getColour(i).getRGB(), 16));
1835 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1838 if (colours.getUserColourScheme().getColourCount() > 24)
1840 newColours = new java.awt.Color[23];
1841 for (int i = 0; i < 23; i++)
1843 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1844 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1846 ucs.setLowerCaseColours(newColours);
1853 * contains last error message (if any) encountered by XML loader.
1855 String errorMessage = null;
1858 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1859 * exceptions are raised during project XML parsing
1861 public boolean attemptversion1parse = true;
1864 * Load a jalview project archive from a jar file
1867 * - HTTP URL or filename
1869 public AlignFrame LoadJalviewAlign(final String file)
1872 jalview.gui.AlignFrame af = null;
1876 // create list to store references for any new Jmol viewers created
1877 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1878 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1879 // Workaround is to make sure caller implements the JarInputStreamProvider
1881 // so we can re-open the jar input stream for each entry.
1883 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1884 af = LoadJalviewAlign(jprovider);
1886 } catch (MalformedURLException e)
1888 errorMessage = "Invalid URL format for '" + file + "'";
1894 SwingUtilities.invokeAndWait(new Runnable()
1898 setLoadingFinishedForNewStructureViewers();
1901 } catch (Exception x)
1909 private jarInputStreamProvider createjarInputStreamProvider(
1910 final String file) throws MalformedURLException
1913 errorMessage = null;
1914 uniqueSetSuffix = null;
1916 viewportsAdded = null;
1917 frefedSequence = null;
1919 if (file.startsWith("http://"))
1921 url = new URL(file);
1923 final URL _url = url;
1924 return new jarInputStreamProvider()
1928 public JarInputStream getJarInputStream() throws IOException
1932 return new JarInputStream(_url.openStream());
1936 return new JarInputStream(new FileInputStream(file));
1941 public String getFilename()
1949 * Recover jalview session from a jalview project archive. Caller may
1950 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1951 * themselves. Any null fields will be initialised with default values,
1952 * non-null fields are left alone.
1957 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1959 errorMessage = null;
1960 if (uniqueSetSuffix == null)
1962 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1964 if (seqRefIds == null)
1966 seqRefIds = new Hashtable();
1968 if (viewportsAdded == null)
1970 viewportsAdded = new Hashtable();
1972 if (frefedSequence == null)
1974 frefedSequence = new Vector();
1977 jalview.gui.AlignFrame af = null, _af = null;
1978 Hashtable gatherToThisFrame = new Hashtable();
1979 final String file = jprovider.getFilename();
1982 JarInputStream jin = null;
1983 JarEntry jarentry = null;
1988 jin = jprovider.getJarInputStream();
1989 for (int i = 0; i < entryCount; i++)
1991 jarentry = jin.getNextJarEntry();
1994 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1996 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1997 JalviewModel object = new JalviewModel();
1999 Unmarshaller unmar = new Unmarshaller(object);
2000 unmar.setValidation(false);
2001 object = (JalviewModel) unmar.unmarshal(in);
2002 if (true) // !skipViewport(object))
2004 _af = LoadFromObject(object, file, true, jprovider);
2005 if (object.getJalviewModelSequence().getViewportCount() > 0)
2008 if (af.viewport.gatherViewsHere)
2010 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2016 else if (jarentry != null)
2018 // Some other file here.
2021 } while (jarentry != null);
2022 resolveFrefedSequences();
2023 } catch (java.io.FileNotFoundException ex)
2025 ex.printStackTrace();
2026 errorMessage = "Couldn't locate Jalview XML file : " + file;
2027 System.err.println("Exception whilst loading jalview XML file : "
2029 } catch (java.net.UnknownHostException ex)
2031 ex.printStackTrace();
2032 errorMessage = "Couldn't locate Jalview XML file : " + file;
2033 System.err.println("Exception whilst loading jalview XML file : "
2035 } catch (Exception ex)
2037 System.err.println("Parsing as Jalview Version 2 file failed.");
2038 ex.printStackTrace(System.err);
2039 if (attemptversion1parse)
2041 // Is Version 1 Jar file?
2044 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2045 } catch (Exception ex2)
2047 System.err.println("Exception whilst loading as jalviewXMLV1:");
2048 ex2.printStackTrace();
2052 if (Desktop.instance != null)
2054 Desktop.instance.stopLoading();
2058 System.out.println("Successfully loaded archive file");
2061 ex.printStackTrace();
2063 System.err.println("Exception whilst loading jalview XML file : "
2065 } catch (OutOfMemoryError e)
2067 // Don't use the OOM Window here
2068 errorMessage = "Out of memory loading jalview XML file";
2069 System.err.println("Out of memory whilst loading jalview XML file");
2070 e.printStackTrace();
2073 if (Desktop.instance != null)
2075 Desktop.instance.stopLoading();
2078 Enumeration en = gatherToThisFrame.elements();
2079 while (en.hasMoreElements())
2081 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2083 if (errorMessage != null)
2091 * check errorMessage for a valid error message and raise an error box in the
2092 * GUI or write the current errorMessage to stderr and then clear the error
2095 protected void reportErrors()
2097 reportErrors(false);
2100 protected void reportErrors(final boolean saving)
2102 if (errorMessage != null)
2104 final String finalErrorMessage = errorMessage;
2107 javax.swing.SwingUtilities.invokeLater(new Runnable()
2112 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2113 finalErrorMessage, "Error "
2114 + (saving ? "saving" : "loading")
2115 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2121 System.err.println("Problem loading Jalview file: " + errorMessage);
2124 errorMessage = null;
2127 Hashtable<String, String> alreadyLoadedPDB;
2130 * when set, local views will be updated from view stored in JalviewXML
2131 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2132 * sync if this is set to true.
2134 private final boolean updateLocalViews = false;
2136 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2138 if (alreadyLoadedPDB == null)
2140 alreadyLoadedPDB = new Hashtable();
2143 if (alreadyLoadedPDB.containsKey(pdbId))
2145 return alreadyLoadedPDB.get(pdbId).toString();
2150 JarInputStream jin = jprovider.getJarInputStream();
2152 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2153 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2154 * FileInputStream(jprovider)); }
2157 JarEntry entry = null;
2160 entry = jin.getNextJarEntry();
2161 } while (entry != null && !entry.getName().equals(pdbId));
2164 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2165 File outFile = File.createTempFile("jalview_pdb", ".txt");
2166 outFile.deleteOnExit();
2167 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2170 while ((data = in.readLine()) != null)
2177 } catch (Exception foo)
2182 String t = outFile.getAbsolutePath();
2183 alreadyLoadedPDB.put(pdbId, t);
2188 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2190 } catch (Exception ex)
2192 ex.printStackTrace();
2198 private class JvAnnotRow
2200 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2207 * persisted version of annotation row from which to take vis properties
2209 public jalview.datamodel.AlignmentAnnotation template;
2212 * original position of the annotation row in the alignment
2218 * Load alignment frame from jalview XML DOM object
2223 * filename source string
2224 * @param loadTreesAndStructures
2225 * when false only create Viewport
2227 * data source provider
2228 * @return alignment frame created from view stored in DOM
2230 AlignFrame LoadFromObject(JalviewModel object, String file,
2231 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2233 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2234 Sequence[] vamsasSeq = vamsasSet.getSequence();
2236 JalviewModelSequence jms = object.getJalviewModelSequence();
2238 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2241 // ////////////////////////////////
2244 Vector hiddenSeqs = null;
2245 jalview.datamodel.Sequence jseq;
2247 ArrayList tmpseqs = new ArrayList();
2249 boolean multipleView = false;
2251 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2252 int vi = 0; // counter in vamsasSeq array
2253 for (int i = 0; i < JSEQ.length; i++)
2255 String seqId = JSEQ[i].getId();
2257 if (seqRefIds.get(seqId) != null)
2259 tmpseqs.add(seqRefIds.get(seqId));
2260 multipleView = true;
2264 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2265 vamsasSeq[vi].getSequence());
2266 jseq.setDescription(vamsasSeq[vi].getDescription());
2267 jseq.setStart(JSEQ[i].getStart());
2268 jseq.setEnd(JSEQ[i].getEnd());
2269 jseq.setVamsasId(uniqueSetSuffix + seqId);
2270 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2275 if (JSEQ[i].getHidden())
2277 if (hiddenSeqs == null)
2279 hiddenSeqs = new Vector();
2282 hiddenSeqs.addElement(seqRefIds.get(seqId));
2288 // Create the alignment object from the sequence set
2289 // ///////////////////////////////
2290 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2293 tmpseqs.toArray(orderedSeqs);
2295 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2298 // / Add the alignment properties
2299 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2301 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2302 al.setProperty(ssp.getKey(), ssp.getValue());
2306 // SequenceFeatures are added to the DatasetSequence,
2307 // so we must create or recover the dataset before loading features
2308 // ///////////////////////////////
2309 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2311 // older jalview projects do not have a dataset id.
2312 al.setDataset(null);
2316 // recover dataset - passing on flag indicating if this a 'viewless'
2317 // sequence set (a.k.a. a stored dataset for the project)
2318 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2319 .getViewportCount() == 0);
2321 // ///////////////////////////////
2323 Hashtable pdbloaded = new Hashtable();
2326 // load sequence features, database references and any associated PDB
2327 // structures for the alignment
2328 for (int i = 0; i < vamsasSeq.length; i++)
2330 if (JSEQ[i].getFeaturesCount() > 0)
2332 Features[] features = JSEQ[i].getFeatures();
2333 for (int f = 0; f < features.length; f++)
2335 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2336 features[f].getType(), features[f].getDescription(),
2337 features[f].getStatus(), features[f].getBegin(),
2338 features[f].getEnd(), features[f].getFeatureGroup());
2340 sf.setScore(features[f].getScore());
2341 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2343 OtherData keyValue = features[f].getOtherData(od);
2344 if (keyValue.getKey().startsWith("LINK"))
2346 sf.addLink(keyValue.getValue());
2350 sf.setValue(keyValue.getKey(), keyValue.getValue());
2355 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2358 if (vamsasSeq[i].getDBRefCount() > 0)
2360 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2362 if (JSEQ[i].getPdbidsCount() > 0)
2364 Pdbids[] ids = JSEQ[i].getPdbids();
2365 for (int p = 0; p < ids.length; p++)
2367 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2368 entry.setId(ids[p].getId());
2369 entry.setType(ids[p].getType());
2370 if (ids[p].getFile() != null)
2372 if (!pdbloaded.containsKey(ids[p].getFile()))
2374 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2378 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2381 StructureSelectionManager.getStructureSelectionManager(
2383 .registerPDBEntry(entry);
2384 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2388 } // end !multipleview
2390 // ///////////////////////////////
2391 // LOAD SEQUENCE MAPPINGS
2393 if (vamsasSet.getAlcodonFrameCount() > 0)
2395 // TODO Potentially this should only be done once for all views of an
2397 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2398 for (int i = 0; i < alc.length; i++)
2400 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2401 alc[i].getAlcodonCount());
2402 if (alc[i].getAlcodonCount() > 0)
2404 Alcodon[] alcods = alc[i].getAlcodon();
2405 for (int p = 0; p < cf.codons.length; p++)
2407 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2408 && alcods[p].hasPos3())
2410 // translated codons require three valid positions
2411 cf.codons[p] = new int[3];
2412 cf.codons[p][0] = (int) alcods[p].getPos1();
2413 cf.codons[p][1] = (int) alcods[p].getPos2();
2414 cf.codons[p][2] = (int) alcods[p].getPos3();
2418 cf.codons[p] = null;
2422 if (alc[i].getAlcodMapCount() > 0)
2424 AlcodMap[] maps = alc[i].getAlcodMap();
2425 for (int m = 0; m < maps.length; m++)
2427 SequenceI dnaseq = (SequenceI) seqRefIds
2428 .get(maps[m].getDnasq());
2430 jalview.datamodel.Mapping mapping = null;
2431 // attach to dna sequence reference.
2432 if (maps[m].getMapping() != null)
2434 mapping = addMapping(maps[m].getMapping());
2438 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2443 frefedSequence.add(new Object[]
2444 { maps[m].getDnasq(), cf, mapping });
2448 al.addCodonFrame(cf);
2453 // ////////////////////////////////
2455 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2457 * store any annotations which forward reference a group's ID
2459 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2461 if (vamsasSet.getAnnotationCount() > 0)
2463 Annotation[] an = vamsasSet.getAnnotation();
2465 for (int i = 0; i < an.length; i++)
2468 * test if annotation is automatically calculated for this view only
2470 boolean autoForView = false;
2471 if (an[i].getLabel().equals("Quality")
2472 || an[i].getLabel().equals("Conservation")
2473 || an[i].getLabel().equals("Consensus"))
2475 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2477 if (!an[i].hasAutoCalculated())
2479 an[i].setAutoCalculated(true);
2483 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2485 // remove ID - we don't recover annotation from other views for
2486 // view-specific annotation
2490 // set visiblity for other annotation in this view
2491 if (an[i].getId() != null
2492 && annotationIds.containsKey(an[i].getId()))
2494 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2495 .get(an[i].getId());
2496 // in principle Visible should always be true for annotation displayed
2497 // in multiple views
2498 if (an[i].hasVisible())
2500 jda.visible = an[i].getVisible();
2503 al.addAnnotation(jda);
2507 // Construct new annotation from model.
2508 AnnotationElement[] ae = an[i].getAnnotationElement();
2509 jalview.datamodel.Annotation[] anot = null;
2510 java.awt.Color firstColour = null;
2512 if (!an[i].getScoreOnly())
2514 anot = new jalview.datamodel.Annotation[al.getWidth()];
2515 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2517 anpos = ae[aa].getPosition();
2519 if (anpos >= anot.length)
2524 anot[anpos] = new jalview.datamodel.Annotation(
2526 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2527 (ae[aa].getSecondaryStructure() == null || ae[aa]
2528 .getSecondaryStructure().length() == 0) ? ' '
2529 : ae[aa].getSecondaryStructure().charAt(0),
2533 // JBPNote: Consider verifying dataflow for IO of secondary
2534 // structure annotation read from Stockholm files
2535 // this was added to try to ensure that
2536 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2538 // anot[ae[aa].getPosition()].displayCharacter = "";
2540 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2541 if (firstColour == null)
2543 firstColour = anot[anpos].colour;
2547 jalview.datamodel.AlignmentAnnotation jaa = null;
2549 if (an[i].getGraph())
2551 float llim = 0, hlim = 0;
2552 // if (autoForView || an[i].isAutoCalculated()) {
2555 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2556 an[i].getDescription(), anot, llim, hlim,
2557 an[i].getGraphType());
2559 jaa.graphGroup = an[i].getGraphGroup();
2560 jaa._linecolour = firstColour;
2561 if (an[i].getThresholdLine() != null)
2563 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2564 .getThresholdLine().getValue(), an[i]
2565 .getThresholdLine().getLabel(), new java.awt.Color(
2566 an[i].getThresholdLine().getColour())));
2569 if (autoForView || an[i].isAutoCalculated())
2571 // Hardwire the symbol display line to ensure that labels for
2572 // histograms are displayed
2578 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2579 an[i].getDescription(), anot);
2580 jaa._linecolour = firstColour;
2582 // register new annotation
2583 if (an[i].getId() != null)
2585 annotationIds.put(an[i].getId(), jaa);
2586 jaa.annotationId = an[i].getId();
2588 // recover sequence association
2589 if (an[i].getSequenceRef() != null)
2591 if (al.findName(an[i].getSequenceRef()) != null)
2593 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2595 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2598 // and make a note of any group association
2599 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2601 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2602 .get(an[i].getGroupRef());
2605 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2606 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2611 if (an[i].hasScore())
2613 jaa.setScore(an[i].getScore());
2615 if (an[i].hasVisible())
2617 jaa.visible = an[i].getVisible();
2620 if (an[i].hasCentreColLabels())
2622 jaa.centreColLabels = an[i].getCentreColLabels();
2625 if (an[i].hasScaleColLabels())
2627 jaa.scaleColLabel = an[i].getScaleColLabels();
2629 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2631 // newer files have an 'autoCalculated' flag and store calculation
2632 // state in viewport properties
2633 jaa.autoCalculated = true; // means annotation will be marked for
2634 // update at end of load.
2636 if (an[i].hasGraphHeight())
2638 jaa.graphHeight = an[i].getGraphHeight();
2640 if (an[i].hasBelowAlignment())
2642 jaa.belowAlignment = an[i].isBelowAlignment();
2644 jaa.setCalcId(an[i].getCalcId());
2645 if (an[i].getPropertyCount() > 0)
2647 for (jalview.schemabinding.version2.Property prop : an[i]
2650 jaa.setProperty(prop.getName(), prop.getValue());
2653 if (jaa.autoCalculated)
2655 autoAlan.add(new JvAnnotRow(i, jaa));
2658 // if (!autoForView)
2660 // add autocalculated group annotation and any user created annotation
2662 al.addAnnotation(jaa);
2666 // ///////////////////////
2668 // Create alignment markup and styles for this view
2669 if (jms.getJGroupCount() > 0)
2671 JGroup[] groups = jms.getJGroup();
2672 boolean addAnnotSchemeGroup = false;
2673 for (int i = 0; i < groups.length; i++)
2675 ColourSchemeI cs = null;
2677 if (groups[i].getColour() != null)
2679 if (groups[i].getColour().startsWith("ucs"))
2681 cs = GetUserColourScheme(jms, groups[i].getColour());
2683 else if (groups[i].getColour().equals("AnnotationColourGradient")
2684 && groups[i].getAnnotationColours() != null)
2686 addAnnotSchemeGroup = true;
2691 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2696 cs.setThreshold(groups[i].getPidThreshold(), true);
2700 Vector seqs = new Vector();
2702 for (int s = 0; s < groups[i].getSeqCount(); s++)
2704 String seqId = groups[i].getSeq(s) + "";
2705 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2710 seqs.addElement(ts);
2714 if (seqs.size() < 1)
2719 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2720 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2721 groups[i].getDisplayText(), groups[i].getColourText(),
2722 groups[i].getStart(), groups[i].getEnd());
2724 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2726 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2727 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2728 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2729 .isShowUnconserved() : false);
2730 sg.thresholdTextColour = groups[i].getTextColThreshold();
2731 if (groups[i].hasShowConsensusHistogram())
2733 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2736 if (groups[i].hasShowSequenceLogo())
2738 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2740 if (groups[i].hasNormaliseSequenceLogo())
2742 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2744 if (groups[i].hasIgnoreGapsinConsensus())
2746 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2748 if (groups[i].getConsThreshold() != 0)
2750 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2751 "All", ResidueProperties.propHash, 3,
2752 sg.getSequences(null), 0, sg.getWidth() - 1);
2754 c.verdict(false, 25);
2755 sg.cs.setConservation(c);
2758 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2760 // re-instate unique group/annotation row reference
2761 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2762 .get(groups[i].getId());
2765 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2768 if (jaa.autoCalculated)
2770 // match up and try to set group autocalc alignment row for this
2772 if (jaa.label.startsWith("Consensus for "))
2774 sg.setConsensus(jaa);
2776 // match up and try to set group autocalc alignment row for this
2778 if (jaa.label.startsWith("Conservation for "))
2780 sg.setConservationRow(jaa);
2787 if (addAnnotSchemeGroup)
2789 // reconstruct the annotation colourscheme
2790 sg.cs = constructAnnotationColour(
2791 groups[i].getAnnotationColours(), null, al, jms, false);
2797 // only dataset in this model, so just return.
2800 // ///////////////////////////////
2803 // If we just load in the same jar file again, the sequenceSetId
2804 // will be the same, and we end up with multiple references
2805 // to the same sequenceSet. We must modify this id on load
2806 // so that each load of the file gives a unique id
2807 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2808 String viewId = (view.getId() == null ? null : view.getId()
2810 AlignFrame af = null;
2811 AlignViewport av = null;
2812 // now check to see if we really need to create a new viewport.
2813 if (multipleView && viewportsAdded.size() == 0)
2815 // We recovered an alignment for which a viewport already exists.
2816 // TODO: fix up any settings necessary for overlaying stored state onto
2817 // state recovered from another document. (may not be necessary).
2818 // we may need a binding from a viewport in memory to one recovered from
2820 // and then recover its containing af to allow the settings to be applied.
2821 // TODO: fix for vamsas demo
2823 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2825 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2826 if (seqsetobj != null)
2828 if (seqsetobj instanceof String)
2830 uniqueSeqSetId = (String) seqsetobj;
2832 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2838 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2844 * indicate that annotation colours are applied across all groups (pre
2845 * Jalview 2.8.1 behaviour)
2847 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2848 object.getVersion());
2850 AlignmentPanel ap = null;
2851 boolean isnewview = true;
2854 // Check to see if this alignment already has a view id == viewId
2855 jalview.gui.AlignmentPanel views[] = Desktop
2856 .getAlignmentPanels(uniqueSeqSetId);
2857 if (views != null && views.length > 0)
2859 for (int v = 0; v < views.length; v++)
2861 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2863 // recover the existing alignpanel, alignframe, viewport
2864 af = views[v].alignFrame;
2867 // TODO: could even skip resetting view settings if we don't want to
2868 // change the local settings from other jalview processes
2877 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2878 uniqueSeqSetId, viewId, autoAlan);
2883 // /////////////////////////////////////
2884 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2888 for (int t = 0; t < jms.getTreeCount(); t++)
2891 Tree tree = jms.getTree(t);
2893 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2896 tp = af.ShowNewickTree(
2897 new jalview.io.NewickFile(tree.getNewick()),
2898 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2899 tree.getXpos(), tree.getYpos());
2900 if (tree.getId() != null)
2902 // perhaps bind the tree id to something ?
2907 // update local tree attributes ?
2908 // TODO: should check if tp has been manipulated by user - if so its
2909 // settings shouldn't be modified
2910 tp.setTitle(tree.getTitle());
2911 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2912 .getWidth(), tree.getHeight()));
2913 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2916 tp.treeCanvas.av = av; // af.viewport;
2917 tp.treeCanvas.ap = ap; // af.alignPanel;
2922 warn("There was a problem recovering stored Newick tree: \n"
2923 + tree.getNewick());
2927 tp.fitToWindow.setState(tree.getFitToWindow());
2928 tp.fitToWindow_actionPerformed(null);
2930 if (tree.getFontName() != null)
2932 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2933 .getFontStyle(), tree.getFontSize()));
2937 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2938 .getFontStyle(), tree.getFontSize()));
2941 tp.showPlaceholders(tree.getMarkUnlinked());
2942 tp.showBootstrap(tree.getShowBootstrap());
2943 tp.showDistances(tree.getShowDistances());
2945 tp.treeCanvas.threshold = tree.getThreshold();
2947 if (tree.getCurrentTree())
2949 af.viewport.setCurrentTree(tp.getTree());
2953 } catch (Exception ex)
2955 ex.printStackTrace();
2959 // //LOAD STRUCTURES
2960 if (loadTreesAndStructures)
2962 // run through all PDB ids on the alignment, and collect mappings between
2963 // jmol view ids and all sequences referring to it
2964 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2966 for (int i = 0; i < JSEQ.length; i++)
2968 if (JSEQ[i].getPdbidsCount() > 0)
2970 Pdbids[] ids = JSEQ[i].getPdbids();
2971 for (int p = 0; p < ids.length; p++)
2973 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2975 // check to see if we haven't already created this structure view
2976 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2977 : ids[p].getStructureState(s).getViewId()
2979 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2980 // Originally : ids[p].getFile()
2981 // : TODO: verify external PDB file recovery still works in normal
2982 // jalview project load
2983 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2984 jpdb.setId(ids[p].getId());
2986 int x = ids[p].getStructureState(s).getXpos();
2987 int y = ids[p].getStructureState(s).getYpos();
2988 int width = ids[p].getStructureState(s).getWidth();
2989 int height = ids[p].getStructureState(s).getHeight();
2991 // Probably don't need to do this anymore...
2992 // Desktop.desktop.getComponentAt(x, y);
2993 // TODO: NOW: check that this recovers the PDB file correctly.
2994 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2995 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2996 .get(JSEQ[i].getId() + "");
2997 if (sviewid == null)
2999 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3002 if (!jmolViewIds.containsKey(sviewid))
3004 jmolViewIds.put(sviewid, new Object[]
3006 { x, y, width, height }, "",
3007 new Hashtable<String, Object[]>(), new boolean[]
3008 { false, false, true } });
3009 // Legacy pre-2.7 conversion JAL-823 :
3010 // do not assume any view has to be linked for colour by
3014 // assemble String[] { pdb files }, String[] { id for each
3015 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3016 // seqs_file 2}, boolean[] {
3017 // linkAlignPanel,superposeWithAlignpanel}} from hash
3018 Object[] jmoldat = jmolViewIds.get(sviewid);
3019 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
3020 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
3021 s).getAlignwithAlignPanel() : false;
3022 // never colour by linked panel if not specified
3023 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
3024 .hasColourwithAlignPanel() ? ids[p]
3025 .getStructureState(s).getColourwithAlignPanel()
3027 // default for pre-2.7 projects is that Jmol colouring is enabled
3028 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
3029 .hasColourByJmol() ? ids[p].getStructureState(s)
3030 .getColourByJmol() : true;
3032 if (((String) jmoldat[1]).length() < ids[p]
3033 .getStructureState(s).getContent().length())
3036 jmoldat[1] = ids[p].getStructureState(s).getContent();
3039 if (ids[p].getFile() != null)
3041 File mapkey = new File(ids[p].getFile());
3042 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3044 if (seqstrmaps == null)
3046 ((Hashtable) jmoldat[2]).put(mapkey,
3047 seqstrmaps = new Object[]
3048 { pdbFile, ids[p].getId(), new Vector(),
3051 if (!((Vector) seqstrmaps[2]).contains(seq))
3053 ((Vector) seqstrmaps[2]).addElement(seq);
3054 // ((Vector)seqstrmaps[3]).addElement(n) :
3055 // in principle, chains
3056 // should be stored here : do we need to
3057 // TODO: store and recover seq/pdb_id :
3063 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");
3072 // Instantiate the associated Jmol views
3073 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3075 String sviewid = entry.getKey();
3076 Object[] svattrib = entry.getValue();
3077 int[] geom = (int[]) svattrib[0];
3078 String state = (String) svattrib[1];
3079 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3080 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3081 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3082 // collate the pdbfile -> sequence mappings from this view
3083 Vector<String> pdbfilenames = new Vector<String>();
3084 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3085 Vector<String> pdbids = new Vector<String>();
3087 // Search to see if we've already created this Jmol view
3088 AppJmol comp = null;
3089 JInternalFrame[] frames = null;
3094 frames = Desktop.desktop.getAllFrames();
3095 } catch (ArrayIndexOutOfBoundsException e)
3097 // occasional No such child exceptions are thrown here...
3102 } catch (Exception f)
3107 } while (frames == null);
3108 // search for any Jmol windows already open from other
3109 // alignment views that exactly match the stored structure state
3110 for (int f = 0; comp == null && f < frames.length; f++)
3112 if (frames[f] instanceof AppJmol)
3115 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3117 // post jalview 2.4 schema includes structure view id
3118 comp = (AppJmol) frames[f];
3120 else if (frames[f].getX() == x && frames[f].getY() == y
3121 && frames[f].getHeight() == height
3122 && frames[f].getWidth() == width)
3124 comp = (AppJmol) frames[f];
3131 // create a new Jmol window.
3132 // First parse the Jmol state to translate filenames loaded into the
3133 // view, and record the order in which files are shown in the Jmol
3134 // view, so we can add the sequence mappings in same order.
3135 StringBuffer newFileLoc = null;
3136 int cp = 0, ncp, ecp;
3137 while ((ncp = state.indexOf("load ", cp)) > -1)
3139 if (newFileLoc == null)
3141 newFileLoc = new StringBuffer();
3145 // look for next filename in load statement
3146 newFileLoc.append(state.substring(cp,
3147 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3148 String oldfilenam = state.substring(ncp,
3149 ecp = state.indexOf("\"", ncp));
3150 // recover the new mapping data for this old filename
3151 // have to normalize filename - since Jmol and jalview do
3153 // translation differently.
3154 Object[] filedat = oldFiles.get(new File(oldfilenam));
3155 newFileLoc.append(Platform
3156 .escapeString((String) filedat[0]));
3157 pdbfilenames.addElement((String) filedat[0]);
3158 pdbids.addElement((String) filedat[1]);
3159 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3160 .toArray(new SequenceI[0]));
3161 newFileLoc.append("\"");
3162 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3163 // look for next file statement.
3164 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3168 // just append rest of state
3169 newFileLoc.append(state.substring(cp));
3174 .print("Ignoring incomplete Jmol state for PDB ids: ");
3175 newFileLoc = new StringBuffer(state);
3176 newFileLoc.append("; load append ");
3177 for (File id : oldFiles.keySet())
3179 // add this and any other pdb files that should be present in
3181 Object[] filedat = oldFiles.get(id);
3183 newFileLoc.append(((String) filedat[0]));
3184 pdbfilenames.addElement((String) filedat[0]);
3185 pdbids.addElement((String) filedat[1]);
3186 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3187 .toArray(new SequenceI[0]));
3188 newFileLoc.append(" \"");
3189 newFileLoc.append((String) filedat[0]);
3190 newFileLoc.append("\"");
3193 newFileLoc.append(";");
3196 if (newFileLoc != null)
3198 int histbug = newFileLoc.indexOf("history = ");
3200 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3202 String val = (diff == -1) ? null : newFileLoc.substring(
3204 if (val != null && val.length() >= 4)
3206 if (val.contains("e"))
3208 if (val.trim().equals("true"))
3216 newFileLoc.replace(histbug, diff, val);
3219 // TODO: assemble String[] { pdb files }, String[] { id for each
3220 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3221 // seqs_file 2}} from hash
3222 final String[] pdbf = pdbfilenames
3223 .toArray(new String[pdbfilenames.size()]), id = pdbids
3224 .toArray(new String[pdbids.size()]);
3225 final SequenceI[][] sq = seqmaps
3226 .toArray(new SequenceI[seqmaps.size()][]);
3227 final String fileloc = newFileLoc.toString(), vid = sviewid;
3228 final AlignFrame alf = af;
3229 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3233 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3238 JalviewStructureDisplayI sview = null;
3241 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3242 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3243 useinJmolsuperpos, usetoColourbyseq,
3244 jmolColouring, fileloc, rect, vid);
3245 addNewStructureViewer(sview);
3246 } catch (OutOfMemoryError ex)
3248 new OOMWarning("restoring structure view for PDB id "
3249 + id, (OutOfMemoryError) ex.getCause());
3250 if (sview != null && sview.isVisible())
3252 sview.closeViewer();
3253 sview.setVisible(false);
3259 } catch (InvocationTargetException ex)
3261 warn("Unexpected error when opening Jmol view.", ex);
3263 } catch (InterruptedException e)
3265 // e.printStackTrace();
3271 // if (comp != null)
3273 // NOTE: if the jalview project is part of a shared session then
3274 // view synchronization should/could be done here.
3276 // add mapping for sequences in this view to an already open Jmol
3278 for (File id : oldFiles.keySet())
3280 // add this and any other pdb files that should be present in the
3282 Object[] filedat = oldFiles.get(id);
3283 String pdbFile = (String) filedat[0];
3284 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3285 .toArray(new SequenceI[0]);
3286 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3287 jalview.io.AppletFormatAdapter.FILE);
3288 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3290 // and add the AlignmentPanel's reference to the Jmol view
3291 comp.addAlignmentPanel(ap);
3292 if (useinJmolsuperpos)
3294 comp.useAlignmentPanelForSuperposition(ap);
3298 comp.excludeAlignmentPanelForSuperposition(ap);
3300 if (usetoColourbyseq)
3302 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3306 comp.excludeAlignmentPanelForColourbyseq(ap);
3312 // and finally return.
3319 * - minimum version we are comparing against
3321 * - version of data being processsed.
3322 * @return true if version is development/null or evaluates to the same or
3323 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3325 private boolean isVersionStringLaterThan(String supported, String version)
3327 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3328 || version.equalsIgnoreCase("Test")
3329 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3331 System.err.println("Assuming project file with "
3332 + (version == null ? "null" : version)
3333 + " is compatible with Jalview version " + supported);
3338 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3340 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3342 // convert b to decimal to catch bugfix releases within a series
3343 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3344 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3347 if (Float.valueOf(curT) > Float.valueOf(fileT))
3349 // current version is newer than the version that wrote the file
3352 } catch (NumberFormatException nfe)
3355 .println("** WARNING: Version comparison failed for tokens ("
3359 + ")\n** Current: '"
3360 + supported + "' and Version: '" + version + "'");
3363 if (currentV.hasMoreElements())
3365 // fileV has no minor version but identical series to current
3372 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3374 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3376 if (newStructureViewers != null)
3378 sview.getBinding().setFinishedLoadingFromArchive(false);
3379 newStructureViewers.add(sview);
3383 protected void setLoadingFinishedForNewStructureViewers()
3385 if (newStructureViewers != null)
3387 for (JalviewStructureDisplayI sview : newStructureViewers)
3389 sview.getBinding().setFinishedLoadingFromArchive(true);
3391 newStructureViewers.clear();
3392 newStructureViewers = null;
3396 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3397 Alignment al, JalviewModelSequence jms, Viewport view,
3398 String uniqueSeqSetId, String viewId,
3399 ArrayList<JvAnnotRow> autoAlan)
3401 AlignFrame af = null;
3402 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3403 uniqueSeqSetId, viewId);
3405 af.setFileName(file, "Jalview");
3407 for (int i = 0; i < JSEQ.length; i++)
3409 af.viewport.setSequenceColour(af.viewport.getAlignment()
3410 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3413 af.viewport.gatherViewsHere = view.getGatheredViews();
3415 if (view.getSequenceSetId() != null)
3417 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3418 .get(uniqueSeqSetId);
3420 af.viewport.setSequenceSetId(uniqueSeqSetId);
3423 // propagate shared settings to this new view
3424 af.viewport.historyList = av.historyList;
3425 af.viewport.redoList = av.redoList;
3429 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3431 // TODO: check if this method can be called repeatedly without
3432 // side-effects if alignpanel already registered.
3433 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3435 // apply Hidden regions to view.
3436 if (hiddenSeqs != null)
3438 for (int s = 0; s < JSEQ.length; s++)
3440 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3442 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3445 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3447 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3450 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3453 for (int s = 0; s < hiddenSeqs.size(); s++)
3455 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3458 af.viewport.hideSequence(hseqs);
3461 // recover view properties and display parameters
3462 if (view.getViewName() != null)
3464 af.viewport.viewName = view.getViewName();
3465 af.setInitialTabVisible();
3467 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3470 af.viewport.setShowAnnotation(view.getShowAnnotation());
3471 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3473 af.viewport.setColourText(view.getShowColourText());
3475 af.viewport.setConservationSelected(view.getConservationSelected());
3476 af.viewport.setShowJVSuffix(view.getShowFullId());
3477 af.viewport.setRightAlignIds(view.getRightAlignIds());
3478 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3479 .getFontStyle(), view.getFontSize()));
3480 af.alignPanel.fontChanged();
3481 af.viewport.setRenderGaps(view.getRenderGaps());
3482 af.viewport.setWrapAlignment(view.getWrapAlignment());
3483 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3484 af.viewport.setShowAnnotation(view.getShowAnnotation());
3485 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3487 af.viewport.setShowBoxes(view.getShowBoxes());
3489 af.viewport.setShowText(view.getShowText());
3491 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3492 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3493 af.viewport.thresholdTextColour = view.getTextColThreshold();
3494 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3495 .isShowUnconserved() : false);
3496 af.viewport.setStartRes(view.getStartRes());
3497 af.viewport.setStartSeq(view.getStartSeq());
3499 ColourSchemeI cs = null;
3500 // apply colourschemes
3501 if (view.getBgColour() != null)
3503 if (view.getBgColour().startsWith("ucs"))
3505 cs = GetUserColourScheme(jms, view.getBgColour());
3507 else if (view.getBgColour().startsWith("Annotation"))
3509 AnnotationColours viewAnnColour = view.getAnnotationColours();
3510 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3517 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3522 cs.setThreshold(view.getPidThreshold(), true);
3523 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3527 af.viewport.setGlobalColourScheme(cs);
3528 af.viewport.setColourAppliesToAllGroups(false);
3530 if (view.getConservationSelected() && cs != null)
3532 cs.setConservationInc(view.getConsThreshold());
3535 af.changeColour(cs);
3537 af.viewport.setColourAppliesToAllGroups(true);
3539 if (view.getShowSequenceFeatures())
3541 af.viewport.showSequenceFeatures = true;
3543 if (view.hasCentreColumnLabels())
3545 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3547 if (view.hasIgnoreGapsinConsensus())
3549 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3552 if (view.hasFollowHighlight())
3554 af.viewport.followHighlight = view.getFollowHighlight();
3556 if (view.hasFollowSelection())
3558 af.viewport.followSelection = view.getFollowSelection();
3560 if (view.hasShowConsensusHistogram())
3562 af.viewport.setShowConsensusHistogram(view
3563 .getShowConsensusHistogram());
3567 af.viewport.setShowConsensusHistogram(true);
3569 if (view.hasShowSequenceLogo())
3571 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3575 af.viewport.setShowSequenceLogo(false);
3577 if (view.hasNormaliseSequenceLogo())
3579 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3581 if (view.hasShowDbRefTooltip())
3583 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3585 if (view.hasShowNPfeatureTooltip())
3587 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3589 if (view.hasShowGroupConsensus())
3591 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3595 af.viewport.setShowGroupConsensus(false);
3597 if (view.hasShowGroupConservation())
3599 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3603 af.viewport.setShowGroupConservation(false);
3606 // recover featre settings
3607 if (jms.getFeatureSettings() != null)
3609 af.viewport.setFeaturesDisplayed(new Hashtable());
3610 String[] renderOrder = new String[jms.getFeatureSettings()
3611 .getSettingCount()];
3612 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3614 Setting setting = jms.getFeatureSettings().getSetting(fs);
3615 if (setting.hasMincolour())
3617 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3618 new java.awt.Color(setting.getMincolour()),
3619 new java.awt.Color(setting.getColour()),
3620 setting.getMin(), setting.getMax()) : new GraduatedColor(
3621 new java.awt.Color(setting.getMincolour()),
3622 new java.awt.Color(setting.getColour()), 0, 1);
3623 if (setting.hasThreshold())
3625 gc.setThresh(setting.getThreshold());
3626 gc.setThreshType(setting.getThreshstate());
3628 gc.setAutoScaled(true); // default
3629 if (setting.hasAutoScale())
3631 gc.setAutoScaled(setting.getAutoScale());
3633 if (setting.hasColourByLabel())
3635 gc.setColourByLabel(setting.getColourByLabel());
3637 // and put in the feature colour table.
3638 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3639 setting.getType(), gc);
3643 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3645 new java.awt.Color(setting.getColour()));
3647 renderOrder[fs] = setting.getType();
3648 if (setting.hasOrder())
3650 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3651 setting.getType(), setting.getOrder());
3655 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3657 fs / jms.getFeatureSettings().getSettingCount());
3659 if (setting.getDisplay())
3661 af.viewport.getFeaturesDisplayed().put(setting.getType(), new Integer(
3662 setting.getColour()));
3665 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3667 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3668 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3670 Group grp = jms.getFeatureSettings().getGroup(gs);
3671 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3675 if (view.getHiddenColumnsCount() > 0)
3677 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3679 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3680 .getHiddenColumns(c).getEnd() // +1
3684 if (view.getCalcIdParam() != null)
3686 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3688 if (calcIdParam != null)
3690 if (recoverCalcIdParam(calcIdParam, af.viewport))
3695 warn("Couldn't recover parameters for "
3696 + calcIdParam.getCalcId());
3701 af.setMenusFromViewport(af.viewport);
3702 // TODO: we don't need to do this if the viewport is aready visible.
3703 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3705 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3706 reorderAutoannotation(af, al, autoAlan);
3707 af.alignPanel.alignmentChanged();
3711 private ColourSchemeI constructAnnotationColour(
3712 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3713 JalviewModelSequence jms, boolean checkGroupAnnColour)
3715 boolean propagateAnnColour = false;
3716 ColourSchemeI cs = null;
3717 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3718 if (checkGroupAnnColour && al.getGroups() != null
3719 && al.getGroups().size() > 0)
3721 // pre 2.8.1 behaviour
3722 // check to see if we should transfer annotation colours
3723 propagateAnnColour = true;
3724 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3726 if (sg.cs instanceof AnnotationColourGradient)
3728 propagateAnnColour = false;
3732 // int find annotation
3733 if (annAlignment.getAlignmentAnnotation() != null)
3735 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3737 if (annAlignment.getAlignmentAnnotation()[i].label
3738 .equals(viewAnnColour.getAnnotation()))
3740 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3742 annAlignment.getAlignmentAnnotation()[i]
3743 .setThreshold(new jalview.datamodel.GraphLine(
3744 viewAnnColour.getThreshold(), "Threshold",
3745 java.awt.Color.black)
3750 if (viewAnnColour.getColourScheme().equals("None"))
3752 cs = new AnnotationColourGradient(
3753 annAlignment.getAlignmentAnnotation()[i],
3754 new java.awt.Color(viewAnnColour.getMinColour()),
3755 new java.awt.Color(viewAnnColour.getMaxColour()),
3756 viewAnnColour.getAboveThreshold());
3758 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3760 cs = new AnnotationColourGradient(
3761 annAlignment.getAlignmentAnnotation()[i],
3762 GetUserColourScheme(jms,
3763 viewAnnColour.getColourScheme()),
3764 viewAnnColour.getAboveThreshold());
3768 cs = new AnnotationColourGradient(
3769 annAlignment.getAlignmentAnnotation()[i],
3770 ColourSchemeProperty.getColour(al,
3771 viewAnnColour.getColourScheme()),
3772 viewAnnColour.getAboveThreshold());
3774 if (viewAnnColour.hasPerSequence())
3776 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3779 if (viewAnnColour.hasPredefinedColours())
3781 ((AnnotationColourGradient) cs)
3782 .setPredefinedColours(viewAnnColour
3783 .isPredefinedColours());
3785 if (propagateAnnColour && al.getGroups() != null)
3787 // Also use these settings for all the groups
3788 for (int g = 0; g < al.getGroups().size(); g++)
3790 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3798 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3799 * new AnnotationColourGradient(
3800 * annAlignment.getAlignmentAnnotation()[i], new
3801 * java.awt.Color(viewAnnColour. getMinColour()), new
3802 * java.awt.Color(viewAnnColour. getMaxColour()),
3803 * viewAnnColour.getAboveThreshold()); } else
3806 sg.cs = new AnnotationColourGradient(
3807 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3808 viewAnnColour.getAboveThreshold());
3809 if (cs instanceof AnnotationColourGradient)
3811 if (viewAnnColour.hasPerSequence())
3813 ((AnnotationColourGradient) cs)
3814 .setSeqAssociated(viewAnnColour.isPerSequence());
3816 if (viewAnnColour.hasPredefinedColours())
3818 ((AnnotationColourGradient) cs)
3819 .setPredefinedColours(viewAnnColour
3820 .isPredefinedColours());
3836 private void reorderAutoannotation(AlignFrame af, Alignment al,
3837 ArrayList<JvAnnotRow> autoAlan)
3839 // copy over visualization settings for autocalculated annotation in the
3841 if (al.getAlignmentAnnotation() != null)
3844 * Kludge for magic autoannotation names (see JAL-811)
3846 String[] magicNames = new String[]
3847 { "Consensus", "Quality", "Conservation" };
3848 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3849 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3850 for (String nm : magicNames)
3852 visan.put(nm, nullAnnot);
3854 for (JvAnnotRow auan : autoAlan)
3856 visan.put(auan.template.label
3857 + (auan.template.getCalcId() == null ? "" : "\t"
3858 + auan.template.getCalcId()), auan);
3860 int hSize = al.getAlignmentAnnotation().length;
3861 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3862 // work through any autoCalculated annotation already on the view
3863 // removing it if it should be placed in a different location on the
3864 // annotation panel.
3865 List<String> remains = new ArrayList(visan.keySet());
3866 for (int h = 0; h < hSize; h++)
3868 jalview.datamodel.AlignmentAnnotation jalan = al
3869 .getAlignmentAnnotation()[h];
3870 if (jalan.autoCalculated)
3873 JvAnnotRow valan = visan.get(k = jalan.label);
3874 if (jalan.getCalcId() != null)
3876 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3881 // delete the auto calculated row from the alignment
3882 al.deleteAnnotation(jalan, false);
3886 if (valan != nullAnnot)
3888 if (jalan != valan.template)
3890 // newly created autoannotation row instance
3891 // so keep a reference to the visible annotation row
3892 // and copy over all relevant attributes
3893 if (valan.template.graphHeight >= 0)
3896 jalan.graphHeight = valan.template.graphHeight;
3898 jalan.visible = valan.template.visible;
3900 reorder.add(new JvAnnotRow(valan.order, jalan));
3905 // Add any (possibly stale) autocalculated rows that were not appended to
3906 // the view during construction
3907 for (String other : remains)
3909 JvAnnotRow othera = visan.get(other);
3910 if (othera != nullAnnot && othera.template.getCalcId() != null
3911 && othera.template.getCalcId().length() > 0)
3913 reorder.add(othera);
3916 // now put the automatic annotation in its correct place
3917 int s = 0, srt[] = new int[reorder.size()];
3918 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3919 for (JvAnnotRow jvar : reorder)
3922 srt[s++] = jvar.order;
3925 jalview.util.QuickSort.sort(srt, rws);
3926 // and re-insert the annotation at its correct position
3927 for (JvAnnotRow jvar : rws)
3929 al.addAnnotation(jvar.template, jvar.order);
3931 af.alignPanel.adjustAnnotationHeight();
3935 Hashtable skipList = null;
3938 * TODO remove this method
3941 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3942 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3943 * throw new Error("Implementation Error. No skipList defined for this
3944 * Jalview2XML instance."); } return (AlignFrame)
3945 * skipList.get(view.getSequenceSetId()); }
3949 * Check if the Jalview view contained in object should be skipped or not.
3952 * @return true if view's sequenceSetId is a key in skipList
3954 private boolean skipViewport(JalviewModel object)
3956 if (skipList == null)
3961 if (skipList.containsKey(id = object.getJalviewModelSequence()
3962 .getViewport()[0].getSequenceSetId()))
3964 if (Cache.log != null && Cache.log.isDebugEnabled())
3966 Cache.log.debug("Skipping seuqence set id " + id);
3973 public void AddToSkipList(AlignFrame af)
3975 if (skipList == null)
3977 skipList = new Hashtable();
3979 skipList.put(af.getViewport().getSequenceSetId(), af);
3982 public void clearSkipList()
3984 if (skipList != null)
3991 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
3992 boolean ignoreUnrefed)
3994 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3995 Vector dseqs = null;
3998 // create a list of new dataset sequences
3999 dseqs = new Vector();
4001 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4003 Sequence vamsasSeq = vamsasSet.getSequence(i);
4004 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4006 // create a new dataset
4009 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4010 dseqs.copyInto(dsseqs);
4011 ds = new jalview.datamodel.Alignment(dsseqs);
4012 debug("Created new dataset " + vamsasSet.getDatasetId()
4013 + " for alignment " + System.identityHashCode(al));
4014 addDatasetRef(vamsasSet.getDatasetId(), ds);
4016 // set the dataset for the newly imported alignment.
4017 if (al.getDataset() == null && !ignoreUnrefed)
4026 * sequence definition to create/merge dataset sequence for
4030 * vector to add new dataset sequence to
4032 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4033 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4035 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4037 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4038 .get(vamsasSeq.getId());
4039 jalview.datamodel.SequenceI dsq = null;
4040 if (sq != null && sq.getDatasetSequence() != null)
4042 dsq = sq.getDatasetSequence();
4044 if (sq == null && ignoreUnrefed)
4048 String sqid = vamsasSeq.getDsseqid();
4051 // need to create or add a new dataset sequence reference to this sequence
4054 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4059 // make a new dataset sequence
4060 dsq = sq.createDatasetSequence();
4063 // make up a new dataset reference for this sequence
4064 sqid = seqHash(dsq);
4066 dsq.setVamsasId(uniqueSetSuffix + sqid);
4067 seqRefIds.put(sqid, dsq);
4072 dseqs.addElement(dsq);
4077 ds.addSequence(dsq);
4083 { // make this dataset sequence sq's dataset sequence
4084 sq.setDatasetSequence(dsq);
4085 // and update the current dataset alignment
4090 if (!dseqs.contains(dsq))
4097 if (ds.findIndex(dsq) < 0)
4099 ds.addSequence(dsq);
4106 // TODO: refactor this as a merge dataset sequence function
4107 // now check that sq (the dataset sequence) sequence really is the union of
4108 // all references to it
4109 // boolean pre = sq.getStart() < dsq.getStart();
4110 // boolean post = sq.getEnd() > dsq.getEnd();
4114 StringBuffer sb = new StringBuffer();
4115 String newres = jalview.analysis.AlignSeq.extractGaps(
4116 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4117 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4118 && newres.length() > dsq.getLength())
4120 // Update with the longer sequence.
4124 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4125 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4126 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4127 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4129 dsq.setSequence(newres);
4131 // TODO: merges will never happen if we 'know' we have the real dataset
4132 // sequence - this should be detected when id==dssid
4134 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4135 // + (pre ? "prepended" : "") + " "
4136 // + (post ? "appended" : ""));
4141 java.util.Hashtable datasetIds = null;
4143 java.util.IdentityHashMap dataset2Ids = null;
4145 private Alignment getDatasetFor(String datasetId)
4147 if (datasetIds == null)
4149 datasetIds = new Hashtable();
4152 if (datasetIds.containsKey(datasetId))
4154 return (Alignment) datasetIds.get(datasetId);
4159 private void addDatasetRef(String datasetId, Alignment dataset)
4161 if (datasetIds == null)
4163 datasetIds = new Hashtable();
4165 datasetIds.put(datasetId, dataset);
4169 * make a new dataset ID for this jalview dataset alignment
4174 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4176 if (dataset.getDataset() != null)
4178 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4180 String datasetId = makeHashCode(dataset, null);
4181 if (datasetId == null)
4183 // make a new datasetId and record it
4184 if (dataset2Ids == null)
4186 dataset2Ids = new IdentityHashMap();
4190 datasetId = (String) dataset2Ids.get(dataset);
4192 if (datasetId == null)
4194 datasetId = "ds" + dataset2Ids.size() + 1;
4195 dataset2Ids.put(dataset, datasetId);
4201 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4203 for (int d = 0; d < sequence.getDBRefCount(); d++)
4205 DBRef dr = sequence.getDBRef(d);
4206 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4207 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4208 .getVersion(), sequence.getDBRef(d).getAccessionId());
4209 if (dr.getMapping() != null)
4211 entry.setMap(addMapping(dr.getMapping()));
4213 datasetSequence.addDBRef(entry);
4217 private jalview.datamodel.Mapping addMapping(Mapping m)
4219 SequenceI dsto = null;
4220 // Mapping m = dr.getMapping();
4221 int fr[] = new int[m.getMapListFromCount() * 2];
4222 Enumeration f = m.enumerateMapListFrom();
4223 for (int _i = 0; f.hasMoreElements(); _i += 2)
4225 MapListFrom mf = (MapListFrom) f.nextElement();
4226 fr[_i] = mf.getStart();
4227 fr[_i + 1] = mf.getEnd();
4229 int fto[] = new int[m.getMapListToCount() * 2];
4230 f = m.enumerateMapListTo();
4231 for (int _i = 0; f.hasMoreElements(); _i += 2)
4233 MapListTo mf = (MapListTo) f.nextElement();
4234 fto[_i] = mf.getStart();
4235 fto[_i + 1] = mf.getEnd();
4237 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4238 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4239 if (m.getMappingChoice() != null)
4241 MappingChoice mc = m.getMappingChoice();
4242 if (mc.getDseqFor() != null)
4244 String dsfor = "" + mc.getDseqFor();
4245 if (seqRefIds.containsKey(dsfor))
4250 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4254 frefedSequence.add(new Object[]
4261 * local sequence definition
4263 Sequence ms = mc.getSequence();
4264 jalview.datamodel.Sequence djs = null;
4265 String sqid = ms.getDsseqid();
4266 if (sqid != null && sqid.length() > 0)
4269 * recover dataset sequence
4271 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4276 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4277 sqid = ((Object) ms).toString(); // make up a new hascode for
4278 // undefined dataset sequence hash
4279 // (unlikely to happen)
4285 * make a new dataset sequence and add it to refIds hash
4287 djs = new jalview.datamodel.Sequence(ms.getName(),
4289 djs.setStart(jmap.getMap().getToLowest());
4290 djs.setEnd(jmap.getMap().getToHighest());
4291 djs.setVamsasId(uniqueSetSuffix + sqid);
4293 seqRefIds.put(sqid, djs);
4296 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4305 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4306 boolean keepSeqRefs)
4309 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4315 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4319 uniqueSetSuffix = "";
4320 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4325 if (this.frefedSequence == null)
4327 frefedSequence = new Vector();
4330 viewportsAdded = new Hashtable();
4332 AlignFrame af = LoadFromObject(jm, null, false, null);
4333 af.alignPanels.clear();
4334 af.closeMenuItem_actionPerformed(true);
4337 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4338 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4339 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4340 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4341 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4344 return af.alignPanel;
4348 * flag indicating if hashtables should be cleared on finalization TODO this
4349 * flag may not be necessary
4351 private final boolean _cleartables = true;
4353 private Hashtable jvids2vobj;
4358 * @see java.lang.Object#finalize()
4361 protected void finalize() throws Throwable
4363 // really make sure we have no buried refs left.
4368 this.seqRefIds = null;
4369 this.seqsToIds = null;
4373 private void warn(String msg)
4378 private void warn(String msg, Exception e)
4380 if (Cache.log != null)
4384 Cache.log.warn(msg, e);
4388 Cache.log.warn(msg);
4393 System.err.println("Warning: " + msg);
4396 e.printStackTrace();
4401 private void debug(String string)
4403 debug(string, null);
4406 private void debug(String msg, Exception e)
4408 if (Cache.log != null)
4412 Cache.log.debug(msg, e);
4416 Cache.log.debug(msg);
4421 System.err.println("Warning: " + msg);
4424 e.printStackTrace();
4430 * set the object to ID mapping tables used to write/recover objects and XML
4431 * ID strings for the jalview project. If external tables are provided then
4432 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4433 * object goes out of scope. - also populates the datasetIds hashtable with
4434 * alignment objects containing dataset sequences
4437 * Map from ID strings to jalview datamodel
4439 * Map from jalview datamodel to ID strings
4443 public void setObjectMappingTables(Hashtable vobj2jv,
4444 IdentityHashMap jv2vobj)
4446 this.jv2vobj = jv2vobj;
4447 this.vobj2jv = vobj2jv;
4448 Iterator ds = jv2vobj.keySet().iterator();
4450 while (ds.hasNext())
4452 Object jvobj = ds.next();
4453 id = jv2vobj.get(jvobj).toString();
4454 if (jvobj instanceof jalview.datamodel.Alignment)
4456 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4458 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4461 else if (jvobj instanceof jalview.datamodel.Sequence)
4463 // register sequence object so the XML parser can recover it.
4464 if (seqRefIds == null)
4466 seqRefIds = new Hashtable();
4468 if (seqsToIds == null)
4470 seqsToIds = new IdentityHashMap();
4472 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4473 seqsToIds.put(jvobj, id);
4475 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4477 if (annotationIds == null)
4479 annotationIds = new Hashtable();
4482 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4483 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4484 if (jvann.annotationId == null)
4486 jvann.annotationId = anid;
4488 if (!jvann.annotationId.equals(anid))
4490 // TODO verify that this is the correct behaviour
4491 this.warn("Overriding Annotation ID for " + anid
4492 + " from different id : " + jvann.annotationId);
4493 jvann.annotationId = anid;
4496 else if (jvobj instanceof String)
4498 if (jvids2vobj == null)
4500 jvids2vobj = new Hashtable();
4501 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4506 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4512 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4513 * objects created from the project archive. If string is null (default for
4514 * construction) then suffix will be set automatically.
4518 public void setUniqueSetSuffix(String string)
4520 uniqueSetSuffix = string;
4525 * uses skipList2 as the skipList for skipping views on sequence sets
4526 * associated with keys in the skipList
4530 public void setSkipList(Hashtable skipList2)
4532 skipList = skipList2;