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 = MessageManager.formatMessage("label.dataset_for", new String[]{fileName,_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.rightAlignIds);
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.featuresDisplayed != null)
1150 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1152 String[] renderOrder = ap.seqPanel.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.seqPanel.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.seqPanel.seqCanvas.getFeatureRenderer()
1180 .getColour(renderOrder[ro]).getRGB());
1183 setting.setDisplay(av.featuresDisplayed
1184 .containsKey(renderOrder[ro]));
1185 float rorder = ap.seqPanel.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.seqPanel.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.seqPanel.seqCanvas.getFeatureRenderer()
1210 .getColour(key).getRGB());
1212 setting.setDisplay(false);
1213 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1217 setting.setOrder(rorder);
1219 fs.addSetting(setting);
1220 settingsAdded.addElement(key);
1222 en = ap.seqPanel.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.seqPanel.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 != ' '
1460 && aa[i].annotations[a].secondaryStructure != '\0')
1462 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1466 if (aa[i].annotations[a].colour != null
1467 && aa[i].annotations[a].colour != java.awt.Color.black)
1469 ae.setColour(aa[i].annotations[a].colour.getRGB());
1472 an.addAnnotationElement(ae);
1473 if (aa[i].autoCalculated)
1475 // only write one non-null entry into the annotation row -
1476 // sufficient to get the visualization attributes necessary to
1484 an.setScoreOnly(true);
1486 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1488 // skip autocalculated annotation - these are only provided for
1490 vamsasSet.addAnnotation(an);
1496 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1498 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1499 if (settings != null)
1501 CalcIdParam vCalcIdParam = new CalcIdParam();
1502 vCalcIdParam.setCalcId(calcId);
1503 vCalcIdParam.addServiceURL(settings.getServiceURI());
1504 // generic URI allowing a third party to resolve another instance of the
1505 // service used for this calculation
1506 for (String urls : settings.getServiceURLs())
1508 vCalcIdParam.addServiceURL(urls);
1510 vCalcIdParam.setVersion("1.0");
1511 if (settings.getPreset() != null)
1513 WsParamSetI setting = settings.getPreset();
1514 vCalcIdParam.setName(setting.getName());
1515 vCalcIdParam.setDescription(setting.getDescription());
1519 vCalcIdParam.setName("");
1520 vCalcIdParam.setDescription("Last used parameters");
1522 // need to be able to recover 1) settings 2) user-defined presets or
1523 // recreate settings from preset 3) predefined settings provided by
1524 // service - or settings that can be transferred (or discarded)
1525 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1527 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1528 // todo - decide if updateImmediately is needed for any projects.
1530 return vCalcIdParam;
1535 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1538 if (calcIdParam.getVersion().equals("1.0"))
1540 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1541 .getPreferredServiceFor(calcIdParam.getServiceURL());
1542 if (service != null)
1544 WsParamSetI parmSet = null;
1547 parmSet = service.getParamStore().parseServiceParameterFile(
1548 calcIdParam.getName(), calcIdParam.getDescription(),
1549 calcIdParam.getServiceURL(),
1550 calcIdParam.getParameters().replace("|\\n|", "\n"));
1551 } catch (IOException x)
1553 warn("Couldn't parse parameter data for "
1554 + calcIdParam.getCalcId(), x);
1557 List<ArgumentI> argList = null;
1558 if (calcIdParam.getName().length() > 0)
1560 parmSet = service.getParamStore()
1561 .getPreset(calcIdParam.getName());
1562 if (parmSet != null)
1564 // TODO : check we have a good match with settings in AACon -
1565 // otherwise we'll need to create a new preset
1570 argList = parmSet.getArguments();
1573 AAConSettings settings = new AAConSettings(
1574 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1575 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1576 calcIdParam.isNeedsUpdate());
1581 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1585 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1589 * External mapping between jalview objects and objects yielding a valid and
1590 * unique object ID string. This is null for normal Jalview project IO, but
1591 * non-null when a jalview project is being read or written as part of a
1594 IdentityHashMap jv2vobj = null;
1597 * Construct a unique ID for jvobj using either existing bindings or if none
1598 * exist, the result of the hashcode call for the object.
1601 * jalview data object
1602 * @return unique ID for referring to jvobj
1604 private String makeHashCode(Object jvobj, String altCode)
1606 if (jv2vobj != null)
1608 Object id = jv2vobj.get(jvobj);
1611 return id.toString();
1613 // check string ID mappings
1614 if (jvids2vobj != null && jvobj instanceof String)
1616 id = jvids2vobj.get(jvobj);
1620 return id.toString();
1622 // give up and warn that something has gone wrong
1623 warn("Cannot find ID for object in external mapping : " + jvobj);
1629 * return local jalview object mapped to ID, if it exists
1633 * @return null or object bound to idcode
1635 private Object retrieveExistingObj(String idcode)
1637 if (idcode != null && vobj2jv != null)
1639 return vobj2jv.get(idcode);
1645 * binding from ID strings from external mapping table to jalview data model
1648 private Hashtable vobj2jv;
1650 private Sequence createVamsasSequence(String id, SequenceI jds)
1652 return createVamsasSequence(true, id, jds, null);
1655 private Sequence createVamsasSequence(boolean recurse, String id,
1656 SequenceI jds, SequenceI parentseq)
1658 Sequence vamsasSeq = new Sequence();
1659 vamsasSeq.setId(id);
1660 vamsasSeq.setName(jds.getName());
1661 vamsasSeq.setSequence(jds.getSequenceAsString());
1662 vamsasSeq.setDescription(jds.getDescription());
1663 jalview.datamodel.DBRefEntry[] dbrefs = null;
1664 if (jds.getDatasetSequence() != null)
1666 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1667 if (jds.getDatasetSequence().getDBRef() != null)
1669 dbrefs = jds.getDatasetSequence().getDBRef();
1674 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1675 // dataset sequences only
1676 dbrefs = jds.getDBRef();
1680 for (int d = 0; d < dbrefs.length; d++)
1682 DBRef dbref = new DBRef();
1683 dbref.setSource(dbrefs[d].getSource());
1684 dbref.setVersion(dbrefs[d].getVersion());
1685 dbref.setAccessionId(dbrefs[d].getAccessionId());
1686 if (dbrefs[d].hasMap())
1688 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1690 dbref.setMapping(mp);
1692 vamsasSeq.addDBRef(dbref);
1698 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1699 SequenceI parentseq, SequenceI jds, boolean recurse)
1702 if (jmp.getMap() != null)
1706 jalview.util.MapList mlst = jmp.getMap();
1707 int r[] = mlst.getFromRanges();
1708 for (int s = 0; s < r.length; s += 2)
1710 MapListFrom mfrom = new MapListFrom();
1711 mfrom.setStart(r[s]);
1712 mfrom.setEnd(r[s + 1]);
1713 mp.addMapListFrom(mfrom);
1715 r = mlst.getToRanges();
1716 for (int s = 0; s < r.length; s += 2)
1718 MapListTo mto = new MapListTo();
1720 mto.setEnd(r[s + 1]);
1721 mp.addMapListTo(mto);
1723 mp.setMapFromUnit(mlst.getFromRatio());
1724 mp.setMapToUnit(mlst.getToRatio());
1725 if (jmp.getTo() != null)
1727 MappingChoice mpc = new MappingChoice();
1729 && (parentseq != jmp.getTo() || parentseq
1730 .getDatasetSequence() != jmp.getTo()))
1732 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1738 SequenceI ps = null;
1739 if (parentseq != jmp.getTo()
1740 && parentseq.getDatasetSequence() != jmp.getTo())
1742 // chaining dbref rather than a handshaking one
1743 jmpid = seqHash(ps = jmp.getTo());
1747 jmpid = seqHash(ps = parentseq);
1749 mpc.setDseqFor(jmpid);
1750 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1752 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1753 seqRefIds.put(mpc.getDseqFor(), ps);
1757 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1760 mp.setMappingChoice(mpc);
1766 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1767 Vector userColours, JalviewModelSequence jms)
1770 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1771 boolean newucs = false;
1772 if (!userColours.contains(ucs))
1774 userColours.add(ucs);
1777 id = "ucs" + userColours.indexOf(ucs);
1780 // actually create the scheme's entry in the XML model
1781 java.awt.Color[] colours = ucs.getColours();
1782 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1783 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1785 for (int i = 0; i < colours.length; i++)
1787 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1788 col.setName(ResidueProperties.aa[i]);
1789 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1790 jbucs.addColour(col);
1792 if (ucs.getLowerCaseColours() != null)
1794 colours = ucs.getLowerCaseColours();
1795 for (int i = 0; i < colours.length; i++)
1797 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1798 col.setName(ResidueProperties.aa[i].toLowerCase());
1799 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1800 jbucs.addColour(col);
1805 uc.setUserColourScheme(jbucs);
1806 jms.addUserColours(uc);
1812 jalview.schemes.UserColourScheme GetUserColourScheme(
1813 JalviewModelSequence jms, String id)
1815 UserColours[] uc = jms.getUserColours();
1816 UserColours colours = null;
1818 for (int i = 0; i < uc.length; i++)
1820 if (uc[i].getId().equals(id))
1828 java.awt.Color[] newColours = new java.awt.Color[24];
1830 for (int i = 0; i < 24; i++)
1832 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1833 .getUserColourScheme().getColour(i).getRGB(), 16));
1836 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1839 if (colours.getUserColourScheme().getColourCount() > 24)
1841 newColours = new java.awt.Color[23];
1842 for (int i = 0; i < 23; i++)
1844 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1845 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1847 ucs.setLowerCaseColours(newColours);
1854 * contains last error message (if any) encountered by XML loader.
1856 String errorMessage = null;
1859 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1860 * exceptions are raised during project XML parsing
1862 public boolean attemptversion1parse = true;
1865 * Load a jalview project archive from a jar file
1868 * - HTTP URL or filename
1870 public AlignFrame LoadJalviewAlign(final String file)
1873 jalview.gui.AlignFrame af = null;
1877 // create list to store references for any new Jmol viewers created
1878 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1879 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1880 // Workaround is to make sure caller implements the JarInputStreamProvider
1882 // so we can re-open the jar input stream for each entry.
1884 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1885 af = LoadJalviewAlign(jprovider);
1887 } catch (MalformedURLException e)
1889 errorMessage = "Invalid URL format for '" + file + "'";
1895 SwingUtilities.invokeAndWait(new Runnable()
1899 setLoadingFinishedForNewStructureViewers();
1902 } catch (Exception x)
1910 private jarInputStreamProvider createjarInputStreamProvider(
1911 final String file) throws MalformedURLException
1914 errorMessage = null;
1915 uniqueSetSuffix = null;
1917 viewportsAdded = null;
1918 frefedSequence = null;
1920 if (file.startsWith("http://"))
1922 url = new URL(file);
1924 final URL _url = url;
1925 return new jarInputStreamProvider()
1929 public JarInputStream getJarInputStream() throws IOException
1933 return new JarInputStream(_url.openStream());
1937 return new JarInputStream(new FileInputStream(file));
1942 public String getFilename()
1950 * Recover jalview session from a jalview project archive. Caller may
1951 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1952 * themselves. Any null fields will be initialised with default values,
1953 * non-null fields are left alone.
1958 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1960 errorMessage = null;
1961 if (uniqueSetSuffix == null)
1963 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1965 if (seqRefIds == null)
1967 seqRefIds = new Hashtable();
1969 if (viewportsAdded == null)
1971 viewportsAdded = new Hashtable();
1973 if (frefedSequence == null)
1975 frefedSequence = new Vector();
1978 jalview.gui.AlignFrame af = null, _af = null;
1979 Hashtable gatherToThisFrame = new Hashtable();
1980 final String file = jprovider.getFilename();
1983 JarInputStream jin = null;
1984 JarEntry jarentry = null;
1989 jin = jprovider.getJarInputStream();
1990 for (int i = 0; i < entryCount; i++)
1992 jarentry = jin.getNextJarEntry();
1995 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1997 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1998 JalviewModel object = new JalviewModel();
2000 Unmarshaller unmar = new Unmarshaller(object);
2001 unmar.setValidation(false);
2002 object = (JalviewModel) unmar.unmarshal(in);
2003 if (true) // !skipViewport(object))
2005 _af = LoadFromObject(object, file, true, jprovider);
2006 if (object.getJalviewModelSequence().getViewportCount() > 0)
2009 if (af.viewport.gatherViewsHere)
2011 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2017 else if (jarentry != null)
2019 // Some other file here.
2022 } while (jarentry != null);
2023 resolveFrefedSequences();
2024 } catch (java.io.FileNotFoundException ex)
2026 ex.printStackTrace();
2027 errorMessage = "Couldn't locate Jalview XML file : " + file;
2028 System.err.println("Exception whilst loading jalview XML file : "
2030 } catch (java.net.UnknownHostException ex)
2032 ex.printStackTrace();
2033 errorMessage = "Couldn't locate Jalview XML file : " + file;
2034 System.err.println("Exception whilst loading jalview XML file : "
2036 } catch (Exception ex)
2038 System.err.println("Parsing as Jalview Version 2 file failed.");
2039 ex.printStackTrace(System.err);
2040 if (attemptversion1parse)
2042 // Is Version 1 Jar file?
2045 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2046 } catch (Exception ex2)
2048 System.err.println("Exception whilst loading as jalviewXMLV1:");
2049 ex2.printStackTrace();
2053 if (Desktop.instance != null)
2055 Desktop.instance.stopLoading();
2059 System.out.println("Successfully loaded archive file");
2062 ex.printStackTrace();
2064 System.err.println("Exception whilst loading jalview XML file : "
2066 } catch (OutOfMemoryError e)
2068 // Don't use the OOM Window here
2069 errorMessage = "Out of memory loading jalview XML file";
2070 System.err.println("Out of memory whilst loading jalview XML file");
2071 e.printStackTrace();
2074 if (Desktop.instance != null)
2076 Desktop.instance.stopLoading();
2079 Enumeration en = gatherToThisFrame.elements();
2080 while (en.hasMoreElements())
2082 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2084 if (errorMessage != null)
2092 * check errorMessage for a valid error message and raise an error box in the
2093 * GUI or write the current errorMessage to stderr and then clear the error
2096 protected void reportErrors()
2098 reportErrors(false);
2101 protected void reportErrors(final boolean saving)
2103 if (errorMessage != null)
2105 final String finalErrorMessage = errorMessage;
2108 javax.swing.SwingUtilities.invokeLater(new Runnable()
2113 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2114 finalErrorMessage, "Error "
2115 + (saving ? "saving" : "loading")
2116 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2122 System.err.println("Problem loading Jalview file: " + errorMessage);
2125 errorMessage = null;
2128 Hashtable<String, String> alreadyLoadedPDB;
2131 * when set, local views will be updated from view stored in JalviewXML
2132 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2133 * sync if this is set to true.
2135 private final boolean updateLocalViews = false;
2137 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2139 if (alreadyLoadedPDB == null)
2141 alreadyLoadedPDB = new Hashtable();
2144 if (alreadyLoadedPDB.containsKey(pdbId))
2146 return alreadyLoadedPDB.get(pdbId).toString();
2151 JarInputStream jin = jprovider.getJarInputStream();
2153 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2154 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2155 * FileInputStream(jprovider)); }
2158 JarEntry entry = null;
2161 entry = jin.getNextJarEntry();
2162 } while (entry != null && !entry.getName().equals(pdbId));
2165 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2166 File outFile = File.createTempFile("jalview_pdb", ".txt");
2167 outFile.deleteOnExit();
2168 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2171 while ((data = in.readLine()) != null)
2178 } catch (Exception foo)
2183 String t = outFile.getAbsolutePath();
2184 alreadyLoadedPDB.put(pdbId, t);
2189 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2191 } catch (Exception ex)
2193 ex.printStackTrace();
2199 private class JvAnnotRow
2201 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2208 * persisted version of annotation row from which to take vis properties
2210 public jalview.datamodel.AlignmentAnnotation template;
2213 * original position of the annotation row in the alignment
2219 * Load alignment frame from jalview XML DOM object
2224 * filename source string
2225 * @param loadTreesAndStructures
2226 * when false only create Viewport
2228 * data source provider
2229 * @return alignment frame created from view stored in DOM
2231 AlignFrame LoadFromObject(JalviewModel object, String file,
2232 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2234 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2235 Sequence[] vamsasSeq = vamsasSet.getSequence();
2237 JalviewModelSequence jms = object.getJalviewModelSequence();
2239 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2242 // ////////////////////////////////
2245 Vector hiddenSeqs = null;
2246 jalview.datamodel.Sequence jseq;
2248 ArrayList tmpseqs = new ArrayList();
2250 boolean multipleView = false;
2252 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2253 int vi = 0; // counter in vamsasSeq array
2254 for (int i = 0; i < JSEQ.length; i++)
2256 String seqId = JSEQ[i].getId();
2258 if (seqRefIds.get(seqId) != null)
2260 tmpseqs.add(seqRefIds.get(seqId));
2261 multipleView = true;
2265 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2266 vamsasSeq[vi].getSequence());
2267 jseq.setDescription(vamsasSeq[vi].getDescription());
2268 jseq.setStart(JSEQ[i].getStart());
2269 jseq.setEnd(JSEQ[i].getEnd());
2270 jseq.setVamsasId(uniqueSetSuffix + seqId);
2271 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2276 if (JSEQ[i].getHidden())
2278 if (hiddenSeqs == null)
2280 hiddenSeqs = new Vector();
2283 hiddenSeqs.addElement(seqRefIds.get(seqId));
2289 // Create the alignment object from the sequence set
2290 // ///////////////////////////////
2291 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2294 tmpseqs.toArray(orderedSeqs);
2296 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2299 // / Add the alignment properties
2300 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2302 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2303 al.setProperty(ssp.getKey(), ssp.getValue());
2307 // SequenceFeatures are added to the DatasetSequence,
2308 // so we must create or recover the dataset before loading features
2309 // ///////////////////////////////
2310 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2312 // older jalview projects do not have a dataset id.
2313 al.setDataset(null);
2317 recoverDatasetFor(vamsasSet, al);
2319 // ///////////////////////////////
2321 Hashtable pdbloaded = new Hashtable();
2324 // load sequence features, database references and any associated PDB
2325 // structures for the alignment
2326 for (int i = 0; i < vamsasSeq.length; i++)
2328 if (JSEQ[i].getFeaturesCount() > 0)
2330 Features[] features = JSEQ[i].getFeatures();
2331 for (int f = 0; f < features.length; f++)
2333 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2334 features[f].getType(), features[f].getDescription(),
2335 features[f].getStatus(), features[f].getBegin(),
2336 features[f].getEnd(), features[f].getFeatureGroup());
2338 sf.setScore(features[f].getScore());
2339 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2341 OtherData keyValue = features[f].getOtherData(od);
2342 if (keyValue.getKey().startsWith("LINK"))
2344 sf.addLink(keyValue.getValue());
2348 sf.setValue(keyValue.getKey(), keyValue.getValue());
2353 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2356 if (vamsasSeq[i].getDBRefCount() > 0)
2358 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2360 if (JSEQ[i].getPdbidsCount() > 0)
2362 Pdbids[] ids = JSEQ[i].getPdbids();
2363 for (int p = 0; p < ids.length; p++)
2365 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2366 entry.setId(ids[p].getId());
2367 entry.setType(ids[p].getType());
2368 if (ids[p].getFile() != null)
2370 if (!pdbloaded.containsKey(ids[p].getFile()))
2372 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2376 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2379 StructureSelectionManager.getStructureSelectionManager(
2381 .registerPDBEntry(entry);
2382 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2386 } // end !multipleview
2388 // ///////////////////////////////
2389 // LOAD SEQUENCE MAPPINGS
2391 if (vamsasSet.getAlcodonFrameCount() > 0)
2393 // TODO Potentially this should only be done once for all views of an
2395 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2396 for (int i = 0; i < alc.length; i++)
2398 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2399 alc[i].getAlcodonCount());
2400 if (alc[i].getAlcodonCount() > 0)
2402 Alcodon[] alcods = alc[i].getAlcodon();
2403 for (int p = 0; p < cf.codons.length; p++)
2405 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2406 && alcods[p].hasPos3())
2408 // translated codons require three valid positions
2409 cf.codons[p] = new int[3];
2410 cf.codons[p][0] = (int) alcods[p].getPos1();
2411 cf.codons[p][1] = (int) alcods[p].getPos2();
2412 cf.codons[p][2] = (int) alcods[p].getPos3();
2416 cf.codons[p] = null;
2420 if (alc[i].getAlcodMapCount() > 0)
2422 AlcodMap[] maps = alc[i].getAlcodMap();
2423 for (int m = 0; m < maps.length; m++)
2425 SequenceI dnaseq = (SequenceI) seqRefIds
2426 .get(maps[m].getDnasq());
2428 jalview.datamodel.Mapping mapping = null;
2429 // attach to dna sequence reference.
2430 if (maps[m].getMapping() != null)
2432 mapping = addMapping(maps[m].getMapping());
2436 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2441 frefedSequence.add(new Object[]
2442 { maps[m].getDnasq(), cf, mapping });
2446 al.addCodonFrame(cf);
2451 // ////////////////////////////////
2453 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2455 * store any annotations which forward reference a group's ID
2457 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2459 if (vamsasSet.getAnnotationCount() > 0)
2461 Annotation[] an = vamsasSet.getAnnotation();
2463 for (int i = 0; i < an.length; i++)
2466 * test if annotation is automatically calculated for this view only
2468 boolean autoForView = false;
2469 if (an[i].getLabel().equals("Quality")
2470 || an[i].getLabel().equals("Conservation")
2471 || an[i].getLabel().equals("Consensus"))
2473 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2475 if (!an[i].hasAutoCalculated())
2477 an[i].setAutoCalculated(true);
2481 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2483 // remove ID - we don't recover annotation from other views for
2484 // view-specific annotation
2488 // set visiblity for other annotation in this view
2489 if (an[i].getId() != null
2490 && annotationIds.containsKey(an[i].getId()))
2492 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2493 .get(an[i].getId());
2494 // in principle Visible should always be true for annotation displayed
2495 // in multiple views
2496 if (an[i].hasVisible())
2498 jda.visible = an[i].getVisible();
2501 al.addAnnotation(jda);
2505 // Construct new annotation from model.
2506 AnnotationElement[] ae = an[i].getAnnotationElement();
2507 jalview.datamodel.Annotation[] anot = null;
2508 java.awt.Color firstColour = null;
2510 if (!an[i].getScoreOnly())
2512 anot = new jalview.datamodel.Annotation[al.getWidth()];
2513 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2515 anpos = ae[aa].getPosition();
2517 if (anpos >= anot.length)
2522 anot[anpos] = new jalview.datamodel.Annotation(
2524 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2525 (ae[aa].getSecondaryStructure() == null || ae[aa]
2526 .getSecondaryStructure().length() == 0) ? ' '
2527 : ae[aa].getSecondaryStructure().charAt(0),
2531 // JBPNote: Consider verifying dataflow for IO of secondary
2532 // structure annotation read from Stockholm files
2533 // this was added to try to ensure that
2534 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2536 // anot[ae[aa].getPosition()].displayCharacter = "";
2538 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2539 if (firstColour == null)
2541 firstColour = anot[anpos].colour;
2545 jalview.datamodel.AlignmentAnnotation jaa = null;
2547 if (an[i].getGraph())
2549 float llim = 0, hlim = 0;
2550 // if (autoForView || an[i].isAutoCalculated()) {
2553 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2554 an[i].getDescription(), anot, llim, hlim,
2555 an[i].getGraphType());
2557 jaa.graphGroup = an[i].getGraphGroup();
2558 jaa._linecolour = firstColour;
2559 if (an[i].getThresholdLine() != null)
2561 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2562 .getThresholdLine().getValue(), an[i]
2563 .getThresholdLine().getLabel(), new java.awt.Color(
2564 an[i].getThresholdLine().getColour())));
2567 if (autoForView || an[i].isAutoCalculated())
2569 // Hardwire the symbol display line to ensure that labels for
2570 // histograms are displayed
2576 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2577 an[i].getDescription(), anot);
2578 jaa._linecolour = firstColour;
2580 // register new annotation
2581 if (an[i].getId() != null)
2583 annotationIds.put(an[i].getId(), jaa);
2584 jaa.annotationId = an[i].getId();
2586 // recover sequence association
2587 if (an[i].getSequenceRef() != null)
2589 if (al.findName(an[i].getSequenceRef()) != null)
2591 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2593 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2596 // and make a note of any group association
2597 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2599 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2600 .get(an[i].getGroupRef());
2603 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2604 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2609 if (an[i].hasScore())
2611 jaa.setScore(an[i].getScore());
2613 if (an[i].hasVisible())
2615 jaa.visible = an[i].getVisible();
2618 if (an[i].hasCentreColLabels())
2620 jaa.centreColLabels = an[i].getCentreColLabels();
2623 if (an[i].hasScaleColLabels())
2625 jaa.scaleColLabel = an[i].getScaleColLabels();
2627 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2629 // newer files have an 'autoCalculated' flag and store calculation
2630 // state in viewport properties
2631 jaa.autoCalculated = true; // means annotation will be marked for
2632 // update at end of load.
2634 if (an[i].hasGraphHeight())
2636 jaa.graphHeight = an[i].getGraphHeight();
2638 if (an[i].hasBelowAlignment())
2640 jaa.belowAlignment = an[i].isBelowAlignment();
2642 jaa.setCalcId(an[i].getCalcId());
2643 if (an[i].getPropertyCount() > 0)
2645 for (jalview.schemabinding.version2.Property prop : an[i]
2648 jaa.setProperty(prop.getName(), prop.getValue());
2651 if (jaa.autoCalculated)
2653 autoAlan.add(new JvAnnotRow(i, jaa));
2656 // if (!autoForView)
2658 // add autocalculated group annotation and any user created annotation
2660 al.addAnnotation(jaa);
2664 // ///////////////////////
2666 // Create alignment markup and styles for this view
2667 if (jms.getJGroupCount() > 0)
2669 JGroup[] groups = jms.getJGroup();
2670 boolean addAnnotSchemeGroup = false;
2671 for (int i = 0; i < groups.length; i++)
2673 ColourSchemeI cs = null;
2675 if (groups[i].getColour() != null)
2677 if (groups[i].getColour().startsWith("ucs"))
2679 cs = GetUserColourScheme(jms, groups[i].getColour());
2681 else if (groups[i].getColour().equals("AnnotationColourGradient")
2682 && groups[i].getAnnotationColours() != null)
2684 addAnnotSchemeGroup = true;
2689 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2694 cs.setThreshold(groups[i].getPidThreshold(), true);
2698 Vector seqs = new Vector();
2700 for (int s = 0; s < groups[i].getSeqCount(); s++)
2702 String seqId = groups[i].getSeq(s) + "";
2703 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2708 seqs.addElement(ts);
2712 if (seqs.size() < 1)
2717 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2718 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2719 groups[i].getDisplayText(), groups[i].getColourText(),
2720 groups[i].getStart(), groups[i].getEnd());
2722 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2724 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2725 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2726 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2727 .isShowUnconserved() : false);
2728 sg.thresholdTextColour = groups[i].getTextColThreshold();
2729 if (groups[i].hasShowConsensusHistogram())
2731 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2734 if (groups[i].hasShowSequenceLogo())
2736 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2738 if (groups[i].hasNormaliseSequenceLogo())
2740 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2742 if (groups[i].hasIgnoreGapsinConsensus())
2744 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2746 if (groups[i].getConsThreshold() != 0)
2748 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2749 "All", ResidueProperties.propHash, 3,
2750 sg.getSequences(null), 0, sg.getWidth() - 1);
2752 c.verdict(false, 25);
2753 sg.cs.setConservation(c);
2756 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2758 // re-instate unique group/annotation row reference
2759 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2760 .get(groups[i].getId());
2763 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2766 if (jaa.autoCalculated)
2768 // match up and try to set group autocalc alignment row for this
2770 if (jaa.label.startsWith("Consensus for "))
2772 sg.setConsensus(jaa);
2774 // match up and try to set group autocalc alignment row for this
2776 if (jaa.label.startsWith("Conservation for "))
2778 sg.setConservationRow(jaa);
2785 if (addAnnotSchemeGroup)
2787 // reconstruct the annotation colourscheme
2788 sg.cs = constructAnnotationColour(
2789 groups[i].getAnnotationColours(), null, al, jms, false);
2795 // only dataset in this model, so just return.
2798 // ///////////////////////////////
2801 // If we just load in the same jar file again, the sequenceSetId
2802 // will be the same, and we end up with multiple references
2803 // to the same sequenceSet. We must modify this id on load
2804 // so that each load of the file gives a unique id
2805 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2806 String viewId = (view.getId() == null ? null : view.getId()
2808 AlignFrame af = null;
2809 AlignViewport av = null;
2810 // now check to see if we really need to create a new viewport.
2811 if (multipleView && viewportsAdded.size() == 0)
2813 // We recovered an alignment for which a viewport already exists.
2814 // TODO: fix up any settings necessary for overlaying stored state onto
2815 // state recovered from another document. (may not be necessary).
2816 // we may need a binding from a viewport in memory to one recovered from
2818 // and then recover its containing af to allow the settings to be applied.
2819 // TODO: fix for vamsas demo
2821 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2823 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2824 if (seqsetobj != null)
2826 if (seqsetobj instanceof String)
2828 uniqueSeqSetId = (String) seqsetobj;
2830 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2836 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2842 * indicate that annotation colours are applied across all groups (pre
2843 * Jalview 2.8.1 behaviour)
2845 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2846 object.getVersion());
2848 AlignmentPanel ap = null;
2849 boolean isnewview = true;
2852 // Check to see if this alignment already has a view id == viewId
2853 jalview.gui.AlignmentPanel views[] = Desktop
2854 .getAlignmentPanels(uniqueSeqSetId);
2855 if (views != null && views.length > 0)
2857 for (int v = 0; v < views.length; v++)
2859 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2861 // recover the existing alignpanel, alignframe, viewport
2862 af = views[v].alignFrame;
2865 // TODO: could even skip resetting view settings if we don't want to
2866 // change the local settings from other jalview processes
2875 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2876 uniqueSeqSetId, viewId, autoAlan);
2881 // /////////////////////////////////////
2882 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2886 for (int t = 0; t < jms.getTreeCount(); t++)
2889 Tree tree = jms.getTree(t);
2891 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2894 tp = af.ShowNewickTree(
2895 new jalview.io.NewickFile(tree.getNewick()),
2896 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2897 tree.getXpos(), tree.getYpos());
2898 if (tree.getId() != null)
2900 // perhaps bind the tree id to something ?
2905 // update local tree attributes ?
2906 // TODO: should check if tp has been manipulated by user - if so its
2907 // settings shouldn't be modified
2908 tp.setTitle(tree.getTitle());
2909 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2910 .getWidth(), tree.getHeight()));
2911 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2914 tp.treeCanvas.av = av; // af.viewport;
2915 tp.treeCanvas.ap = ap; // af.alignPanel;
2920 warn("There was a problem recovering stored Newick tree: \n"
2921 + tree.getNewick());
2925 tp.fitToWindow.setState(tree.getFitToWindow());
2926 tp.fitToWindow_actionPerformed(null);
2928 if (tree.getFontName() != null)
2930 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2931 .getFontStyle(), tree.getFontSize()));
2935 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2936 .getFontStyle(), tree.getFontSize()));
2939 tp.showPlaceholders(tree.getMarkUnlinked());
2940 tp.showBootstrap(tree.getShowBootstrap());
2941 tp.showDistances(tree.getShowDistances());
2943 tp.treeCanvas.threshold = tree.getThreshold();
2945 if (tree.getCurrentTree())
2947 af.viewport.setCurrentTree(tp.getTree());
2951 } catch (Exception ex)
2953 ex.printStackTrace();
2957 // //LOAD STRUCTURES
2958 if (loadTreesAndStructures)
2960 // run through all PDB ids on the alignment, and collect mappings between
2961 // jmol view ids and all sequences referring to it
2962 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2964 for (int i = 0; i < JSEQ.length; i++)
2966 if (JSEQ[i].getPdbidsCount() > 0)
2968 Pdbids[] ids = JSEQ[i].getPdbids();
2969 for (int p = 0; p < ids.length; p++)
2971 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2973 // check to see if we haven't already created this structure view
2974 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2975 : ids[p].getStructureState(s).getViewId()
2977 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2978 // Originally : ids[p].getFile()
2979 // : TODO: verify external PDB file recovery still works in normal
2980 // jalview project load
2981 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2982 jpdb.setId(ids[p].getId());
2984 int x = ids[p].getStructureState(s).getXpos();
2985 int y = ids[p].getStructureState(s).getYpos();
2986 int width = ids[p].getStructureState(s).getWidth();
2987 int height = ids[p].getStructureState(s).getHeight();
2989 // Probably don't need to do this anymore...
2990 // Desktop.desktop.getComponentAt(x, y);
2991 // TODO: NOW: check that this recovers the PDB file correctly.
2992 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2993 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2994 .get(JSEQ[i].getId() + "");
2995 if (sviewid == null)
2997 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3000 if (!jmolViewIds.containsKey(sviewid))
3002 jmolViewIds.put(sviewid, new Object[]
3004 { x, y, width, height }, "",
3005 new Hashtable<String, Object[]>(), new boolean[]
3006 { false, false, true } });
3007 // Legacy pre-2.7 conversion JAL-823 :
3008 // do not assume any view has to be linked for colour by
3012 // assemble String[] { pdb files }, String[] { id for each
3013 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3014 // seqs_file 2}, boolean[] {
3015 // linkAlignPanel,superposeWithAlignpanel}} from hash
3016 Object[] jmoldat = jmolViewIds.get(sviewid);
3017 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
3018 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
3019 s).getAlignwithAlignPanel() : false;
3020 // never colour by linked panel if not specified
3021 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
3022 .hasColourwithAlignPanel() ? ids[p]
3023 .getStructureState(s).getColourwithAlignPanel()
3025 // default for pre-2.7 projects is that Jmol colouring is enabled
3026 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
3027 .hasColourByJmol() ? ids[p].getStructureState(s)
3028 .getColourByJmol() : true;
3030 if (((String) jmoldat[1]).length() < ids[p]
3031 .getStructureState(s).getContent().length())
3034 jmoldat[1] = ids[p].getStructureState(s).getContent();
3037 if (ids[p].getFile() != null)
3039 File mapkey = new File(ids[p].getFile());
3040 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3042 if (seqstrmaps == null)
3044 ((Hashtable) jmoldat[2]).put(mapkey,
3045 seqstrmaps = new Object[]
3046 { pdbFile, ids[p].getId(), new Vector(),
3049 if (!((Vector) seqstrmaps[2]).contains(seq))
3051 ((Vector) seqstrmaps[2]).addElement(seq);
3052 // ((Vector)seqstrmaps[3]).addElement(n) :
3053 // in principle, chains
3054 // should be stored here : do we need to
3055 // TODO: store and recover seq/pdb_id :
3061 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");
3070 // Instantiate the associated Jmol views
3071 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3073 String sviewid = entry.getKey();
3074 Object[] svattrib = entry.getValue();
3075 int[] geom = (int[]) svattrib[0];
3076 String state = (String) svattrib[1];
3077 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3078 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3079 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3080 // collate the pdbfile -> sequence mappings from this view
3081 Vector<String> pdbfilenames = new Vector<String>();
3082 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3083 Vector<String> pdbids = new Vector<String>();
3085 // Search to see if we've already created this Jmol view
3086 AppJmol comp = null;
3087 JInternalFrame[] frames = null;
3092 frames = Desktop.desktop.getAllFrames();
3093 } catch (ArrayIndexOutOfBoundsException e)
3095 // occasional No such child exceptions are thrown here...
3100 } catch (Exception f)
3105 } while (frames == null);
3106 // search for any Jmol windows already open from other
3107 // alignment views that exactly match the stored structure state
3108 for (int f = 0; comp == null && f < frames.length; f++)
3110 if (frames[f] instanceof AppJmol)
3113 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3115 // post jalview 2.4 schema includes structure view id
3116 comp = (AppJmol) frames[f];
3118 else if (frames[f].getX() == x && frames[f].getY() == y
3119 && frames[f].getHeight() == height
3120 && frames[f].getWidth() == width)
3122 comp = (AppJmol) frames[f];
3129 // create a new Jmol window.
3130 // First parse the Jmol state to translate filenames loaded into the
3131 // view, and record the order in which files are shown in the Jmol
3132 // view, so we can add the sequence mappings in same order.
3133 StringBuffer newFileLoc = null;
3134 int cp = 0, ncp, ecp;
3135 while ((ncp = state.indexOf("load ", cp)) > -1)
3137 if (newFileLoc == null)
3139 newFileLoc = new StringBuffer();
3143 // look for next filename in load statement
3144 newFileLoc.append(state.substring(cp,
3145 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3146 String oldfilenam = state.substring(ncp,
3147 ecp = state.indexOf("\"", ncp));
3148 // recover the new mapping data for this old filename
3149 // have to normalize filename - since Jmol and jalview do
3151 // translation differently.
3152 Object[] filedat = oldFiles.get(new File(oldfilenam));
3153 newFileLoc.append(Platform
3154 .escapeString((String) filedat[0]));
3155 pdbfilenames.addElement((String) filedat[0]);
3156 pdbids.addElement((String) filedat[1]);
3157 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3158 .toArray(new SequenceI[0]));
3159 newFileLoc.append("\"");
3160 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3161 // look for next file statement.
3162 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3166 // just append rest of state
3167 newFileLoc.append(state.substring(cp));
3172 .print("Ignoring incomplete Jmol state for PDB ids: ");
3173 newFileLoc = new StringBuffer(state);
3174 newFileLoc.append("; load append ");
3175 for (File id : oldFiles.keySet())
3177 // add this and any other pdb files that should be present in
3179 Object[] filedat = oldFiles.get(id);
3181 newFileLoc.append(((String) filedat[0]));
3182 pdbfilenames.addElement((String) filedat[0]);
3183 pdbids.addElement((String) filedat[1]);
3184 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3185 .toArray(new SequenceI[0]));
3186 newFileLoc.append(" \"");
3187 newFileLoc.append((String) filedat[0]);
3188 newFileLoc.append("\"");
3191 newFileLoc.append(";");
3194 if (newFileLoc != null)
3196 int histbug = newFileLoc.indexOf("history = ");
3198 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3200 String val = (diff == -1) ? null : newFileLoc.substring(
3202 if (val != null && val.length() >= 4)
3204 if (val.contains("e"))
3206 if (val.trim().equals("true"))
3214 newFileLoc.replace(histbug, diff, val);
3217 // TODO: assemble String[] { pdb files }, String[] { id for each
3218 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3219 // seqs_file 2}} from hash
3220 final String[] pdbf = pdbfilenames
3221 .toArray(new String[pdbfilenames.size()]), id = pdbids
3222 .toArray(new String[pdbids.size()]);
3223 final SequenceI[][] sq = seqmaps
3224 .toArray(new SequenceI[seqmaps.size()][]);
3225 final String fileloc = newFileLoc.toString(), vid = sviewid;
3226 final AlignFrame alf = af;
3227 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3231 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3236 JalviewStructureDisplayI sview = null;
3239 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3240 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3241 useinJmolsuperpos, usetoColourbyseq,
3242 jmolColouring, fileloc, rect, vid);
3243 addNewStructureViewer(sview);
3244 } catch (OutOfMemoryError ex)
3246 new OOMWarning("restoring structure view for PDB id "
3247 + id, (OutOfMemoryError) ex.getCause());
3248 if (sview != null && sview.isVisible())
3250 sview.closeViewer();
3251 sview.setVisible(false);
3257 } catch (InvocationTargetException ex)
3259 warn("Unexpected error when opening Jmol view.", ex);
3261 } catch (InterruptedException e)
3263 // e.printStackTrace();
3269 // if (comp != null)
3271 // NOTE: if the jalview project is part of a shared session then
3272 // view synchronization should/could be done here.
3274 // add mapping for sequences in this view to an already open Jmol
3276 for (File id : oldFiles.keySet())
3278 // add this and any other pdb files that should be present in the
3280 Object[] filedat = oldFiles.get(id);
3281 String pdbFile = (String) filedat[0];
3282 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3283 .toArray(new SequenceI[0]);
3284 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3285 jalview.io.AppletFormatAdapter.FILE);
3286 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3288 // and add the AlignmentPanel's reference to the Jmol view
3289 comp.addAlignmentPanel(ap);
3290 if (useinJmolsuperpos)
3292 comp.useAlignmentPanelForSuperposition(ap);
3296 comp.excludeAlignmentPanelForSuperposition(ap);
3298 if (usetoColourbyseq)
3300 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3304 comp.excludeAlignmentPanelForColourbyseq(ap);
3310 // and finally return.
3317 * - minimum version we are comparing against
3319 * - version of data being processsed.
3320 * @return true if version is development/null or evaluates to the same or
3321 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3323 private boolean isVersionStringLaterThan(String supported, String version)
3325 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3326 || version.equalsIgnoreCase("Test")
3327 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3329 System.err.println("Assuming project file with "
3330 + (version == null ? "null" : version)
3331 + " is compatible with Jalview version " + supported);
3336 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3338 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3340 // convert b to decimal to catch bugfix releases within a series
3341 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3342 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3345 if (Float.valueOf(curT) > Float.valueOf(fileT))
3347 // current version is newer than the version that wrote the file
3350 } catch (NumberFormatException nfe)
3353 .println("** WARNING: Version comparison failed for tokens ("
3357 + ")\n** Current: '"
3358 + supported + "' and Version: '" + version + "'");
3361 if (currentV.hasMoreElements())
3363 // fileV has no minor version but identical series to current
3370 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3372 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3374 if (newStructureViewers != null)
3376 sview.getBinding().setFinishedLoadingFromArchive(false);
3377 newStructureViewers.add(sview);
3381 protected void setLoadingFinishedForNewStructureViewers()
3383 if (newStructureViewers != null)
3385 for (JalviewStructureDisplayI sview : newStructureViewers)
3387 sview.getBinding().setFinishedLoadingFromArchive(true);
3389 newStructureViewers.clear();
3390 newStructureViewers = null;
3394 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3395 Alignment al, JalviewModelSequence jms, Viewport view,
3396 String uniqueSeqSetId, String viewId,
3397 ArrayList<JvAnnotRow> autoAlan)
3399 AlignFrame af = null;
3400 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3401 uniqueSeqSetId, viewId);
3403 af.setFileName(file, "Jalview");
3405 for (int i = 0; i < JSEQ.length; i++)
3407 af.viewport.setSequenceColour(af.viewport.getAlignment()
3408 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3411 af.viewport.gatherViewsHere = view.getGatheredViews();
3413 if (view.getSequenceSetId() != null)
3415 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3416 .get(uniqueSeqSetId);
3418 af.viewport.setSequenceSetId(uniqueSeqSetId);
3421 // propagate shared settings to this new view
3422 af.viewport.historyList = av.historyList;
3423 af.viewport.redoList = av.redoList;
3427 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3429 // TODO: check if this method can be called repeatedly without
3430 // side-effects if alignpanel already registered.
3431 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3433 // apply Hidden regions to view.
3434 if (hiddenSeqs != null)
3436 for (int s = 0; s < JSEQ.length; s++)
3438 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3440 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3443 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3445 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3448 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3451 for (int s = 0; s < hiddenSeqs.size(); s++)
3453 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3456 af.viewport.hideSequence(hseqs);
3459 // recover view properties and display parameters
3460 if (view.getViewName() != null)
3462 af.viewport.viewName = view.getViewName();
3463 af.setInitialTabVisible();
3465 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3468 af.viewport.setShowAnnotation(view.getShowAnnotation());
3469 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3471 af.viewport.setColourText(view.getShowColourText());
3473 af.viewport.setConservationSelected(view.getConservationSelected());
3474 af.viewport.setShowJVSuffix(view.getShowFullId());
3475 af.viewport.rightAlignIds = view.getRightAlignIds();
3476 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3477 .getFontStyle(), view.getFontSize()));
3478 af.alignPanel.fontChanged();
3479 af.viewport.setRenderGaps(view.getRenderGaps());
3480 af.viewport.setWrapAlignment(view.getWrapAlignment());
3481 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3482 af.viewport.setShowAnnotation(view.getShowAnnotation());
3483 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3485 af.viewport.setShowBoxes(view.getShowBoxes());
3487 af.viewport.setShowText(view.getShowText());
3489 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3490 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3491 af.viewport.thresholdTextColour = view.getTextColThreshold();
3492 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3493 .isShowUnconserved() : false);
3494 af.viewport.setStartRes(view.getStartRes());
3495 af.viewport.setStartSeq(view.getStartSeq());
3497 ColourSchemeI cs = null;
3498 // apply colourschemes
3499 if (view.getBgColour() != null)
3501 if (view.getBgColour().startsWith("ucs"))
3503 cs = GetUserColourScheme(jms, view.getBgColour());
3505 else if (view.getBgColour().startsWith("Annotation"))
3507 AnnotationColours viewAnnColour = view.getAnnotationColours();
3508 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3515 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3520 cs.setThreshold(view.getPidThreshold(), true);
3521 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3525 af.viewport.setGlobalColourScheme(cs);
3526 af.viewport.setColourAppliesToAllGroups(false);
3528 if (view.getConservationSelected() && cs != null)
3530 cs.setConservationInc(view.getConsThreshold());
3533 af.changeColour(cs);
3535 af.viewport.setColourAppliesToAllGroups(true);
3537 if (view.getShowSequenceFeatures())
3539 af.viewport.showSequenceFeatures = true;
3541 if (view.hasCentreColumnLabels())
3543 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3545 if (view.hasIgnoreGapsinConsensus())
3547 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3550 if (view.hasFollowHighlight())
3552 af.viewport.followHighlight = view.getFollowHighlight();
3554 if (view.hasFollowSelection())
3556 af.viewport.followSelection = view.getFollowSelection();
3558 if (view.hasShowConsensusHistogram())
3560 af.viewport.setShowConsensusHistogram(view
3561 .getShowConsensusHistogram());
3565 af.viewport.setShowConsensusHistogram(true);
3567 if (view.hasShowSequenceLogo())
3569 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3573 af.viewport.setShowSequenceLogo(false);
3575 if (view.hasNormaliseSequenceLogo())
3577 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3579 if (view.hasShowDbRefTooltip())
3581 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3583 if (view.hasShowNPfeatureTooltip())
3585 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3587 if (view.hasShowGroupConsensus())
3589 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3593 af.viewport.setShowGroupConsensus(false);
3595 if (view.hasShowGroupConservation())
3597 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3601 af.viewport.setShowGroupConservation(false);
3604 // recover featre settings
3605 if (jms.getFeatureSettings() != null)
3607 af.viewport.featuresDisplayed = new Hashtable();
3608 String[] renderOrder = new String[jms.getFeatureSettings()
3609 .getSettingCount()];
3610 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3612 Setting setting = jms.getFeatureSettings().getSetting(fs);
3613 if (setting.hasMincolour())
3615 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3616 new java.awt.Color(setting.getMincolour()),
3617 new java.awt.Color(setting.getColour()),
3618 setting.getMin(), setting.getMax()) : new GraduatedColor(
3619 new java.awt.Color(setting.getMincolour()),
3620 new java.awt.Color(setting.getColour()), 0, 1);
3621 if (setting.hasThreshold())
3623 gc.setThresh(setting.getThreshold());
3624 gc.setThreshType(setting.getThreshstate());
3626 gc.setAutoScaled(true); // default
3627 if (setting.hasAutoScale())
3629 gc.setAutoScaled(setting.getAutoScale());
3631 if (setting.hasColourByLabel())
3633 gc.setColourByLabel(setting.getColourByLabel());
3635 // and put in the feature colour table.
3636 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3637 setting.getType(), gc);
3641 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3643 new java.awt.Color(setting.getColour()));
3645 renderOrder[fs] = setting.getType();
3646 if (setting.hasOrder())
3648 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3649 setting.getType(), setting.getOrder());
3653 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3655 fs / jms.getFeatureSettings().getSettingCount());
3657 if (setting.getDisplay())
3659 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3660 setting.getColour()));
3663 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3665 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3666 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3668 Group grp = jms.getFeatureSettings().getGroup(gs);
3669 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3673 if (view.getHiddenColumnsCount() > 0)
3675 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3677 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3678 .getHiddenColumns(c).getEnd() // +1
3682 if (view.getCalcIdParam() != null)
3684 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3686 if (calcIdParam != null)
3688 if (recoverCalcIdParam(calcIdParam, af.viewport))
3693 warn("Couldn't recover parameters for "
3694 + calcIdParam.getCalcId());
3699 af.setMenusFromViewport(af.viewport);
3700 // TODO: we don't need to do this if the viewport is aready visible.
3701 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3703 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3704 reorderAutoannotation(af, al, autoAlan);
3705 af.alignPanel.alignmentChanged();
3709 private ColourSchemeI constructAnnotationColour(
3710 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3711 JalviewModelSequence jms, boolean checkGroupAnnColour)
3713 boolean propagateAnnColour = false;
3714 ColourSchemeI cs = null;
3715 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3716 if (checkGroupAnnColour && al.getGroups() != null
3717 && al.getGroups().size() > 0)
3719 // pre 2.8.1 behaviour
3720 // check to see if we should transfer annotation colours
3721 propagateAnnColour = true;
3722 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3724 if (sg.cs instanceof AnnotationColourGradient)
3726 propagateAnnColour = false;
3730 // int find annotation
3731 if (annAlignment.getAlignmentAnnotation() != null)
3733 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3735 if (annAlignment.getAlignmentAnnotation()[i].label
3736 .equals(viewAnnColour.getAnnotation()))
3738 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3740 annAlignment.getAlignmentAnnotation()[i]
3741 .setThreshold(new jalview.datamodel.GraphLine(
3742 viewAnnColour.getThreshold(), "Threshold",
3743 java.awt.Color.black)
3748 if (viewAnnColour.getColourScheme().equals("None"))
3750 cs = new AnnotationColourGradient(
3751 annAlignment.getAlignmentAnnotation()[i],
3752 new java.awt.Color(viewAnnColour.getMinColour()),
3753 new java.awt.Color(viewAnnColour.getMaxColour()),
3754 viewAnnColour.getAboveThreshold());
3756 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3758 cs = new AnnotationColourGradient(
3759 annAlignment.getAlignmentAnnotation()[i],
3760 GetUserColourScheme(jms,
3761 viewAnnColour.getColourScheme()),
3762 viewAnnColour.getAboveThreshold());
3766 cs = new AnnotationColourGradient(
3767 annAlignment.getAlignmentAnnotation()[i],
3768 ColourSchemeProperty.getColour(al,
3769 viewAnnColour.getColourScheme()),
3770 viewAnnColour.getAboveThreshold());
3772 if (viewAnnColour.hasPerSequence())
3774 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3777 if (viewAnnColour.hasPredefinedColours())
3779 ((AnnotationColourGradient) cs)
3780 .setPredefinedColours(viewAnnColour
3781 .isPredefinedColours());
3783 if (propagateAnnColour && al.getGroups() != null)
3785 // Also use these settings for all the groups
3786 for (int g = 0; g < al.getGroups().size(); g++)
3788 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3796 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3797 * new AnnotationColourGradient(
3798 * annAlignment.getAlignmentAnnotation()[i], new
3799 * java.awt.Color(viewAnnColour. getMinColour()), new
3800 * java.awt.Color(viewAnnColour. getMaxColour()),
3801 * viewAnnColour.getAboveThreshold()); } else
3804 sg.cs = new AnnotationColourGradient(
3805 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3806 viewAnnColour.getAboveThreshold());
3807 if (cs instanceof AnnotationColourGradient)
3809 if (viewAnnColour.hasPerSequence())
3811 ((AnnotationColourGradient) cs)
3812 .setSeqAssociated(viewAnnColour.isPerSequence());
3814 if (viewAnnColour.hasPredefinedColours())
3816 ((AnnotationColourGradient) cs)
3817 .setPredefinedColours(viewAnnColour
3818 .isPredefinedColours());
3834 private void reorderAutoannotation(AlignFrame af, Alignment al,
3835 ArrayList<JvAnnotRow> autoAlan)
3837 // copy over visualization settings for autocalculated annotation in the
3839 if (al.getAlignmentAnnotation() != null)
3842 * Kludge for magic autoannotation names (see JAL-811)
3844 String[] magicNames = new String[]
3845 { "Consensus", "Quality", "Conservation" };
3846 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3847 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3848 for (String nm : magicNames)
3850 visan.put(nm, nullAnnot);
3852 for (JvAnnotRow auan : autoAlan)
3854 visan.put(auan.template.label
3855 + (auan.template.getCalcId() == null ? "" : "\t"
3856 + auan.template.getCalcId()), auan);
3858 int hSize = al.getAlignmentAnnotation().length;
3859 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3860 // work through any autoCalculated annotation already on the view
3861 // removing it if it should be placed in a different location on the
3862 // annotation panel.
3863 List<String> remains = new ArrayList(visan.keySet());
3864 for (int h = 0; h < hSize; h++)
3866 jalview.datamodel.AlignmentAnnotation jalan = al
3867 .getAlignmentAnnotation()[h];
3868 if (jalan.autoCalculated)
3871 JvAnnotRow valan = visan.get(k = jalan.label);
3872 if (jalan.getCalcId() != null)
3874 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3879 // delete the auto calculated row from the alignment
3880 al.deleteAnnotation(jalan, false);
3884 if (valan != nullAnnot)
3886 if (jalan != valan.template)
3888 // newly created autoannotation row instance
3889 // so keep a reference to the visible annotation row
3890 // and copy over all relevant attributes
3891 if (valan.template.graphHeight >= 0)
3894 jalan.graphHeight = valan.template.graphHeight;
3896 jalan.visible = valan.template.visible;
3898 reorder.add(new JvAnnotRow(valan.order, jalan));
3903 // Add any (possibly stale) autocalculated rows that were not appended to
3904 // the view during construction
3905 for (String other : remains)
3907 JvAnnotRow othera = visan.get(other);
3908 if (othera != nullAnnot && othera.template.getCalcId() != null
3909 && othera.template.getCalcId().length() > 0)
3911 reorder.add(othera);
3914 // now put the automatic annotation in its correct place
3915 int s = 0, srt[] = new int[reorder.size()];
3916 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3917 for (JvAnnotRow jvar : reorder)
3920 srt[s++] = jvar.order;
3923 jalview.util.QuickSort.sort(srt, rws);
3924 // and re-insert the annotation at its correct position
3925 for (JvAnnotRow jvar : rws)
3927 al.addAnnotation(jvar.template, jvar.order);
3929 af.alignPanel.adjustAnnotationHeight();
3933 Hashtable skipList = null;
3936 * TODO remove this method
3939 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3940 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3941 * throw new Error("Implementation Error. No skipList defined for this
3942 * Jalview2XML instance."); } return (AlignFrame)
3943 * skipList.get(view.getSequenceSetId()); }
3947 * Check if the Jalview view contained in object should be skipped or not.
3950 * @return true if view's sequenceSetId is a key in skipList
3952 private boolean skipViewport(JalviewModel object)
3954 if (skipList == null)
3959 if (skipList.containsKey(id = object.getJalviewModelSequence()
3960 .getViewport()[0].getSequenceSetId()))
3962 if (Cache.log != null && Cache.log.isDebugEnabled())
3964 Cache.log.debug("Skipping seuqence set id " + id);
3971 public void AddToSkipList(AlignFrame af)
3973 if (skipList == null)
3975 skipList = new Hashtable();
3977 skipList.put(af.getViewport().getSequenceSetId(), af);
3980 public void clearSkipList()
3982 if (skipList != null)
3989 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3991 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3992 Vector dseqs = null;
3995 // create a list of new dataset sequences
3996 dseqs = new Vector();
3998 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4000 Sequence vamsasSeq = vamsasSet.getSequence(i);
4001 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
4003 // create a new dataset
4006 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4007 dseqs.copyInto(dsseqs);
4008 ds = new jalview.datamodel.Alignment(dsseqs);
4009 debug("Created new dataset " + vamsasSet.getDatasetId()
4010 + " for alignment " + System.identityHashCode(al));
4011 addDatasetRef(vamsasSet.getDatasetId(), ds);
4013 // set the dataset for the newly imported alignment.
4014 if (al.getDataset() == null)
4023 * sequence definition to create/merge dataset sequence for
4027 * vector to add new dataset sequence to
4029 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4030 AlignmentI ds, Vector dseqs)
4032 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4034 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4035 .get(vamsasSeq.getId());
4036 jalview.datamodel.SequenceI dsq = null;
4037 if (sq != null && sq.getDatasetSequence() != null)
4039 dsq = sq.getDatasetSequence();
4042 String sqid = vamsasSeq.getDsseqid();
4045 // need to create or add a new dataset sequence reference to this sequence
4048 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4053 // make a new dataset sequence
4054 dsq = sq.createDatasetSequence();
4057 // make up a new dataset reference for this sequence
4058 sqid = seqHash(dsq);
4060 dsq.setVamsasId(uniqueSetSuffix + sqid);
4061 seqRefIds.put(sqid, dsq);
4066 dseqs.addElement(dsq);
4071 ds.addSequence(dsq);
4077 { // make this dataset sequence sq's dataset sequence
4078 sq.setDatasetSequence(dsq);
4079 // and update the current dataset alignment
4084 if (!dseqs.contains(dsq))
4091 if (ds.findIndex(dsq) < 0)
4093 ds.addSequence(dsq);
4100 // TODO: refactor this as a merge dataset sequence function
4101 // now check that sq (the dataset sequence) sequence really is the union of
4102 // all references to it
4103 // boolean pre = sq.getStart() < dsq.getStart();
4104 // boolean post = sq.getEnd() > dsq.getEnd();
4108 StringBuffer sb = new StringBuffer();
4109 String newres = jalview.analysis.AlignSeq.extractGaps(
4110 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4111 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4112 && newres.length() > dsq.getLength())
4114 // Update with the longer sequence.
4118 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4119 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4120 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4121 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4123 dsq.setSequence(newres);
4125 // TODO: merges will never happen if we 'know' we have the real dataset
4126 // sequence - this should be detected when id==dssid
4128 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4129 // + (pre ? "prepended" : "") + " "
4130 // + (post ? "appended" : ""));
4135 java.util.Hashtable datasetIds = null;
4137 java.util.IdentityHashMap dataset2Ids = null;
4139 private Alignment getDatasetFor(String datasetId)
4141 if (datasetIds == null)
4143 datasetIds = new Hashtable();
4146 if (datasetIds.containsKey(datasetId))
4148 return (Alignment) datasetIds.get(datasetId);
4153 private void addDatasetRef(String datasetId, Alignment dataset)
4155 if (datasetIds == null)
4157 datasetIds = new Hashtable();
4159 datasetIds.put(datasetId, dataset);
4163 * make a new dataset ID for this jalview dataset alignment
4168 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4170 if (dataset.getDataset() != null)
4172 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4174 String datasetId = makeHashCode(dataset, null);
4175 if (datasetId == null)
4177 // make a new datasetId and record it
4178 if (dataset2Ids == null)
4180 dataset2Ids = new IdentityHashMap();
4184 datasetId = (String) dataset2Ids.get(dataset);
4186 if (datasetId == null)
4188 datasetId = "ds" + dataset2Ids.size() + 1;
4189 dataset2Ids.put(dataset, datasetId);
4195 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4197 for (int d = 0; d < sequence.getDBRefCount(); d++)
4199 DBRef dr = sequence.getDBRef(d);
4200 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4201 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4202 .getVersion(), sequence.getDBRef(d).getAccessionId());
4203 if (dr.getMapping() != null)
4205 entry.setMap(addMapping(dr.getMapping()));
4207 datasetSequence.addDBRef(entry);
4211 private jalview.datamodel.Mapping addMapping(Mapping m)
4213 SequenceI dsto = null;
4214 // Mapping m = dr.getMapping();
4215 int fr[] = new int[m.getMapListFromCount() * 2];
4216 Enumeration f = m.enumerateMapListFrom();
4217 for (int _i = 0; f.hasMoreElements(); _i += 2)
4219 MapListFrom mf = (MapListFrom) f.nextElement();
4220 fr[_i] = mf.getStart();
4221 fr[_i + 1] = mf.getEnd();
4223 int fto[] = new int[m.getMapListToCount() * 2];
4224 f = m.enumerateMapListTo();
4225 for (int _i = 0; f.hasMoreElements(); _i += 2)
4227 MapListTo mf = (MapListTo) f.nextElement();
4228 fto[_i] = mf.getStart();
4229 fto[_i + 1] = mf.getEnd();
4231 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4232 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4233 if (m.getMappingChoice() != null)
4235 MappingChoice mc = m.getMappingChoice();
4236 if (mc.getDseqFor() != null)
4238 String dsfor = "" + mc.getDseqFor();
4239 if (seqRefIds.containsKey(dsfor))
4244 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4248 frefedSequence.add(new Object[]
4255 * local sequence definition
4257 Sequence ms = mc.getSequence();
4258 jalview.datamodel.Sequence djs = null;
4259 String sqid = ms.getDsseqid();
4260 if (sqid != null && sqid.length() > 0)
4263 * recover dataset sequence
4265 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4270 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4271 sqid = ((Object) ms).toString(); // make up a new hascode for
4272 // undefined dataset sequence hash
4273 // (unlikely to happen)
4279 * make a new dataset sequence and add it to refIds hash
4281 djs = new jalview.datamodel.Sequence(ms.getName(),
4283 djs.setStart(jmap.getMap().getToLowest());
4284 djs.setEnd(jmap.getMap().getToHighest());
4285 djs.setVamsasId(uniqueSetSuffix + sqid);
4287 seqRefIds.put(sqid, djs);
4290 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4299 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4300 boolean keepSeqRefs)
4303 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4309 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4313 uniqueSetSuffix = "";
4314 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4319 if (this.frefedSequence == null)
4321 frefedSequence = new Vector();
4324 viewportsAdded = new Hashtable();
4326 AlignFrame af = LoadFromObject(jm, null, false, null);
4327 af.alignPanels.clear();
4328 af.closeMenuItem_actionPerformed(true);
4331 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4332 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4333 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4334 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4335 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4338 return af.alignPanel;
4342 * flag indicating if hashtables should be cleared on finalization TODO this
4343 * flag may not be necessary
4345 private final boolean _cleartables = true;
4347 private Hashtable jvids2vobj;
4352 * @see java.lang.Object#finalize()
4355 protected void finalize() throws Throwable
4357 // really make sure we have no buried refs left.
4362 this.seqRefIds = null;
4363 this.seqsToIds = null;
4367 private void warn(String msg)
4372 private void warn(String msg, Exception e)
4374 if (Cache.log != null)
4378 Cache.log.warn(msg, e);
4382 Cache.log.warn(msg);
4387 System.err.println("Warning: " + msg);
4390 e.printStackTrace();
4395 private void debug(String string)
4397 debug(string, null);
4400 private void debug(String msg, Exception e)
4402 if (Cache.log != null)
4406 Cache.log.debug(msg, e);
4410 Cache.log.debug(msg);
4415 System.err.println("Warning: " + msg);
4418 e.printStackTrace();
4424 * set the object to ID mapping tables used to write/recover objects and XML
4425 * ID strings for the jalview project. If external tables are provided then
4426 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4427 * object goes out of scope. - also populates the datasetIds hashtable with
4428 * alignment objects containing dataset sequences
4431 * Map from ID strings to jalview datamodel
4433 * Map from jalview datamodel to ID strings
4437 public void setObjectMappingTables(Hashtable vobj2jv,
4438 IdentityHashMap jv2vobj)
4440 this.jv2vobj = jv2vobj;
4441 this.vobj2jv = vobj2jv;
4442 Iterator ds = jv2vobj.keySet().iterator();
4444 while (ds.hasNext())
4446 Object jvobj = ds.next();
4447 id = jv2vobj.get(jvobj).toString();
4448 if (jvobj instanceof jalview.datamodel.Alignment)
4450 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4452 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4455 else if (jvobj instanceof jalview.datamodel.Sequence)
4457 // register sequence object so the XML parser can recover it.
4458 if (seqRefIds == null)
4460 seqRefIds = new Hashtable();
4462 if (seqsToIds == null)
4464 seqsToIds = new IdentityHashMap();
4466 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4467 seqsToIds.put(jvobj, id);
4469 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4471 if (annotationIds == null)
4473 annotationIds = new Hashtable();
4476 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4477 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4478 if (jvann.annotationId == null)
4480 jvann.annotationId = anid;
4482 if (!jvann.annotationId.equals(anid))
4484 // TODO verify that this is the correct behaviour
4485 this.warn("Overriding Annotation ID for " + anid
4486 + " from different id : " + jvann.annotationId);
4487 jvann.annotationId = anid;
4490 else if (jvobj instanceof String)
4492 if (jvids2vobj == null)
4494 jvids2vobj = new Hashtable();
4495 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4500 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4506 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4507 * objects created from the project archive. If string is null (default for
4508 * construction) then suffix will be set automatically.
4512 public void setUniqueSetSuffix(String string)
4514 uniqueSetSuffix = string;
4519 * uses skipList2 as the skipList for skipping views on sequence sets
4520 * associated with keys in the skipList
4524 public void setSkipList(Hashtable skipList2)
4526 skipList = skipList2;