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 > ' ')
1461 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1465 if (aa[i].annotations[a].colour != null
1466 && aa[i].annotations[a].colour != java.awt.Color.black)
1468 ae.setColour(aa[i].annotations[a].colour.getRGB());
1471 an.addAnnotationElement(ae);
1472 if (aa[i].autoCalculated)
1474 // only write one non-null entry into the annotation row -
1475 // sufficient to get the visualization attributes necessary to
1483 an.setScoreOnly(true);
1485 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1487 // skip autocalculated annotation - these are only provided for
1489 vamsasSet.addAnnotation(an);
1495 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1497 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1498 if (settings != null)
1500 CalcIdParam vCalcIdParam = new CalcIdParam();
1501 vCalcIdParam.setCalcId(calcId);
1502 vCalcIdParam.addServiceURL(settings.getServiceURI());
1503 // generic URI allowing a third party to resolve another instance of the
1504 // service used for this calculation
1505 for (String urls : settings.getServiceURLs())
1507 vCalcIdParam.addServiceURL(urls);
1509 vCalcIdParam.setVersion("1.0");
1510 if (settings.getPreset() != null)
1512 WsParamSetI setting = settings.getPreset();
1513 vCalcIdParam.setName(setting.getName());
1514 vCalcIdParam.setDescription(setting.getDescription());
1518 vCalcIdParam.setName("");
1519 vCalcIdParam.setDescription("Last used parameters");
1521 // need to be able to recover 1) settings 2) user-defined presets or
1522 // recreate settings from preset 3) predefined settings provided by
1523 // service - or settings that can be transferred (or discarded)
1524 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1526 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1527 // todo - decide if updateImmediately is needed for any projects.
1529 return vCalcIdParam;
1534 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1537 if (calcIdParam.getVersion().equals("1.0"))
1539 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1540 .getPreferredServiceFor(calcIdParam.getServiceURL());
1541 if (service != null)
1543 WsParamSetI parmSet = null;
1546 parmSet = service.getParamStore().parseServiceParameterFile(
1547 calcIdParam.getName(), calcIdParam.getDescription(),
1548 calcIdParam.getServiceURL(),
1549 calcIdParam.getParameters().replace("|\\n|", "\n"));
1550 } catch (IOException x)
1552 warn("Couldn't parse parameter data for "
1553 + calcIdParam.getCalcId(), x);
1556 List<ArgumentI> argList = null;
1557 if (calcIdParam.getName().length() > 0)
1559 parmSet = service.getParamStore()
1560 .getPreset(calcIdParam.getName());
1561 if (parmSet != null)
1563 // TODO : check we have a good match with settings in AACon -
1564 // otherwise we'll need to create a new preset
1569 argList = parmSet.getArguments();
1572 AAConSettings settings = new AAConSettings(
1573 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1574 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1575 calcIdParam.isNeedsUpdate());
1580 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1584 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1588 * External mapping between jalview objects and objects yielding a valid and
1589 * unique object ID string. This is null for normal Jalview project IO, but
1590 * non-null when a jalview project is being read or written as part of a
1593 IdentityHashMap jv2vobj = null;
1596 * Construct a unique ID for jvobj using either existing bindings or if none
1597 * exist, the result of the hashcode call for the object.
1600 * jalview data object
1601 * @return unique ID for referring to jvobj
1603 private String makeHashCode(Object jvobj, String altCode)
1605 if (jv2vobj != null)
1607 Object id = jv2vobj.get(jvobj);
1610 return id.toString();
1612 // check string ID mappings
1613 if (jvids2vobj != null && jvobj instanceof String)
1615 id = jvids2vobj.get(jvobj);
1619 return id.toString();
1621 // give up and warn that something has gone wrong
1622 warn("Cannot find ID for object in external mapping : " + jvobj);
1628 * return local jalview object mapped to ID, if it exists
1632 * @return null or object bound to idcode
1634 private Object retrieveExistingObj(String idcode)
1636 if (idcode != null && vobj2jv != null)
1638 return vobj2jv.get(idcode);
1644 * binding from ID strings from external mapping table to jalview data model
1647 private Hashtable vobj2jv;
1649 private Sequence createVamsasSequence(String id, SequenceI jds)
1651 return createVamsasSequence(true, id, jds, null);
1654 private Sequence createVamsasSequence(boolean recurse, String id,
1655 SequenceI jds, SequenceI parentseq)
1657 Sequence vamsasSeq = new Sequence();
1658 vamsasSeq.setId(id);
1659 vamsasSeq.setName(jds.getName());
1660 vamsasSeq.setSequence(jds.getSequenceAsString());
1661 vamsasSeq.setDescription(jds.getDescription());
1662 jalview.datamodel.DBRefEntry[] dbrefs = null;
1663 if (jds.getDatasetSequence() != null)
1665 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1666 if (jds.getDatasetSequence().getDBRef() != null)
1668 dbrefs = jds.getDatasetSequence().getDBRef();
1673 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1674 // dataset sequences only
1675 dbrefs = jds.getDBRef();
1679 for (int d = 0; d < dbrefs.length; d++)
1681 DBRef dbref = new DBRef();
1682 dbref.setSource(dbrefs[d].getSource());
1683 dbref.setVersion(dbrefs[d].getVersion());
1684 dbref.setAccessionId(dbrefs[d].getAccessionId());
1685 if (dbrefs[d].hasMap())
1687 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1689 dbref.setMapping(mp);
1691 vamsasSeq.addDBRef(dbref);
1697 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1698 SequenceI parentseq, SequenceI jds, boolean recurse)
1701 if (jmp.getMap() != null)
1705 jalview.util.MapList mlst = jmp.getMap();
1706 int r[] = mlst.getFromRanges();
1707 for (int s = 0; s < r.length; s += 2)
1709 MapListFrom mfrom = new MapListFrom();
1710 mfrom.setStart(r[s]);
1711 mfrom.setEnd(r[s + 1]);
1712 mp.addMapListFrom(mfrom);
1714 r = mlst.getToRanges();
1715 for (int s = 0; s < r.length; s += 2)
1717 MapListTo mto = new MapListTo();
1719 mto.setEnd(r[s + 1]);
1720 mp.addMapListTo(mto);
1722 mp.setMapFromUnit(mlst.getFromRatio());
1723 mp.setMapToUnit(mlst.getToRatio());
1724 if (jmp.getTo() != null)
1726 MappingChoice mpc = new MappingChoice();
1728 && (parentseq != jmp.getTo() || parentseq
1729 .getDatasetSequence() != jmp.getTo()))
1731 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1737 SequenceI ps = null;
1738 if (parentseq != jmp.getTo()
1739 && parentseq.getDatasetSequence() != jmp.getTo())
1741 // chaining dbref rather than a handshaking one
1742 jmpid = seqHash(ps = jmp.getTo());
1746 jmpid = seqHash(ps = parentseq);
1748 mpc.setDseqFor(jmpid);
1749 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1751 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1752 seqRefIds.put(mpc.getDseqFor(), ps);
1756 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1759 mp.setMappingChoice(mpc);
1765 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1766 Vector userColours, JalviewModelSequence jms)
1769 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1770 boolean newucs = false;
1771 if (!userColours.contains(ucs))
1773 userColours.add(ucs);
1776 id = "ucs" + userColours.indexOf(ucs);
1779 // actually create the scheme's entry in the XML model
1780 java.awt.Color[] colours = ucs.getColours();
1781 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1782 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1784 for (int i = 0; i < colours.length; i++)
1786 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1787 col.setName(ResidueProperties.aa[i]);
1788 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1789 jbucs.addColour(col);
1791 if (ucs.getLowerCaseColours() != null)
1793 colours = ucs.getLowerCaseColours();
1794 for (int i = 0; i < colours.length; i++)
1796 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1797 col.setName(ResidueProperties.aa[i].toLowerCase());
1798 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1799 jbucs.addColour(col);
1804 uc.setUserColourScheme(jbucs);
1805 jms.addUserColours(uc);
1811 jalview.schemes.UserColourScheme GetUserColourScheme(
1812 JalviewModelSequence jms, String id)
1814 UserColours[] uc = jms.getUserColours();
1815 UserColours colours = null;
1817 for (int i = 0; i < uc.length; i++)
1819 if (uc[i].getId().equals(id))
1827 java.awt.Color[] newColours = new java.awt.Color[24];
1829 for (int i = 0; i < 24; i++)
1831 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1832 .getUserColourScheme().getColour(i).getRGB(), 16));
1835 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1838 if (colours.getUserColourScheme().getColourCount() > 24)
1840 newColours = new java.awt.Color[23];
1841 for (int i = 0; i < 23; i++)
1843 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1844 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1846 ucs.setLowerCaseColours(newColours);
1853 * contains last error message (if any) encountered by XML loader.
1855 String errorMessage = null;
1858 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1859 * exceptions are raised during project XML parsing
1861 public boolean attemptversion1parse = true;
1864 * Load a jalview project archive from a jar file
1867 * - HTTP URL or filename
1869 public AlignFrame LoadJalviewAlign(final String file)
1872 jalview.gui.AlignFrame af = null;
1876 // create list to store references for any new Jmol viewers created
1877 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1878 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1879 // Workaround is to make sure caller implements the JarInputStreamProvider
1881 // so we can re-open the jar input stream for each entry.
1883 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1884 af = LoadJalviewAlign(jprovider);
1886 } catch (MalformedURLException e)
1888 errorMessage = "Invalid URL format for '" + file + "'";
1894 SwingUtilities.invokeAndWait(new Runnable()
1898 setLoadingFinishedForNewStructureViewers();
1901 } catch (Exception x)
1909 private jarInputStreamProvider createjarInputStreamProvider(
1910 final String file) throws MalformedURLException
1913 errorMessage = null;
1914 uniqueSetSuffix = null;
1916 viewportsAdded = null;
1917 frefedSequence = null;
1919 if (file.startsWith("http://"))
1921 url = new URL(file);
1923 final URL _url = url;
1924 return new jarInputStreamProvider()
1928 public JarInputStream getJarInputStream() throws IOException
1932 return new JarInputStream(_url.openStream());
1936 return new JarInputStream(new FileInputStream(file));
1941 public String getFilename()
1949 * Recover jalview session from a jalview project archive. Caller may
1950 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1951 * themselves. Any null fields will be initialised with default values,
1952 * non-null fields are left alone.
1957 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1959 errorMessage = null;
1960 if (uniqueSetSuffix == null)
1962 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1964 if (seqRefIds == null)
1966 seqRefIds = new Hashtable();
1968 if (viewportsAdded == null)
1970 viewportsAdded = new Hashtable();
1972 if (frefedSequence == null)
1974 frefedSequence = new Vector();
1977 jalview.gui.AlignFrame af = null, _af = null;
1978 Hashtable gatherToThisFrame = new Hashtable();
1979 final String file = jprovider.getFilename();
1982 JarInputStream jin = null;
1983 JarEntry jarentry = null;
1988 jin = jprovider.getJarInputStream();
1989 for (int i = 0; i < entryCount; i++)
1991 jarentry = jin.getNextJarEntry();
1994 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1996 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1997 JalviewModel object = new JalviewModel();
1999 Unmarshaller unmar = new Unmarshaller(object);
2000 unmar.setValidation(false);
2001 object = (JalviewModel) unmar.unmarshal(in);
2002 if (true) // !skipViewport(object))
2004 _af = LoadFromObject(object, file, true, jprovider);
2005 if (object.getJalviewModelSequence().getViewportCount() > 0)
2008 if (af.viewport.gatherViewsHere)
2010 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2016 else if (jarentry != null)
2018 // Some other file here.
2021 } while (jarentry != null);
2022 resolveFrefedSequences();
2023 } catch (java.io.FileNotFoundException ex)
2025 ex.printStackTrace();
2026 errorMessage = "Couldn't locate Jalview XML file : " + file;
2027 System.err.println("Exception whilst loading jalview XML file : "
2029 } catch (java.net.UnknownHostException ex)
2031 ex.printStackTrace();
2032 errorMessage = "Couldn't locate Jalview XML file : " + file;
2033 System.err.println("Exception whilst loading jalview XML file : "
2035 } catch (Exception ex)
2037 System.err.println("Parsing as Jalview Version 2 file failed.");
2038 ex.printStackTrace(System.err);
2039 if (attemptversion1parse)
2041 // Is Version 1 Jar file?
2044 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2045 } catch (Exception ex2)
2047 System.err.println("Exception whilst loading as jalviewXMLV1:");
2048 ex2.printStackTrace();
2052 if (Desktop.instance != null)
2054 Desktop.instance.stopLoading();
2058 System.out.println("Successfully loaded archive file");
2061 ex.printStackTrace();
2063 System.err.println("Exception whilst loading jalview XML file : "
2065 } catch (OutOfMemoryError e)
2067 // Don't use the OOM Window here
2068 errorMessage = "Out of memory loading jalview XML file";
2069 System.err.println("Out of memory whilst loading jalview XML file");
2070 e.printStackTrace();
2073 if (Desktop.instance != null)
2075 Desktop.instance.stopLoading();
2078 Enumeration en = gatherToThisFrame.elements();
2079 while (en.hasMoreElements())
2081 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2083 if (errorMessage != null)
2091 * check errorMessage for a valid error message and raise an error box in the
2092 * GUI or write the current errorMessage to stderr and then clear the error
2095 protected void reportErrors()
2097 reportErrors(false);
2100 protected void reportErrors(final boolean saving)
2102 if (errorMessage != null)
2104 final String finalErrorMessage = errorMessage;
2107 javax.swing.SwingUtilities.invokeLater(new Runnable()
2112 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2113 finalErrorMessage, "Error "
2114 + (saving ? "saving" : "loading")
2115 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2121 System.err.println("Problem loading Jalview file: " + errorMessage);
2124 errorMessage = null;
2127 Hashtable<String, String> alreadyLoadedPDB;
2130 * when set, local views will be updated from view stored in JalviewXML
2131 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2132 * sync if this is set to true.
2134 private final boolean updateLocalViews = false;
2136 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2138 if (alreadyLoadedPDB == null)
2140 alreadyLoadedPDB = new Hashtable();
2143 if (alreadyLoadedPDB.containsKey(pdbId))
2145 return alreadyLoadedPDB.get(pdbId).toString();
2150 JarInputStream jin = jprovider.getJarInputStream();
2152 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2153 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2154 * FileInputStream(jprovider)); }
2157 JarEntry entry = null;
2160 entry = jin.getNextJarEntry();
2161 } while (entry != null && !entry.getName().equals(pdbId));
2164 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2165 File outFile = File.createTempFile("jalview_pdb", ".txt");
2166 outFile.deleteOnExit();
2167 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2170 while ((data = in.readLine()) != null)
2177 } catch (Exception foo)
2182 String t = outFile.getAbsolutePath();
2183 alreadyLoadedPDB.put(pdbId, t);
2188 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2190 } catch (Exception ex)
2192 ex.printStackTrace();
2198 private class JvAnnotRow
2200 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2207 * persisted version of annotation row from which to take vis properties
2209 public jalview.datamodel.AlignmentAnnotation template;
2212 * original position of the annotation row in the alignment
2218 * Load alignment frame from jalview XML DOM object
2223 * filename source string
2224 * @param loadTreesAndStructures
2225 * when false only create Viewport
2227 * data source provider
2228 * @return alignment frame created from view stored in DOM
2230 AlignFrame LoadFromObject(JalviewModel object, String file,
2231 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2233 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2234 Sequence[] vamsasSeq = vamsasSet.getSequence();
2236 JalviewModelSequence jms = object.getJalviewModelSequence();
2238 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2241 // ////////////////////////////////
2244 Vector hiddenSeqs = null;
2245 jalview.datamodel.Sequence jseq;
2247 ArrayList tmpseqs = new ArrayList();
2249 boolean multipleView = false;
2251 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2252 int vi = 0; // counter in vamsasSeq array
2253 for (int i = 0; i < JSEQ.length; i++)
2255 String seqId = JSEQ[i].getId();
2257 if (seqRefIds.get(seqId) != null)
2259 tmpseqs.add(seqRefIds.get(seqId));
2260 multipleView = true;
2264 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2265 vamsasSeq[vi].getSequence());
2266 jseq.setDescription(vamsasSeq[vi].getDescription());
2267 jseq.setStart(JSEQ[i].getStart());
2268 jseq.setEnd(JSEQ[i].getEnd());
2269 jseq.setVamsasId(uniqueSetSuffix + seqId);
2270 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2275 if (JSEQ[i].getHidden())
2277 if (hiddenSeqs == null)
2279 hiddenSeqs = new Vector();
2282 hiddenSeqs.addElement(seqRefIds.get(seqId));
2288 // Create the alignment object from the sequence set
2289 // ///////////////////////////////
2290 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2293 tmpseqs.toArray(orderedSeqs);
2295 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2298 // / Add the alignment properties
2299 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2301 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2302 al.setProperty(ssp.getKey(), ssp.getValue());
2306 // SequenceFeatures are added to the DatasetSequence,
2307 // so we must create or recover the dataset before loading features
2308 // ///////////////////////////////
2309 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2311 // older jalview projects do not have a dataset id.
2312 al.setDataset(null);
2316 recoverDatasetFor(vamsasSet, al);
2318 // ///////////////////////////////
2320 Hashtable pdbloaded = new Hashtable();
2323 // load sequence features, database references and any associated PDB
2324 // structures for the alignment
2325 for (int i = 0; i < vamsasSeq.length; i++)
2327 if (JSEQ[i].getFeaturesCount() > 0)
2329 Features[] features = JSEQ[i].getFeatures();
2330 for (int f = 0; f < features.length; f++)
2332 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2333 features[f].getType(), features[f].getDescription(),
2334 features[f].getStatus(), features[f].getBegin(),
2335 features[f].getEnd(), features[f].getFeatureGroup());
2337 sf.setScore(features[f].getScore());
2338 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2340 OtherData keyValue = features[f].getOtherData(od);
2341 if (keyValue.getKey().startsWith("LINK"))
2343 sf.addLink(keyValue.getValue());
2347 sf.setValue(keyValue.getKey(), keyValue.getValue());
2352 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2355 if (vamsasSeq[i].getDBRefCount() > 0)
2357 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2359 if (JSEQ[i].getPdbidsCount() > 0)
2361 Pdbids[] ids = JSEQ[i].getPdbids();
2362 for (int p = 0; p < ids.length; p++)
2364 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2365 entry.setId(ids[p].getId());
2366 entry.setType(ids[p].getType());
2367 if (ids[p].getFile() != null)
2369 if (!pdbloaded.containsKey(ids[p].getFile()))
2371 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2375 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2378 StructureSelectionManager.getStructureSelectionManager(
2380 .registerPDBEntry(entry);
2381 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2385 } // end !multipleview
2387 // ///////////////////////////////
2388 // LOAD SEQUENCE MAPPINGS
2390 if (vamsasSet.getAlcodonFrameCount() > 0)
2392 // TODO Potentially this should only be done once for all views of an
2394 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2395 for (int i = 0; i < alc.length; i++)
2397 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2398 alc[i].getAlcodonCount());
2399 if (alc[i].getAlcodonCount() > 0)
2401 Alcodon[] alcods = alc[i].getAlcodon();
2402 for (int p = 0; p < cf.codons.length; p++)
2404 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2405 && alcods[p].hasPos3())
2407 // translated codons require three valid positions
2408 cf.codons[p] = new int[3];
2409 cf.codons[p][0] = (int) alcods[p].getPos1();
2410 cf.codons[p][1] = (int) alcods[p].getPos2();
2411 cf.codons[p][2] = (int) alcods[p].getPos3();
2415 cf.codons[p] = null;
2419 if (alc[i].getAlcodMapCount() > 0)
2421 AlcodMap[] maps = alc[i].getAlcodMap();
2422 for (int m = 0; m < maps.length; m++)
2424 SequenceI dnaseq = (SequenceI) seqRefIds
2425 .get(maps[m].getDnasq());
2427 jalview.datamodel.Mapping mapping = null;
2428 // attach to dna sequence reference.
2429 if (maps[m].getMapping() != null)
2431 mapping = addMapping(maps[m].getMapping());
2435 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2440 frefedSequence.add(new Object[]
2441 { maps[m].getDnasq(), cf, mapping });
2445 al.addCodonFrame(cf);
2450 // ////////////////////////////////
2452 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2454 * store any annotations which forward reference a group's ID
2456 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2458 if (vamsasSet.getAnnotationCount() > 0)
2460 Annotation[] an = vamsasSet.getAnnotation();
2462 for (int i = 0; i < an.length; i++)
2465 * test if annotation is automatically calculated for this view only
2467 boolean autoForView = false;
2468 if (an[i].getLabel().equals("Quality")
2469 || an[i].getLabel().equals("Conservation")
2470 || an[i].getLabel().equals("Consensus"))
2472 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2474 if (!an[i].hasAutoCalculated())
2476 an[i].setAutoCalculated(true);
2480 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2482 // remove ID - we don't recover annotation from other views for
2483 // view-specific annotation
2487 // set visiblity for other annotation in this view
2488 if (an[i].getId() != null
2489 && annotationIds.containsKey(an[i].getId()))
2491 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2492 .get(an[i].getId());
2493 // in principle Visible should always be true for annotation displayed
2494 // in multiple views
2495 if (an[i].hasVisible())
2497 jda.visible = an[i].getVisible();
2500 al.addAnnotation(jda);
2504 // Construct new annotation from model.
2505 AnnotationElement[] ae = an[i].getAnnotationElement();
2506 jalview.datamodel.Annotation[] anot = null;
2507 java.awt.Color firstColour = null;
2509 if (!an[i].getScoreOnly())
2511 anot = new jalview.datamodel.Annotation[al.getWidth()];
2512 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2514 anpos = ae[aa].getPosition();
2516 if (anpos >= anot.length)
2521 anot[anpos] = new jalview.datamodel.Annotation(
2523 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2524 (ae[aa].getSecondaryStructure() == null || ae[aa]
2525 .getSecondaryStructure().length() == 0) ? ' '
2526 : ae[aa].getSecondaryStructure().charAt(0),
2530 // JBPNote: Consider verifying dataflow for IO of secondary
2531 // structure annotation read from Stockholm files
2532 // this was added to try to ensure that
2533 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2535 // anot[ae[aa].getPosition()].displayCharacter = "";
2537 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2538 if (firstColour == null)
2540 firstColour = anot[anpos].colour;
2544 jalview.datamodel.AlignmentAnnotation jaa = null;
2546 if (an[i].getGraph())
2548 float llim = 0, hlim = 0;
2549 // if (autoForView || an[i].isAutoCalculated()) {
2552 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2553 an[i].getDescription(), anot, llim, hlim,
2554 an[i].getGraphType());
2556 jaa.graphGroup = an[i].getGraphGroup();
2557 jaa._linecolour = firstColour;
2558 if (an[i].getThresholdLine() != null)
2560 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2561 .getThresholdLine().getValue(), an[i]
2562 .getThresholdLine().getLabel(), new java.awt.Color(
2563 an[i].getThresholdLine().getColour())));
2566 if (autoForView || an[i].isAutoCalculated())
2568 // Hardwire the symbol display line to ensure that labels for
2569 // histograms are displayed
2575 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2576 an[i].getDescription(), anot);
2577 jaa._linecolour = firstColour;
2579 // register new annotation
2580 if (an[i].getId() != null)
2582 annotationIds.put(an[i].getId(), jaa);
2583 jaa.annotationId = an[i].getId();
2585 // recover sequence association
2586 if (an[i].getSequenceRef() != null)
2588 if (al.findName(an[i].getSequenceRef()) != null)
2590 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2592 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2595 // and make a note of any group association
2596 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2598 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2599 .get(an[i].getGroupRef());
2602 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2603 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2608 if (an[i].hasScore())
2610 jaa.setScore(an[i].getScore());
2612 if (an[i].hasVisible())
2614 jaa.visible = an[i].getVisible();
2617 if (an[i].hasCentreColLabels())
2619 jaa.centreColLabels = an[i].getCentreColLabels();
2622 if (an[i].hasScaleColLabels())
2624 jaa.scaleColLabel = an[i].getScaleColLabels();
2626 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2628 // newer files have an 'autoCalculated' flag and store calculation
2629 // state in viewport properties
2630 jaa.autoCalculated = true; // means annotation will be marked for
2631 // update at end of load.
2633 if (an[i].hasGraphHeight())
2635 jaa.graphHeight = an[i].getGraphHeight();
2637 if (an[i].hasBelowAlignment())
2639 jaa.belowAlignment = an[i].isBelowAlignment();
2641 jaa.setCalcId(an[i].getCalcId());
2642 if (an[i].getPropertyCount() > 0)
2644 for (jalview.schemabinding.version2.Property prop : an[i]
2647 jaa.setProperty(prop.getName(), prop.getValue());
2650 if (jaa.autoCalculated)
2652 autoAlan.add(new JvAnnotRow(i, jaa));
2655 // if (!autoForView)
2657 // add autocalculated group annotation and any user created annotation
2659 al.addAnnotation(jaa);
2663 // ///////////////////////
2665 // Create alignment markup and styles for this view
2666 if (jms.getJGroupCount() > 0)
2668 JGroup[] groups = jms.getJGroup();
2669 boolean addAnnotSchemeGroup = false;
2670 for (int i = 0; i < groups.length; i++)
2672 ColourSchemeI cs = null;
2674 if (groups[i].getColour() != null)
2676 if (groups[i].getColour().startsWith("ucs"))
2678 cs = GetUserColourScheme(jms, groups[i].getColour());
2680 else if (groups[i].getColour().equals("AnnotationColourGradient")
2681 && groups[i].getAnnotationColours() != null)
2683 addAnnotSchemeGroup = true;
2688 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2693 cs.setThreshold(groups[i].getPidThreshold(), true);
2697 Vector seqs = new Vector();
2699 for (int s = 0; s < groups[i].getSeqCount(); s++)
2701 String seqId = groups[i].getSeq(s) + "";
2702 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2707 seqs.addElement(ts);
2711 if (seqs.size() < 1)
2716 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2717 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2718 groups[i].getDisplayText(), groups[i].getColourText(),
2719 groups[i].getStart(), groups[i].getEnd());
2721 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2723 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2724 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2725 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2726 .isShowUnconserved() : false);
2727 sg.thresholdTextColour = groups[i].getTextColThreshold();
2728 if (groups[i].hasShowConsensusHistogram())
2730 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2733 if (groups[i].hasShowSequenceLogo())
2735 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2737 if (groups[i].hasNormaliseSequenceLogo())
2739 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2741 if (groups[i].hasIgnoreGapsinConsensus())
2743 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2745 if (groups[i].getConsThreshold() != 0)
2747 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2748 "All", ResidueProperties.propHash, 3,
2749 sg.getSequences(null), 0, sg.getWidth() - 1);
2751 c.verdict(false, 25);
2752 sg.cs.setConservation(c);
2755 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2757 // re-instate unique group/annotation row reference
2758 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2759 .get(groups[i].getId());
2762 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2765 if (jaa.autoCalculated)
2767 // match up and try to set group autocalc alignment row for this
2769 if (jaa.label.startsWith("Consensus for "))
2771 sg.setConsensus(jaa);
2773 // match up and try to set group autocalc alignment row for this
2775 if (jaa.label.startsWith("Conservation for "))
2777 sg.setConservationRow(jaa);
2784 if (addAnnotSchemeGroup)
2786 // reconstruct the annotation colourscheme
2787 sg.cs = constructAnnotationColour(
2788 groups[i].getAnnotationColours(), null, al, jms, false);
2794 // only dataset in this model, so just return.
2797 // ///////////////////////////////
2800 // If we just load in the same jar file again, the sequenceSetId
2801 // will be the same, and we end up with multiple references
2802 // to the same sequenceSet. We must modify this id on load
2803 // so that each load of the file gives a unique id
2804 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2805 String viewId = (view.getId() == null ? null : view.getId()
2807 AlignFrame af = null;
2808 AlignViewport av = null;
2809 // now check to see if we really need to create a new viewport.
2810 if (multipleView && viewportsAdded.size() == 0)
2812 // We recovered an alignment for which a viewport already exists.
2813 // TODO: fix up any settings necessary for overlaying stored state onto
2814 // state recovered from another document. (may not be necessary).
2815 // we may need a binding from a viewport in memory to one recovered from
2817 // and then recover its containing af to allow the settings to be applied.
2818 // TODO: fix for vamsas demo
2820 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2822 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2823 if (seqsetobj != null)
2825 if (seqsetobj instanceof String)
2827 uniqueSeqSetId = (String) seqsetobj;
2829 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2835 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2841 * indicate that annotation colours are applied across all groups (pre
2842 * Jalview 2.8.1 behaviour)
2844 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2845 object.getVersion());
2847 AlignmentPanel ap = null;
2848 boolean isnewview = true;
2851 // Check to see if this alignment already has a view id == viewId
2852 jalview.gui.AlignmentPanel views[] = Desktop
2853 .getAlignmentPanels(uniqueSeqSetId);
2854 if (views != null && views.length > 0)
2856 for (int v = 0; v < views.length; v++)
2858 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2860 // recover the existing alignpanel, alignframe, viewport
2861 af = views[v].alignFrame;
2864 // TODO: could even skip resetting view settings if we don't want to
2865 // change the local settings from other jalview processes
2874 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2875 uniqueSeqSetId, viewId, autoAlan);
2880 // /////////////////////////////////////
2881 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2885 for (int t = 0; t < jms.getTreeCount(); t++)
2888 Tree tree = jms.getTree(t);
2890 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2893 tp = af.ShowNewickTree(
2894 new jalview.io.NewickFile(tree.getNewick()),
2895 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2896 tree.getXpos(), tree.getYpos());
2897 if (tree.getId() != null)
2899 // perhaps bind the tree id to something ?
2904 // update local tree attributes ?
2905 // TODO: should check if tp has been manipulated by user - if so its
2906 // settings shouldn't be modified
2907 tp.setTitle(tree.getTitle());
2908 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2909 .getWidth(), tree.getHeight()));
2910 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2913 tp.treeCanvas.av = av; // af.viewport;
2914 tp.treeCanvas.ap = ap; // af.alignPanel;
2919 warn("There was a problem recovering stored Newick tree: \n"
2920 + tree.getNewick());
2924 tp.fitToWindow.setState(tree.getFitToWindow());
2925 tp.fitToWindow_actionPerformed(null);
2927 if (tree.getFontName() != null)
2929 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2930 .getFontStyle(), tree.getFontSize()));
2934 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2935 .getFontStyle(), tree.getFontSize()));
2938 tp.showPlaceholders(tree.getMarkUnlinked());
2939 tp.showBootstrap(tree.getShowBootstrap());
2940 tp.showDistances(tree.getShowDistances());
2942 tp.treeCanvas.threshold = tree.getThreshold();
2944 if (tree.getCurrentTree())
2946 af.viewport.setCurrentTree(tp.getTree());
2950 } catch (Exception ex)
2952 ex.printStackTrace();
2956 // //LOAD STRUCTURES
2957 if (loadTreesAndStructures)
2959 // run through all PDB ids on the alignment, and collect mappings between
2960 // jmol view ids and all sequences referring to it
2961 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2963 for (int i = 0; i < JSEQ.length; i++)
2965 if (JSEQ[i].getPdbidsCount() > 0)
2967 Pdbids[] ids = JSEQ[i].getPdbids();
2968 for (int p = 0; p < ids.length; p++)
2970 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2972 // check to see if we haven't already created this structure view
2973 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2974 : ids[p].getStructureState(s).getViewId()
2976 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2977 // Originally : ids[p].getFile()
2978 // : TODO: verify external PDB file recovery still works in normal
2979 // jalview project load
2980 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2981 jpdb.setId(ids[p].getId());
2983 int x = ids[p].getStructureState(s).getXpos();
2984 int y = ids[p].getStructureState(s).getYpos();
2985 int width = ids[p].getStructureState(s).getWidth();
2986 int height = ids[p].getStructureState(s).getHeight();
2988 // Probably don't need to do this anymore...
2989 // Desktop.desktop.getComponentAt(x, y);
2990 // TODO: NOW: check that this recovers the PDB file correctly.
2991 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2992 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2993 .get(JSEQ[i].getId() + "");
2994 if (sviewid == null)
2996 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2999 if (!jmolViewIds.containsKey(sviewid))
3001 jmolViewIds.put(sviewid, new Object[]
3003 { x, y, width, height }, "",
3004 new Hashtable<String, Object[]>(), new boolean[]
3005 { false, false, true } });
3006 // Legacy pre-2.7 conversion JAL-823 :
3007 // do not assume any view has to be linked for colour by
3011 // assemble String[] { pdb files }, String[] { id for each
3012 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3013 // seqs_file 2}, boolean[] {
3014 // linkAlignPanel,superposeWithAlignpanel}} from hash
3015 Object[] jmoldat = jmolViewIds.get(sviewid);
3016 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
3017 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
3018 s).getAlignwithAlignPanel() : false;
3019 // never colour by linked panel if not specified
3020 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
3021 .hasColourwithAlignPanel() ? ids[p]
3022 .getStructureState(s).getColourwithAlignPanel()
3024 // default for pre-2.7 projects is that Jmol colouring is enabled
3025 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
3026 .hasColourByJmol() ? ids[p].getStructureState(s)
3027 .getColourByJmol() : true;
3029 if (((String) jmoldat[1]).length() < ids[p]
3030 .getStructureState(s).getContent().length())
3033 jmoldat[1] = ids[p].getStructureState(s).getContent();
3036 if (ids[p].getFile() != null)
3038 File mapkey = new File(ids[p].getFile());
3039 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3041 if (seqstrmaps == null)
3043 ((Hashtable) jmoldat[2]).put(mapkey,
3044 seqstrmaps = new Object[]
3045 { pdbFile, ids[p].getId(), new Vector(),
3048 if (!((Vector) seqstrmaps[2]).contains(seq))
3050 ((Vector) seqstrmaps[2]).addElement(seq);
3051 // ((Vector)seqstrmaps[3]).addElement(n) :
3052 // in principle, chains
3053 // should be stored here : do we need to
3054 // TODO: store and recover seq/pdb_id :
3060 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");
3069 // Instantiate the associated Jmol views
3070 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3072 String sviewid = entry.getKey();
3073 Object[] svattrib = entry.getValue();
3074 int[] geom = (int[]) svattrib[0];
3075 String state = (String) svattrib[1];
3076 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3077 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3078 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3079 // collate the pdbfile -> sequence mappings from this view
3080 Vector<String> pdbfilenames = new Vector<String>();
3081 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3082 Vector<String> pdbids = new Vector<String>();
3084 // Search to see if we've already created this Jmol view
3085 AppJmol comp = null;
3086 JInternalFrame[] frames = null;
3091 frames = Desktop.desktop.getAllFrames();
3092 } catch (ArrayIndexOutOfBoundsException e)
3094 // occasional No such child exceptions are thrown here...
3099 } catch (Exception f)
3104 } while (frames == null);
3105 // search for any Jmol windows already open from other
3106 // alignment views that exactly match the stored structure state
3107 for (int f = 0; comp == null && f < frames.length; f++)
3109 if (frames[f] instanceof AppJmol)
3112 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3114 // post jalview 2.4 schema includes structure view id
3115 comp = (AppJmol) frames[f];
3117 else if (frames[f].getX() == x && frames[f].getY() == y
3118 && frames[f].getHeight() == height
3119 && frames[f].getWidth() == width)
3121 comp = (AppJmol) frames[f];
3128 // create a new Jmol window.
3129 // First parse the Jmol state to translate filenames loaded into the
3130 // view, and record the order in which files are shown in the Jmol
3131 // view, so we can add the sequence mappings in same order.
3132 StringBuffer newFileLoc = null;
3133 int cp = 0, ncp, ecp;
3134 while ((ncp = state.indexOf("load ", cp)) > -1)
3136 if (newFileLoc == null)
3138 newFileLoc = new StringBuffer();
3142 // look for next filename in load statement
3143 newFileLoc.append(state.substring(cp,
3144 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3145 String oldfilenam = state.substring(ncp,
3146 ecp = state.indexOf("\"", ncp));
3147 // recover the new mapping data for this old filename
3148 // have to normalize filename - since Jmol and jalview do
3150 // translation differently.
3151 Object[] filedat = oldFiles.get(new File(oldfilenam));
3152 newFileLoc.append(Platform
3153 .escapeString((String) filedat[0]));
3154 pdbfilenames.addElement((String) filedat[0]);
3155 pdbids.addElement((String) filedat[1]);
3156 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3157 .toArray(new SequenceI[0]));
3158 newFileLoc.append("\"");
3159 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3160 // look for next file statement.
3161 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3165 // just append rest of state
3166 newFileLoc.append(state.substring(cp));
3171 .print("Ignoring incomplete Jmol state for PDB ids: ");
3172 newFileLoc = new StringBuffer(state);
3173 newFileLoc.append("; load append ");
3174 for (File id : oldFiles.keySet())
3176 // add this and any other pdb files that should be present in
3178 Object[] filedat = oldFiles.get(id);
3180 newFileLoc.append(((String) filedat[0]));
3181 pdbfilenames.addElement((String) filedat[0]);
3182 pdbids.addElement((String) filedat[1]);
3183 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3184 .toArray(new SequenceI[0]));
3185 newFileLoc.append(" \"");
3186 newFileLoc.append((String) filedat[0]);
3187 newFileLoc.append("\"");
3190 newFileLoc.append(";");
3193 if (newFileLoc != null)
3195 int histbug = newFileLoc.indexOf("history = ");
3197 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3199 String val = (diff == -1) ? null : newFileLoc.substring(
3201 if (val != null && val.length() >= 4)
3203 if (val.contains("e"))
3205 if (val.trim().equals("true"))
3213 newFileLoc.replace(histbug, diff, val);
3216 // TODO: assemble String[] { pdb files }, String[] { id for each
3217 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3218 // seqs_file 2}} from hash
3219 final String[] pdbf = pdbfilenames
3220 .toArray(new String[pdbfilenames.size()]), id = pdbids
3221 .toArray(new String[pdbids.size()]);
3222 final SequenceI[][] sq = seqmaps
3223 .toArray(new SequenceI[seqmaps.size()][]);
3224 final String fileloc = newFileLoc.toString(), vid = sviewid;
3225 final AlignFrame alf = af;
3226 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3230 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3235 JalviewStructureDisplayI sview = null;
3238 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3239 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3240 useinJmolsuperpos, usetoColourbyseq,
3241 jmolColouring, fileloc, rect, vid);
3242 addNewStructureViewer(sview);
3243 } catch (OutOfMemoryError ex)
3245 new OOMWarning("restoring structure view for PDB id "
3246 + id, (OutOfMemoryError) ex.getCause());
3247 if (sview != null && sview.isVisible())
3249 sview.closeViewer();
3250 sview.setVisible(false);
3256 } catch (InvocationTargetException ex)
3258 warn("Unexpected error when opening Jmol view.", ex);
3260 } catch (InterruptedException e)
3262 // e.printStackTrace();
3268 // if (comp != null)
3270 // NOTE: if the jalview project is part of a shared session then
3271 // view synchronization should/could be done here.
3273 // add mapping for sequences in this view to an already open Jmol
3275 for (File id : oldFiles.keySet())
3277 // add this and any other pdb files that should be present in the
3279 Object[] filedat = oldFiles.get(id);
3280 String pdbFile = (String) filedat[0];
3281 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3282 .toArray(new SequenceI[0]);
3283 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3284 jalview.io.AppletFormatAdapter.FILE);
3285 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3287 // and add the AlignmentPanel's reference to the Jmol view
3288 comp.addAlignmentPanel(ap);
3289 if (useinJmolsuperpos)
3291 comp.useAlignmentPanelForSuperposition(ap);
3295 comp.excludeAlignmentPanelForSuperposition(ap);
3297 if (usetoColourbyseq)
3299 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3303 comp.excludeAlignmentPanelForColourbyseq(ap);
3309 // and finally return.
3316 * - minimum version we are comparing against
3318 * - version of data being processsed.
3319 * @return true if version is development/null or evaluates to the same or
3320 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3322 private boolean isVersionStringLaterThan(String supported, String version)
3324 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3325 || version.equalsIgnoreCase("Test")
3326 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3328 System.err.println("Assuming project file with "
3329 + (version == null ? "null" : version)
3330 + " is compatible with Jalview version " + supported);
3335 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3337 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3339 // convert b to decimal to catch bugfix releases within a series
3340 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3341 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3344 if (Float.valueOf(curT) > Float.valueOf(fileT))
3346 // current version is newer than the version that wrote the file
3349 } catch (NumberFormatException nfe)
3352 .println("** WARNING: Version comparison failed for tokens ("
3356 + ")\n** Current: '"
3357 + supported + "' and Version: '" + version + "'");
3360 if (currentV.hasMoreElements())
3362 // fileV has no minor version but identical series to current
3369 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3371 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3373 if (newStructureViewers != null)
3375 sview.getBinding().setFinishedLoadingFromArchive(false);
3376 newStructureViewers.add(sview);
3380 protected void setLoadingFinishedForNewStructureViewers()
3382 if (newStructureViewers != null)
3384 for (JalviewStructureDisplayI sview : newStructureViewers)
3386 sview.getBinding().setFinishedLoadingFromArchive(true);
3388 newStructureViewers.clear();
3389 newStructureViewers = null;
3393 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3394 Alignment al, JalviewModelSequence jms, Viewport view,
3395 String uniqueSeqSetId, String viewId,
3396 ArrayList<JvAnnotRow> autoAlan)
3398 AlignFrame af = null;
3399 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3400 uniqueSeqSetId, viewId);
3402 af.setFileName(file, "Jalview");
3404 for (int i = 0; i < JSEQ.length; i++)
3406 af.viewport.setSequenceColour(af.viewport.getAlignment()
3407 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3410 af.viewport.gatherViewsHere = view.getGatheredViews();
3412 if (view.getSequenceSetId() != null)
3414 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3415 .get(uniqueSeqSetId);
3417 af.viewport.setSequenceSetId(uniqueSeqSetId);
3420 // propagate shared settings to this new view
3421 af.viewport.historyList = av.historyList;
3422 af.viewport.redoList = av.redoList;
3426 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3428 // TODO: check if this method can be called repeatedly without
3429 // side-effects if alignpanel already registered.
3430 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3432 // apply Hidden regions to view.
3433 if (hiddenSeqs != null)
3435 for (int s = 0; s < JSEQ.length; s++)
3437 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3439 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3442 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3444 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3447 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3450 for (int s = 0; s < hiddenSeqs.size(); s++)
3452 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3455 af.viewport.hideSequence(hseqs);
3458 // recover view properties and display parameters
3459 if (view.getViewName() != null)
3461 af.viewport.viewName = view.getViewName();
3462 af.setInitialTabVisible();
3464 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3467 af.viewport.setShowAnnotation(view.getShowAnnotation());
3468 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3470 af.viewport.setColourText(view.getShowColourText());
3472 af.viewport.setConservationSelected(view.getConservationSelected());
3473 af.viewport.setShowJVSuffix(view.getShowFullId());
3474 af.viewport.rightAlignIds = view.getRightAlignIds();
3475 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3476 .getFontStyle(), view.getFontSize()));
3477 af.alignPanel.fontChanged();
3478 af.viewport.setRenderGaps(view.getRenderGaps());
3479 af.viewport.setWrapAlignment(view.getWrapAlignment());
3480 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3481 af.viewport.setShowAnnotation(view.getShowAnnotation());
3482 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3484 af.viewport.setShowBoxes(view.getShowBoxes());
3486 af.viewport.setShowText(view.getShowText());
3488 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3489 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3490 af.viewport.thresholdTextColour = view.getTextColThreshold();
3491 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3492 .isShowUnconserved() : false);
3493 af.viewport.setStartRes(view.getStartRes());
3494 af.viewport.setStartSeq(view.getStartSeq());
3496 ColourSchemeI cs = null;
3497 // apply colourschemes
3498 if (view.getBgColour() != null)
3500 if (view.getBgColour().startsWith("ucs"))
3502 cs = GetUserColourScheme(jms, view.getBgColour());
3504 else if (view.getBgColour().startsWith("Annotation"))
3506 AnnotationColours viewAnnColour = view.getAnnotationColours();
3507 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3514 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3519 cs.setThreshold(view.getPidThreshold(), true);
3520 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3524 af.viewport.setGlobalColourScheme(cs);
3525 af.viewport.setColourAppliesToAllGroups(false);
3527 if (view.getConservationSelected() && cs != null)
3529 cs.setConservationInc(view.getConsThreshold());
3532 af.changeColour(cs);
3534 af.viewport.setColourAppliesToAllGroups(true);
3536 if (view.getShowSequenceFeatures())
3538 af.viewport.showSequenceFeatures = true;
3540 if (view.hasCentreColumnLabels())
3542 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3544 if (view.hasIgnoreGapsinConsensus())
3546 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3549 if (view.hasFollowHighlight())
3551 af.viewport.followHighlight = view.getFollowHighlight();
3553 if (view.hasFollowSelection())
3555 af.viewport.followSelection = view.getFollowSelection();
3557 if (view.hasShowConsensusHistogram())
3559 af.viewport.setShowConsensusHistogram(view
3560 .getShowConsensusHistogram());
3564 af.viewport.setShowConsensusHistogram(true);
3566 if (view.hasShowSequenceLogo())
3568 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3572 af.viewport.setShowSequenceLogo(false);
3574 if (view.hasNormaliseSequenceLogo())
3576 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3578 if (view.hasShowDbRefTooltip())
3580 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3582 if (view.hasShowNPfeatureTooltip())
3584 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3586 if (view.hasShowGroupConsensus())
3588 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3592 af.viewport.setShowGroupConsensus(false);
3594 if (view.hasShowGroupConservation())
3596 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3600 af.viewport.setShowGroupConservation(false);
3603 // recover featre settings
3604 if (jms.getFeatureSettings() != null)
3606 af.viewport.featuresDisplayed = new Hashtable();
3607 String[] renderOrder = new String[jms.getFeatureSettings()
3608 .getSettingCount()];
3609 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3611 Setting setting = jms.getFeatureSettings().getSetting(fs);
3612 if (setting.hasMincolour())
3614 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3615 new java.awt.Color(setting.getMincolour()),
3616 new java.awt.Color(setting.getColour()),
3617 setting.getMin(), setting.getMax()) : new GraduatedColor(
3618 new java.awt.Color(setting.getMincolour()),
3619 new java.awt.Color(setting.getColour()), 0, 1);
3620 if (setting.hasThreshold())
3622 gc.setThresh(setting.getThreshold());
3623 gc.setThreshType(setting.getThreshstate());
3625 gc.setAutoScaled(true); // default
3626 if (setting.hasAutoScale())
3628 gc.setAutoScaled(setting.getAutoScale());
3630 if (setting.hasColourByLabel())
3632 gc.setColourByLabel(setting.getColourByLabel());
3634 // and put in the feature colour table.
3635 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3636 setting.getType(), gc);
3640 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3642 new java.awt.Color(setting.getColour()));
3644 renderOrder[fs] = setting.getType();
3645 if (setting.hasOrder())
3647 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3648 setting.getType(), setting.getOrder());
3652 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3654 fs / jms.getFeatureSettings().getSettingCount());
3656 if (setting.getDisplay())
3658 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3659 setting.getColour()));
3662 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3664 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3665 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3667 Group grp = jms.getFeatureSettings().getGroup(gs);
3668 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3672 if (view.getHiddenColumnsCount() > 0)
3674 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3676 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3677 .getHiddenColumns(c).getEnd() // +1
3681 if (view.getCalcIdParam() != null)
3683 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3685 if (calcIdParam != null)
3687 if (recoverCalcIdParam(calcIdParam, af.viewport))
3692 warn("Couldn't recover parameters for "
3693 + calcIdParam.getCalcId());
3698 af.setMenusFromViewport(af.viewport);
3699 // TODO: we don't need to do this if the viewport is aready visible.
3700 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3702 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3703 reorderAutoannotation(af, al, autoAlan);
3704 af.alignPanel.alignmentChanged();
3708 private ColourSchemeI constructAnnotationColour(
3709 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3710 JalviewModelSequence jms, boolean checkGroupAnnColour)
3712 boolean propagateAnnColour = false;
3713 ColourSchemeI cs = null;
3714 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3715 if (checkGroupAnnColour && al.getGroups() != null
3716 && al.getGroups().size() > 0)
3718 // pre 2.8.1 behaviour
3719 // check to see if we should transfer annotation colours
3720 propagateAnnColour = true;
3721 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3723 if (sg.cs instanceof AnnotationColourGradient)
3725 propagateAnnColour = false;
3729 // int find annotation
3730 if (annAlignment.getAlignmentAnnotation() != null)
3732 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3734 if (annAlignment.getAlignmentAnnotation()[i].label
3735 .equals(viewAnnColour.getAnnotation()))
3737 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3739 annAlignment.getAlignmentAnnotation()[i]
3740 .setThreshold(new jalview.datamodel.GraphLine(
3741 viewAnnColour.getThreshold(), "Threshold",
3742 java.awt.Color.black)
3747 if (viewAnnColour.getColourScheme().equals("None"))
3749 cs = new AnnotationColourGradient(
3750 annAlignment.getAlignmentAnnotation()[i],
3751 new java.awt.Color(viewAnnColour.getMinColour()),
3752 new java.awt.Color(viewAnnColour.getMaxColour()),
3753 viewAnnColour.getAboveThreshold());
3755 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3757 cs = new AnnotationColourGradient(
3758 annAlignment.getAlignmentAnnotation()[i],
3759 GetUserColourScheme(jms,
3760 viewAnnColour.getColourScheme()),
3761 viewAnnColour.getAboveThreshold());
3765 cs = new AnnotationColourGradient(
3766 annAlignment.getAlignmentAnnotation()[i],
3767 ColourSchemeProperty.getColour(al,
3768 viewAnnColour.getColourScheme()),
3769 viewAnnColour.getAboveThreshold());
3771 if (viewAnnColour.hasPerSequence())
3773 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3776 if (viewAnnColour.hasPredefinedColours())
3778 ((AnnotationColourGradient) cs)
3779 .setPredefinedColours(viewAnnColour
3780 .isPredefinedColours());
3782 if (propagateAnnColour && al.getGroups() != null)
3784 // Also use these settings for all the groups
3785 for (int g = 0; g < al.getGroups().size(); g++)
3787 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3795 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3796 * new AnnotationColourGradient(
3797 * annAlignment.getAlignmentAnnotation()[i], new
3798 * java.awt.Color(viewAnnColour. getMinColour()), new
3799 * java.awt.Color(viewAnnColour. getMaxColour()),
3800 * viewAnnColour.getAboveThreshold()); } else
3803 sg.cs = new AnnotationColourGradient(
3804 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3805 viewAnnColour.getAboveThreshold());
3806 if (cs instanceof AnnotationColourGradient)
3808 if (viewAnnColour.hasPerSequence())
3810 ((AnnotationColourGradient) cs)
3811 .setSeqAssociated(viewAnnColour.isPerSequence());
3813 if (viewAnnColour.hasPredefinedColours())
3815 ((AnnotationColourGradient) cs)
3816 .setPredefinedColours(viewAnnColour
3817 .isPredefinedColours());
3833 private void reorderAutoannotation(AlignFrame af, Alignment al,
3834 ArrayList<JvAnnotRow> autoAlan)
3836 // copy over visualization settings for autocalculated annotation in the
3838 if (al.getAlignmentAnnotation() != null)
3841 * Kludge for magic autoannotation names (see JAL-811)
3843 String[] magicNames = new String[]
3844 { "Consensus", "Quality", "Conservation" };
3845 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3846 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3847 for (String nm : magicNames)
3849 visan.put(nm, nullAnnot);
3851 for (JvAnnotRow auan : autoAlan)
3853 visan.put(auan.template.label
3854 + (auan.template.getCalcId() == null ? "" : "\t"
3855 + auan.template.getCalcId()), auan);
3857 int hSize = al.getAlignmentAnnotation().length;
3858 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3859 // work through any autoCalculated annotation already on the view
3860 // removing it if it should be placed in a different location on the
3861 // annotation panel.
3862 List<String> remains = new ArrayList(visan.keySet());
3863 for (int h = 0; h < hSize; h++)
3865 jalview.datamodel.AlignmentAnnotation jalan = al
3866 .getAlignmentAnnotation()[h];
3867 if (jalan.autoCalculated)
3870 JvAnnotRow valan = visan.get(k = jalan.label);
3871 if (jalan.getCalcId() != null)
3873 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3878 // delete the auto calculated row from the alignment
3879 al.deleteAnnotation(jalan, false);
3883 if (valan != nullAnnot)
3885 if (jalan != valan.template)
3887 // newly created autoannotation row instance
3888 // so keep a reference to the visible annotation row
3889 // and copy over all relevant attributes
3890 if (valan.template.graphHeight >= 0)
3893 jalan.graphHeight = valan.template.graphHeight;
3895 jalan.visible = valan.template.visible;
3897 reorder.add(new JvAnnotRow(valan.order, jalan));
3902 // Add any (possibly stale) autocalculated rows that were not appended to
3903 // the view during construction
3904 for (String other : remains)
3906 JvAnnotRow othera = visan.get(other);
3907 if (othera != nullAnnot && othera.template.getCalcId() != null
3908 && othera.template.getCalcId().length() > 0)
3910 reorder.add(othera);
3913 // now put the automatic annotation in its correct place
3914 int s = 0, srt[] = new int[reorder.size()];
3915 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3916 for (JvAnnotRow jvar : reorder)
3919 srt[s++] = jvar.order;
3922 jalview.util.QuickSort.sort(srt, rws);
3923 // and re-insert the annotation at its correct position
3924 for (JvAnnotRow jvar : rws)
3926 al.addAnnotation(jvar.template, jvar.order);
3928 af.alignPanel.adjustAnnotationHeight();
3932 Hashtable skipList = null;
3935 * TODO remove this method
3938 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3939 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3940 * throw new Error("Implementation Error. No skipList defined for this
3941 * Jalview2XML instance."); } return (AlignFrame)
3942 * skipList.get(view.getSequenceSetId()); }
3946 * Check if the Jalview view contained in object should be skipped or not.
3949 * @return true if view's sequenceSetId is a key in skipList
3951 private boolean skipViewport(JalviewModel object)
3953 if (skipList == null)
3958 if (skipList.containsKey(id = object.getJalviewModelSequence()
3959 .getViewport()[0].getSequenceSetId()))
3961 if (Cache.log != null && Cache.log.isDebugEnabled())
3963 Cache.log.debug("Skipping seuqence set id " + id);
3970 public void AddToSkipList(AlignFrame af)
3972 if (skipList == null)
3974 skipList = new Hashtable();
3976 skipList.put(af.getViewport().getSequenceSetId(), af);
3979 public void clearSkipList()
3981 if (skipList != null)
3988 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3990 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3991 Vector dseqs = null;
3994 // create a list of new dataset sequences
3995 dseqs = new Vector();
3997 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3999 Sequence vamsasSeq = vamsasSet.getSequence(i);
4000 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
4002 // create a new dataset
4005 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4006 dseqs.copyInto(dsseqs);
4007 ds = new jalview.datamodel.Alignment(dsseqs);
4008 debug("Created new dataset " + vamsasSet.getDatasetId()
4009 + " for alignment " + System.identityHashCode(al));
4010 addDatasetRef(vamsasSet.getDatasetId(), ds);
4012 // set the dataset for the newly imported alignment.
4013 if (al.getDataset() == null)
4022 * sequence definition to create/merge dataset sequence for
4026 * vector to add new dataset sequence to
4028 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4029 AlignmentI ds, Vector dseqs)
4031 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4033 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4034 .get(vamsasSeq.getId());
4035 jalview.datamodel.SequenceI dsq = null;
4036 if (sq != null && sq.getDatasetSequence() != null)
4038 dsq = sq.getDatasetSequence();
4041 String sqid = vamsasSeq.getDsseqid();
4044 // need to create or add a new dataset sequence reference to this sequence
4047 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4052 // make a new dataset sequence
4053 dsq = sq.createDatasetSequence();
4056 // make up a new dataset reference for this sequence
4057 sqid = seqHash(dsq);
4059 dsq.setVamsasId(uniqueSetSuffix + sqid);
4060 seqRefIds.put(sqid, dsq);
4065 dseqs.addElement(dsq);
4070 ds.addSequence(dsq);
4076 { // make this dataset sequence sq's dataset sequence
4077 sq.setDatasetSequence(dsq);
4078 // and update the current dataset alignment
4083 if (!dseqs.contains(dsq))
4090 if (ds.findIndex(dsq) < 0)
4092 ds.addSequence(dsq);
4099 // TODO: refactor this as a merge dataset sequence function
4100 // now check that sq (the dataset sequence) sequence really is the union of
4101 // all references to it
4102 // boolean pre = sq.getStart() < dsq.getStart();
4103 // boolean post = sq.getEnd() > dsq.getEnd();
4107 StringBuffer sb = new StringBuffer();
4108 String newres = jalview.analysis.AlignSeq.extractGaps(
4109 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4110 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4111 && newres.length() > dsq.getLength())
4113 // Update with the longer sequence.
4117 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4118 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4119 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4120 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4122 dsq.setSequence(newres);
4124 // TODO: merges will never happen if we 'know' we have the real dataset
4125 // sequence - this should be detected when id==dssid
4127 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4128 // + (pre ? "prepended" : "") + " "
4129 // + (post ? "appended" : ""));
4134 java.util.Hashtable datasetIds = null;
4136 java.util.IdentityHashMap dataset2Ids = null;
4138 private Alignment getDatasetFor(String datasetId)
4140 if (datasetIds == null)
4142 datasetIds = new Hashtable();
4145 if (datasetIds.containsKey(datasetId))
4147 return (Alignment) datasetIds.get(datasetId);
4152 private void addDatasetRef(String datasetId, Alignment dataset)
4154 if (datasetIds == null)
4156 datasetIds = new Hashtable();
4158 datasetIds.put(datasetId, dataset);
4162 * make a new dataset ID for this jalview dataset alignment
4167 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4169 if (dataset.getDataset() != null)
4171 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4173 String datasetId = makeHashCode(dataset, null);
4174 if (datasetId == null)
4176 // make a new datasetId and record it
4177 if (dataset2Ids == null)
4179 dataset2Ids = new IdentityHashMap();
4183 datasetId = (String) dataset2Ids.get(dataset);
4185 if (datasetId == null)
4187 datasetId = "ds" + dataset2Ids.size() + 1;
4188 dataset2Ids.put(dataset, datasetId);
4194 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4196 for (int d = 0; d < sequence.getDBRefCount(); d++)
4198 DBRef dr = sequence.getDBRef(d);
4199 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4200 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4201 .getVersion(), sequence.getDBRef(d).getAccessionId());
4202 if (dr.getMapping() != null)
4204 entry.setMap(addMapping(dr.getMapping()));
4206 datasetSequence.addDBRef(entry);
4210 private jalview.datamodel.Mapping addMapping(Mapping m)
4212 SequenceI dsto = null;
4213 // Mapping m = dr.getMapping();
4214 int fr[] = new int[m.getMapListFromCount() * 2];
4215 Enumeration f = m.enumerateMapListFrom();
4216 for (int _i = 0; f.hasMoreElements(); _i += 2)
4218 MapListFrom mf = (MapListFrom) f.nextElement();
4219 fr[_i] = mf.getStart();
4220 fr[_i + 1] = mf.getEnd();
4222 int fto[] = new int[m.getMapListToCount() * 2];
4223 f = m.enumerateMapListTo();
4224 for (int _i = 0; f.hasMoreElements(); _i += 2)
4226 MapListTo mf = (MapListTo) f.nextElement();
4227 fto[_i] = mf.getStart();
4228 fto[_i + 1] = mf.getEnd();
4230 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4231 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4232 if (m.getMappingChoice() != null)
4234 MappingChoice mc = m.getMappingChoice();
4235 if (mc.getDseqFor() != null)
4237 String dsfor = "" + mc.getDseqFor();
4238 if (seqRefIds.containsKey(dsfor))
4243 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4247 frefedSequence.add(new Object[]
4254 * local sequence definition
4256 Sequence ms = mc.getSequence();
4257 jalview.datamodel.Sequence djs = null;
4258 String sqid = ms.getDsseqid();
4259 if (sqid != null && sqid.length() > 0)
4262 * recover dataset sequence
4264 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4269 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4270 sqid = ((Object) ms).toString(); // make up a new hascode for
4271 // undefined dataset sequence hash
4272 // (unlikely to happen)
4278 * make a new dataset sequence and add it to refIds hash
4280 djs = new jalview.datamodel.Sequence(ms.getName(),
4282 djs.setStart(jmap.getMap().getToLowest());
4283 djs.setEnd(jmap.getMap().getToHighest());
4284 djs.setVamsasId(uniqueSetSuffix + sqid);
4286 seqRefIds.put(sqid, djs);
4289 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4298 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4299 boolean keepSeqRefs)
4302 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4308 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4312 uniqueSetSuffix = "";
4313 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4318 if (this.frefedSequence == null)
4320 frefedSequence = new Vector();
4323 viewportsAdded = new Hashtable();
4325 AlignFrame af = LoadFromObject(jm, null, false, null);
4326 af.alignPanels.clear();
4327 af.closeMenuItem_actionPerformed(true);
4330 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4331 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4332 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4333 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4334 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4337 return af.alignPanel;
4341 * flag indicating if hashtables should be cleared on finalization TODO this
4342 * flag may not be necessary
4344 private final boolean _cleartables = true;
4346 private Hashtable jvids2vobj;
4351 * @see java.lang.Object#finalize()
4354 protected void finalize() throws Throwable
4356 // really make sure we have no buried refs left.
4361 this.seqRefIds = null;
4362 this.seqsToIds = null;
4366 private void warn(String msg)
4371 private void warn(String msg, Exception e)
4373 if (Cache.log != null)
4377 Cache.log.warn(msg, e);
4381 Cache.log.warn(msg);
4386 System.err.println("Warning: " + msg);
4389 e.printStackTrace();
4394 private void debug(String string)
4396 debug(string, null);
4399 private void debug(String msg, Exception e)
4401 if (Cache.log != null)
4405 Cache.log.debug(msg, e);
4409 Cache.log.debug(msg);
4414 System.err.println("Warning: " + msg);
4417 e.printStackTrace();
4423 * set the object to ID mapping tables used to write/recover objects and XML
4424 * ID strings for the jalview project. If external tables are provided then
4425 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4426 * object goes out of scope. - also populates the datasetIds hashtable with
4427 * alignment objects containing dataset sequences
4430 * Map from ID strings to jalview datamodel
4432 * Map from jalview datamodel to ID strings
4436 public void setObjectMappingTables(Hashtable vobj2jv,
4437 IdentityHashMap jv2vobj)
4439 this.jv2vobj = jv2vobj;
4440 this.vobj2jv = vobj2jv;
4441 Iterator ds = jv2vobj.keySet().iterator();
4443 while (ds.hasNext())
4445 Object jvobj = ds.next();
4446 id = jv2vobj.get(jvobj).toString();
4447 if (jvobj instanceof jalview.datamodel.Alignment)
4449 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4451 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4454 else if (jvobj instanceof jalview.datamodel.Sequence)
4456 // register sequence object so the XML parser can recover it.
4457 if (seqRefIds == null)
4459 seqRefIds = new Hashtable();
4461 if (seqsToIds == null)
4463 seqsToIds = new IdentityHashMap();
4465 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4466 seqsToIds.put(jvobj, id);
4468 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4470 if (annotationIds == null)
4472 annotationIds = new Hashtable();
4475 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4476 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4477 if (jvann.annotationId == null)
4479 jvann.annotationId = anid;
4481 if (!jvann.annotationId.equals(anid))
4483 // TODO verify that this is the correct behaviour
4484 this.warn("Overriding Annotation ID for " + anid
4485 + " from different id : " + jvann.annotationId);
4486 jvann.annotationId = anid;
4489 else if (jvobj instanceof String)
4491 if (jvids2vobj == null)
4493 jvids2vobj = new Hashtable();
4494 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4499 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4505 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4506 * objects created from the project archive. If string is null (default for
4507 * construction) then suffix will be set automatically.
4511 public void setUniqueSetSuffix(String string)
4513 uniqueSetSuffix = string;
4518 * uses skipList2 as the skipList for skipping views on sequence sets
4519 * associated with keys in the skipList
4523 public void setSkipList(Hashtable skipList2)
4525 skipList = skipList2;