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());
1423 AnnotationElement ae;
1424 if (aa[i].annotations != null)
1426 an.setScoreOnly(false);
1427 for (int a = 0; a < aa[i].annotations.length; a++)
1429 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1434 ae = new AnnotationElement();
1435 if (aa[i].annotations[a].description != null)
1437 ae.setDescription(aa[i].annotations[a].description);
1439 if (aa[i].annotations[a].displayCharacter != null)
1441 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1444 if (!Float.isNaN(aa[i].annotations[a].value))
1446 ae.setValue(aa[i].annotations[a].value);
1450 if (aa[i].annotations[a].secondaryStructure != ' '
1451 && aa[i].annotations[a].secondaryStructure != '\0')
1453 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1457 if (aa[i].annotations[a].colour != null
1458 && aa[i].annotations[a].colour != java.awt.Color.black)
1460 ae.setColour(aa[i].annotations[a].colour.getRGB());
1463 an.addAnnotationElement(ae);
1464 if (aa[i].autoCalculated)
1466 // only write one non-null entry into the annotation row -
1467 // sufficient to get the visualization attributes necessary to
1475 an.setScoreOnly(true);
1477 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1479 // skip autocalculated annotation - these are only provided for
1481 vamsasSet.addAnnotation(an);
1487 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1489 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1490 if (settings != null)
1492 CalcIdParam vCalcIdParam = new CalcIdParam();
1493 vCalcIdParam.setCalcId(calcId);
1494 vCalcIdParam.addServiceURL(settings.getServiceURI());
1495 // generic URI allowing a third party to resolve another instance of the
1496 // service used for this calculation
1497 for (String urls : settings.getServiceURLs())
1499 vCalcIdParam.addServiceURL(urls);
1501 vCalcIdParam.setVersion("1.0");
1502 if (settings.getPreset() != null)
1504 WsParamSetI setting = settings.getPreset();
1505 vCalcIdParam.setName(setting.getName());
1506 vCalcIdParam.setDescription(setting.getDescription());
1510 vCalcIdParam.setName("");
1511 vCalcIdParam.setDescription("Last used parameters");
1513 // need to be able to recover 1) settings 2) user-defined presets or
1514 // recreate settings from preset 3) predefined settings provided by
1515 // service - or settings that can be transferred (or discarded)
1516 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1518 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1519 // todo - decide if updateImmediately is needed for any projects.
1521 return vCalcIdParam;
1526 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1529 if (calcIdParam.getVersion().equals("1.0"))
1531 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1532 .getPreferredServiceFor(calcIdParam.getServiceURL());
1533 if (service != null)
1535 WsParamSetI parmSet = null;
1538 parmSet = service.getParamStore().parseServiceParameterFile(
1539 calcIdParam.getName(), calcIdParam.getDescription(),
1540 calcIdParam.getServiceURL(),
1541 calcIdParam.getParameters().replace("|\\n|", "\n"));
1542 } catch (IOException x)
1544 warn("Couldn't parse parameter data for "
1545 + calcIdParam.getCalcId(), x);
1548 List<ArgumentI> argList = null;
1549 if (calcIdParam.getName().length() > 0)
1551 parmSet = service.getParamStore()
1552 .getPreset(calcIdParam.getName());
1553 if (parmSet != null)
1555 // TODO : check we have a good match with settings in AACon -
1556 // otherwise we'll need to create a new preset
1561 argList = parmSet.getArguments();
1564 AAConSettings settings = new AAConSettings(
1565 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1566 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1567 calcIdParam.isNeedsUpdate());
1572 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1576 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1580 * External mapping between jalview objects and objects yielding a valid and
1581 * unique object ID string. This is null for normal Jalview project IO, but
1582 * non-null when a jalview project is being read or written as part of a
1585 IdentityHashMap jv2vobj = null;
1588 * Construct a unique ID for jvobj using either existing bindings or if none
1589 * exist, the result of the hashcode call for the object.
1592 * jalview data object
1593 * @return unique ID for referring to jvobj
1595 private String makeHashCode(Object jvobj, String altCode)
1597 if (jv2vobj != null)
1599 Object id = jv2vobj.get(jvobj);
1602 return id.toString();
1604 // check string ID mappings
1605 if (jvids2vobj != null && jvobj instanceof String)
1607 id = jvids2vobj.get(jvobj);
1611 return id.toString();
1613 // give up and warn that something has gone wrong
1614 warn("Cannot find ID for object in external mapping : " + jvobj);
1620 * return local jalview object mapped to ID, if it exists
1624 * @return null or object bound to idcode
1626 private Object retrieveExistingObj(String idcode)
1628 if (idcode != null && vobj2jv != null)
1630 return vobj2jv.get(idcode);
1636 * binding from ID strings from external mapping table to jalview data model
1639 private Hashtable vobj2jv;
1641 private Sequence createVamsasSequence(String id, SequenceI jds)
1643 return createVamsasSequence(true, id, jds, null);
1646 private Sequence createVamsasSequence(boolean recurse, String id,
1647 SequenceI jds, SequenceI parentseq)
1649 Sequence vamsasSeq = new Sequence();
1650 vamsasSeq.setId(id);
1651 vamsasSeq.setName(jds.getName());
1652 vamsasSeq.setSequence(jds.getSequenceAsString());
1653 vamsasSeq.setDescription(jds.getDescription());
1654 jalview.datamodel.DBRefEntry[] dbrefs = null;
1655 if (jds.getDatasetSequence() != null)
1657 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1658 if (jds.getDatasetSequence().getDBRef() != null)
1660 dbrefs = jds.getDatasetSequence().getDBRef();
1665 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1666 // dataset sequences only
1667 dbrefs = jds.getDBRef();
1671 for (int d = 0; d < dbrefs.length; d++)
1673 DBRef dbref = new DBRef();
1674 dbref.setSource(dbrefs[d].getSource());
1675 dbref.setVersion(dbrefs[d].getVersion());
1676 dbref.setAccessionId(dbrefs[d].getAccessionId());
1677 if (dbrefs[d].hasMap())
1679 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1681 dbref.setMapping(mp);
1683 vamsasSeq.addDBRef(dbref);
1689 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1690 SequenceI parentseq, SequenceI jds, boolean recurse)
1693 if (jmp.getMap() != null)
1697 jalview.util.MapList mlst = jmp.getMap();
1698 int r[] = mlst.getFromRanges();
1699 for (int s = 0; s < r.length; s += 2)
1701 MapListFrom mfrom = new MapListFrom();
1702 mfrom.setStart(r[s]);
1703 mfrom.setEnd(r[s + 1]);
1704 mp.addMapListFrom(mfrom);
1706 r = mlst.getToRanges();
1707 for (int s = 0; s < r.length; s += 2)
1709 MapListTo mto = new MapListTo();
1711 mto.setEnd(r[s + 1]);
1712 mp.addMapListTo(mto);
1714 mp.setMapFromUnit(mlst.getFromRatio());
1715 mp.setMapToUnit(mlst.getToRatio());
1716 if (jmp.getTo() != null)
1718 MappingChoice mpc = new MappingChoice();
1720 && (parentseq != jmp.getTo() || parentseq
1721 .getDatasetSequence() != jmp.getTo()))
1723 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1729 SequenceI ps = null;
1730 if (parentseq != jmp.getTo()
1731 && parentseq.getDatasetSequence() != jmp.getTo())
1733 // chaining dbref rather than a handshaking one
1734 jmpid = seqHash(ps = jmp.getTo());
1738 jmpid = seqHash(ps = parentseq);
1740 mpc.setDseqFor(jmpid);
1741 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1743 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1744 seqRefIds.put(mpc.getDseqFor(), ps);
1748 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1751 mp.setMappingChoice(mpc);
1757 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1758 Vector userColours, JalviewModelSequence jms)
1761 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1762 boolean newucs = false;
1763 if (!userColours.contains(ucs))
1765 userColours.add(ucs);
1768 id = "ucs" + userColours.indexOf(ucs);
1771 // actually create the scheme's entry in the XML model
1772 java.awt.Color[] colours = ucs.getColours();
1773 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1774 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1776 for (int i = 0; i < colours.length; i++)
1778 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1779 col.setName(ResidueProperties.aa[i]);
1780 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1781 jbucs.addColour(col);
1783 if (ucs.getLowerCaseColours() != null)
1785 colours = ucs.getLowerCaseColours();
1786 for (int i = 0; i < colours.length; i++)
1788 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1789 col.setName(ResidueProperties.aa[i].toLowerCase());
1790 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1791 jbucs.addColour(col);
1796 uc.setUserColourScheme(jbucs);
1797 jms.addUserColours(uc);
1803 jalview.schemes.UserColourScheme GetUserColourScheme(
1804 JalviewModelSequence jms, String id)
1806 UserColours[] uc = jms.getUserColours();
1807 UserColours colours = null;
1809 for (int i = 0; i < uc.length; i++)
1811 if (uc[i].getId().equals(id))
1819 java.awt.Color[] newColours = new java.awt.Color[24];
1821 for (int i = 0; i < 24; i++)
1823 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1824 .getUserColourScheme().getColour(i).getRGB(), 16));
1827 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1830 if (colours.getUserColourScheme().getColourCount() > 24)
1832 newColours = new java.awt.Color[23];
1833 for (int i = 0; i < 23; i++)
1835 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1836 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1838 ucs.setLowerCaseColours(newColours);
1845 * contains last error message (if any) encountered by XML loader.
1847 String errorMessage = null;
1850 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1851 * exceptions are raised during project XML parsing
1853 public boolean attemptversion1parse = true;
1856 * Load a jalview project archive from a jar file
1859 * - HTTP URL or filename
1861 public AlignFrame LoadJalviewAlign(final String file)
1864 jalview.gui.AlignFrame af = null;
1868 // create list to store references for any new Jmol viewers created
1869 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1870 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1871 // Workaround is to make sure caller implements the JarInputStreamProvider
1873 // so we can re-open the jar input stream for each entry.
1875 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1876 af = LoadJalviewAlign(jprovider);
1878 } catch (MalformedURLException e)
1880 errorMessage = "Invalid URL format for '" + file + "'";
1886 SwingUtilities.invokeAndWait(new Runnable()
1890 setLoadingFinishedForNewStructureViewers();
1893 } catch (Exception x)
1901 private jarInputStreamProvider createjarInputStreamProvider(
1902 final String file) throws MalformedURLException
1905 errorMessage = null;
1906 uniqueSetSuffix = null;
1908 viewportsAdded = null;
1909 frefedSequence = null;
1911 if (file.startsWith("http://"))
1913 url = new URL(file);
1915 final URL _url = url;
1916 return new jarInputStreamProvider()
1920 public JarInputStream getJarInputStream() throws IOException
1924 return new JarInputStream(_url.openStream());
1928 return new JarInputStream(new FileInputStream(file));
1933 public String getFilename()
1941 * Recover jalview session from a jalview project archive. Caller may
1942 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1943 * themselves. Any null fields will be initialised with default values,
1944 * non-null fields are left alone.
1949 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1951 errorMessage = null;
1952 if (uniqueSetSuffix == null)
1954 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1956 if (seqRefIds == null)
1958 seqRefIds = new Hashtable();
1960 if (viewportsAdded == null)
1962 viewportsAdded = new Hashtable();
1964 if (frefedSequence == null)
1966 frefedSequence = new Vector();
1969 jalview.gui.AlignFrame af = null, _af = null;
1970 Hashtable gatherToThisFrame = new Hashtable();
1971 final String file = jprovider.getFilename();
1974 JarInputStream jin = null;
1975 JarEntry jarentry = null;
1980 jin = jprovider.getJarInputStream();
1981 for (int i = 0; i < entryCount; i++)
1983 jarentry = jin.getNextJarEntry();
1986 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1988 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1989 JalviewModel object = new JalviewModel();
1991 Unmarshaller unmar = new Unmarshaller(object);
1992 unmar.setValidation(false);
1993 object = (JalviewModel) unmar.unmarshal(in);
1994 if (true) // !skipViewport(object))
1996 _af = LoadFromObject(object, file, true, jprovider);
1997 if (object.getJalviewModelSequence().getViewportCount() > 0)
2000 if (af.viewport.gatherViewsHere)
2002 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2008 else if (jarentry != null)
2010 // Some other file here.
2013 } while (jarentry != null);
2014 resolveFrefedSequences();
2015 } catch (java.io.FileNotFoundException ex)
2017 ex.printStackTrace();
2018 errorMessage = "Couldn't locate Jalview XML file : " + file;
2019 System.err.println("Exception whilst loading jalview XML file : "
2021 } catch (java.net.UnknownHostException ex)
2023 ex.printStackTrace();
2024 errorMessage = "Couldn't locate Jalview XML file : " + file;
2025 System.err.println("Exception whilst loading jalview XML file : "
2027 } catch (Exception ex)
2029 System.err.println("Parsing as Jalview Version 2 file failed.");
2030 ex.printStackTrace(System.err);
2031 if (attemptversion1parse)
2033 // Is Version 1 Jar file?
2036 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2037 } catch (Exception ex2)
2039 System.err.println("Exception whilst loading as jalviewXMLV1:");
2040 ex2.printStackTrace();
2044 if (Desktop.instance != null)
2046 Desktop.instance.stopLoading();
2050 System.out.println("Successfully loaded archive file");
2053 ex.printStackTrace();
2055 System.err.println("Exception whilst loading jalview XML file : "
2057 } catch (OutOfMemoryError e)
2059 // Don't use the OOM Window here
2060 errorMessage = "Out of memory loading jalview XML file";
2061 System.err.println("Out of memory whilst loading jalview XML file");
2062 e.printStackTrace();
2065 if (Desktop.instance != null)
2067 Desktop.instance.stopLoading();
2070 Enumeration en = gatherToThisFrame.elements();
2071 while (en.hasMoreElements())
2073 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2075 if (errorMessage != null)
2083 * check errorMessage for a valid error message and raise an error box in the
2084 * GUI or write the current errorMessage to stderr and then clear the error
2087 protected void reportErrors()
2089 reportErrors(false);
2092 protected void reportErrors(final boolean saving)
2094 if (errorMessage != null)
2096 final String finalErrorMessage = errorMessage;
2099 javax.swing.SwingUtilities.invokeLater(new Runnable()
2104 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2105 finalErrorMessage, "Error "
2106 + (saving ? "saving" : "loading")
2107 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2113 System.err.println("Problem loading Jalview file: " + errorMessage);
2116 errorMessage = null;
2119 Hashtable<String, String> alreadyLoadedPDB;
2122 * when set, local views will be updated from view stored in JalviewXML
2123 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2124 * sync if this is set to true.
2126 private final boolean updateLocalViews = false;
2128 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2130 if (alreadyLoadedPDB == null)
2132 alreadyLoadedPDB = new Hashtable();
2135 if (alreadyLoadedPDB.containsKey(pdbId))
2137 return alreadyLoadedPDB.get(pdbId).toString();
2142 JarInputStream jin = jprovider.getJarInputStream();
2144 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2145 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2146 * FileInputStream(jprovider)); }
2149 JarEntry entry = null;
2152 entry = jin.getNextJarEntry();
2153 } while (entry != null && !entry.getName().equals(pdbId));
2156 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2157 File outFile = File.createTempFile("jalview_pdb", ".txt");
2158 outFile.deleteOnExit();
2159 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2162 while ((data = in.readLine()) != null)
2169 } catch (Exception foo)
2174 String t = outFile.getAbsolutePath();
2175 alreadyLoadedPDB.put(pdbId, t);
2180 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2182 } catch (Exception ex)
2184 ex.printStackTrace();
2190 private class JvAnnotRow
2192 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2199 * persisted version of annotation row from which to take vis properties
2201 public jalview.datamodel.AlignmentAnnotation template;
2204 * original position of the annotation row in the alignment
2210 * Load alignment frame from jalview XML DOM object
2215 * filename source string
2216 * @param loadTreesAndStructures
2217 * when false only create Viewport
2219 * data source provider
2220 * @return alignment frame created from view stored in DOM
2222 AlignFrame LoadFromObject(JalviewModel object, String file,
2223 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2225 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2226 Sequence[] vamsasSeq = vamsasSet.getSequence();
2228 JalviewModelSequence jms = object.getJalviewModelSequence();
2230 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2233 // ////////////////////////////////
2236 Vector hiddenSeqs = null;
2237 jalview.datamodel.Sequence jseq;
2239 ArrayList tmpseqs = new ArrayList();
2241 boolean multipleView = false;
2243 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2244 int vi = 0; // counter in vamsasSeq array
2245 for (int i = 0; i < JSEQ.length; i++)
2247 String seqId = JSEQ[i].getId();
2249 if (seqRefIds.get(seqId) != null)
2251 tmpseqs.add(seqRefIds.get(seqId));
2252 multipleView = true;
2256 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2257 vamsasSeq[vi].getSequence());
2258 jseq.setDescription(vamsasSeq[vi].getDescription());
2259 jseq.setStart(JSEQ[i].getStart());
2260 jseq.setEnd(JSEQ[i].getEnd());
2261 jseq.setVamsasId(uniqueSetSuffix + seqId);
2262 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2267 if (JSEQ[i].getHidden())
2269 if (hiddenSeqs == null)
2271 hiddenSeqs = new Vector();
2274 hiddenSeqs.addElement(seqRefIds.get(seqId));
2280 // Create the alignment object from the sequence set
2281 // ///////////////////////////////
2282 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2285 tmpseqs.toArray(orderedSeqs);
2287 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2290 // / Add the alignment properties
2291 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2293 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2294 al.setProperty(ssp.getKey(), ssp.getValue());
2298 // SequenceFeatures are added to the DatasetSequence,
2299 // so we must create or recover the dataset before loading features
2300 // ///////////////////////////////
2301 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2303 // older jalview projects do not have a dataset id.
2304 al.setDataset(null);
2308 recoverDatasetFor(vamsasSet, al);
2310 // ///////////////////////////////
2312 Hashtable pdbloaded = new Hashtable();
2315 // load sequence features, database references and any associated PDB
2316 // structures for the alignment
2317 for (int i = 0; i < vamsasSeq.length; i++)
2319 if (JSEQ[i].getFeaturesCount() > 0)
2321 Features[] features = JSEQ[i].getFeatures();
2322 for (int f = 0; f < features.length; f++)
2324 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2325 features[f].getType(), features[f].getDescription(),
2326 features[f].getStatus(), features[f].getBegin(),
2327 features[f].getEnd(), features[f].getFeatureGroup());
2329 sf.setScore(features[f].getScore());
2330 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2332 OtherData keyValue = features[f].getOtherData(od);
2333 if (keyValue.getKey().startsWith("LINK"))
2335 sf.addLink(keyValue.getValue());
2339 sf.setValue(keyValue.getKey(), keyValue.getValue());
2344 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2347 if (vamsasSeq[i].getDBRefCount() > 0)
2349 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2351 if (JSEQ[i].getPdbidsCount() > 0)
2353 Pdbids[] ids = JSEQ[i].getPdbids();
2354 for (int p = 0; p < ids.length; p++)
2356 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2357 entry.setId(ids[p].getId());
2358 entry.setType(ids[p].getType());
2359 if (ids[p].getFile() != null)
2361 if (!pdbloaded.containsKey(ids[p].getFile()))
2363 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2367 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2370 StructureSelectionManager.getStructureSelectionManager(
2372 .registerPDBEntry(entry);
2373 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2377 } // end !multipleview
2379 // ///////////////////////////////
2380 // LOAD SEQUENCE MAPPINGS
2382 if (vamsasSet.getAlcodonFrameCount() > 0)
2384 // TODO Potentially this should only be done once for all views of an
2386 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2387 for (int i = 0; i < alc.length; i++)
2389 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2390 alc[i].getAlcodonCount());
2391 if (alc[i].getAlcodonCount() > 0)
2393 Alcodon[] alcods = alc[i].getAlcodon();
2394 for (int p = 0; p < cf.codons.length; p++)
2396 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2397 && alcods[p].hasPos3())
2399 // translated codons require three valid positions
2400 cf.codons[p] = new int[3];
2401 cf.codons[p][0] = (int) alcods[p].getPos1();
2402 cf.codons[p][1] = (int) alcods[p].getPos2();
2403 cf.codons[p][2] = (int) alcods[p].getPos3();
2407 cf.codons[p] = null;
2411 if (alc[i].getAlcodMapCount() > 0)
2413 AlcodMap[] maps = alc[i].getAlcodMap();
2414 for (int m = 0; m < maps.length; m++)
2416 SequenceI dnaseq = (SequenceI) seqRefIds
2417 .get(maps[m].getDnasq());
2419 jalview.datamodel.Mapping mapping = null;
2420 // attach to dna sequence reference.
2421 if (maps[m].getMapping() != null)
2423 mapping = addMapping(maps[m].getMapping());
2427 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2432 frefedSequence.add(new Object[]
2433 { maps[m].getDnasq(), cf, mapping });
2437 al.addCodonFrame(cf);
2442 // ////////////////////////////////
2444 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2446 * store any annotations which forward reference a group's ID
2448 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2450 if (vamsasSet.getAnnotationCount() > 0)
2452 Annotation[] an = vamsasSet.getAnnotation();
2454 for (int i = 0; i < an.length; i++)
2457 * test if annotation is automatically calculated for this view only
2459 boolean autoForView = false;
2460 if (an[i].getLabel().equals("Quality")
2461 || an[i].getLabel().equals("Conservation")
2462 || an[i].getLabel().equals("Consensus"))
2464 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2466 if (!an[i].hasAutoCalculated())
2468 an[i].setAutoCalculated(true);
2472 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2474 // remove ID - we don't recover annotation from other views for
2475 // view-specific annotation
2479 // set visiblity for other annotation in this view
2480 if (an[i].getId() != null
2481 && annotationIds.containsKey(an[i].getId()))
2483 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2484 .get(an[i].getId());
2485 // in principle Visible should always be true for annotation displayed
2486 // in multiple views
2487 if (an[i].hasVisible())
2489 jda.visible = an[i].getVisible();
2492 al.addAnnotation(jda);
2496 // Construct new annotation from model.
2497 AnnotationElement[] ae = an[i].getAnnotationElement();
2498 jalview.datamodel.Annotation[] anot = null;
2499 java.awt.Color firstColour = null;
2501 if (!an[i].getScoreOnly())
2503 anot = new jalview.datamodel.Annotation[al.getWidth()];
2504 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2506 anpos = ae[aa].getPosition();
2508 if (anpos >= anot.length)
2513 anot[anpos] = new jalview.datamodel.Annotation(
2515 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2516 (ae[aa].getSecondaryStructure() == null || ae[aa]
2517 .getSecondaryStructure().length() == 0) ? ' '
2518 : ae[aa].getSecondaryStructure().charAt(0),
2522 // JBPNote: Consider verifying dataflow for IO of secondary
2523 // structure annotation read from Stockholm files
2524 // this was added to try to ensure that
2525 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2527 // anot[ae[aa].getPosition()].displayCharacter = "";
2529 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2530 if (firstColour == null)
2532 firstColour = anot[anpos].colour;
2536 jalview.datamodel.AlignmentAnnotation jaa = null;
2538 if (an[i].getGraph())
2540 float llim = 0, hlim = 0;
2541 // if (autoForView || an[i].isAutoCalculated()) {
2544 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2545 an[i].getDescription(), anot, llim, hlim,
2546 an[i].getGraphType());
2548 jaa.graphGroup = an[i].getGraphGroup();
2549 jaa._linecolour = firstColour;
2550 if (an[i].getThresholdLine() != null)
2552 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2553 .getThresholdLine().getValue(), an[i]
2554 .getThresholdLine().getLabel(), new java.awt.Color(
2555 an[i].getThresholdLine().getColour())));
2558 if (autoForView || an[i].isAutoCalculated())
2560 // Hardwire the symbol display line to ensure that labels for
2561 // histograms are displayed
2567 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2568 an[i].getDescription(), anot);
2569 jaa._linecolour = firstColour;
2571 // register new annotation
2572 if (an[i].getId() != null)
2574 annotationIds.put(an[i].getId(), jaa);
2575 jaa.annotationId = an[i].getId();
2577 // recover sequence association
2578 if (an[i].getSequenceRef() != null)
2580 if (al.findName(an[i].getSequenceRef()) != null)
2582 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2584 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2587 // and make a note of any group association
2588 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2590 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2591 .get(an[i].getGroupRef());
2594 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2595 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2600 if (an[i].hasScore())
2602 jaa.setScore(an[i].getScore());
2604 if (an[i].hasVisible())
2606 jaa.visible = an[i].getVisible();
2609 if (an[i].hasCentreColLabels())
2611 jaa.centreColLabels = an[i].getCentreColLabels();
2614 if (an[i].hasScaleColLabels())
2616 jaa.scaleColLabel = an[i].getScaleColLabels();
2618 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2620 // newer files have an 'autoCalculated' flag and store calculation
2621 // state in viewport properties
2622 jaa.autoCalculated = true; // means annotation will be marked for
2623 // update at end of load.
2625 if (an[i].hasGraphHeight())
2627 jaa.graphHeight = an[i].getGraphHeight();
2629 if (an[i].hasBelowAlignment())
2631 jaa.belowAlignment = an[i].isBelowAlignment();
2633 jaa.setCalcId(an[i].getCalcId());
2634 if (jaa.autoCalculated)
2636 autoAlan.add(new JvAnnotRow(i, jaa));
2639 // if (!autoForView)
2641 // add autocalculated group annotation and any user created annotation
2643 al.addAnnotation(jaa);
2647 // ///////////////////////
2649 // Create alignment markup and styles for this view
2650 if (jms.getJGroupCount() > 0)
2652 JGroup[] groups = jms.getJGroup();
2653 boolean addAnnotSchemeGroup = false;
2654 for (int i = 0; i < groups.length; i++)
2656 ColourSchemeI cs = null;
2658 if (groups[i].getColour() != null)
2660 if (groups[i].getColour().startsWith("ucs"))
2662 cs = GetUserColourScheme(jms, groups[i].getColour());
2664 else if (groups[i].getColour().equals("AnnotationColourGradient")
2665 && groups[i].getAnnotationColours() != null)
2667 addAnnotSchemeGroup = true;
2672 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2677 cs.setThreshold(groups[i].getPidThreshold(), true);
2681 Vector seqs = new Vector();
2683 for (int s = 0; s < groups[i].getSeqCount(); s++)
2685 String seqId = groups[i].getSeq(s) + "";
2686 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2691 seqs.addElement(ts);
2695 if (seqs.size() < 1)
2700 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2701 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2702 groups[i].getDisplayText(), groups[i].getColourText(),
2703 groups[i].getStart(), groups[i].getEnd());
2705 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2707 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2708 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2709 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2710 .isShowUnconserved() : false);
2711 sg.thresholdTextColour = groups[i].getTextColThreshold();
2712 if (groups[i].hasShowConsensusHistogram())
2714 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2717 if (groups[i].hasShowSequenceLogo())
2719 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2721 if (groups[i].hasNormaliseSequenceLogo())
2723 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2725 if (groups[i].hasIgnoreGapsinConsensus())
2727 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2729 if (groups[i].getConsThreshold() != 0)
2731 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2732 "All", ResidueProperties.propHash, 3,
2733 sg.getSequences(null), 0, sg.getWidth() - 1);
2735 c.verdict(false, 25);
2736 sg.cs.setConservation(c);
2739 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2741 // re-instate unique group/annotation row reference
2742 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2743 .get(groups[i].getId());
2746 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2749 if (jaa.autoCalculated)
2751 // match up and try to set group autocalc alignment row for this
2753 if (jaa.label.startsWith("Consensus for "))
2755 sg.setConsensus(jaa);
2757 // match up and try to set group autocalc alignment row for this
2759 if (jaa.label.startsWith("Conservation for "))
2761 sg.setConservationRow(jaa);
2768 if (addAnnotSchemeGroup)
2770 // reconstruct the annotation colourscheme
2771 sg.cs = constructAnnotationColour(
2772 groups[i].getAnnotationColours(), null, al, jms, false);
2778 // only dataset in this model, so just return.
2781 // ///////////////////////////////
2784 // If we just load in the same jar file again, the sequenceSetId
2785 // will be the same, and we end up with multiple references
2786 // to the same sequenceSet. We must modify this id on load
2787 // so that each load of the file gives a unique id
2788 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2789 String viewId = (view.getId() == null ? null : view.getId()
2791 AlignFrame af = null;
2792 AlignViewport av = null;
2793 // now check to see if we really need to create a new viewport.
2794 if (multipleView && viewportsAdded.size() == 0)
2796 // We recovered an alignment for which a viewport already exists.
2797 // TODO: fix up any settings necessary for overlaying stored state onto
2798 // state recovered from another document. (may not be necessary).
2799 // we may need a binding from a viewport in memory to one recovered from
2801 // and then recover its containing af to allow the settings to be applied.
2802 // TODO: fix for vamsas demo
2804 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2806 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2807 if (seqsetobj != null)
2809 if (seqsetobj instanceof String)
2811 uniqueSeqSetId = (String) seqsetobj;
2813 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2819 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2825 * indicate that annotation colours are applied across all groups (pre
2826 * Jalview 2.8.1 behaviour)
2828 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2829 object.getVersion());
2831 AlignmentPanel ap = null;
2832 boolean isnewview = true;
2835 // Check to see if this alignment already has a view id == viewId
2836 jalview.gui.AlignmentPanel views[] = Desktop
2837 .getAlignmentPanels(uniqueSeqSetId);
2838 if (views != null && views.length > 0)
2840 for (int v = 0; v < views.length; v++)
2842 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2844 // recover the existing alignpanel, alignframe, viewport
2845 af = views[v].alignFrame;
2848 // TODO: could even skip resetting view settings if we don't want to
2849 // change the local settings from other jalview processes
2858 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2859 uniqueSeqSetId, viewId, autoAlan);
2864 // /////////////////////////////////////
2865 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2869 for (int t = 0; t < jms.getTreeCount(); t++)
2872 Tree tree = jms.getTree(t);
2874 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2877 tp = af.ShowNewickTree(
2878 new jalview.io.NewickFile(tree.getNewick()),
2879 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2880 tree.getXpos(), tree.getYpos());
2881 if (tree.getId() != null)
2883 // perhaps bind the tree id to something ?
2888 // update local tree attributes ?
2889 // TODO: should check if tp has been manipulated by user - if so its
2890 // settings shouldn't be modified
2891 tp.setTitle(tree.getTitle());
2892 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2893 .getWidth(), tree.getHeight()));
2894 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2897 tp.treeCanvas.av = av; // af.viewport;
2898 tp.treeCanvas.ap = ap; // af.alignPanel;
2903 warn("There was a problem recovering stored Newick tree: \n"
2904 + tree.getNewick());
2908 tp.fitToWindow.setState(tree.getFitToWindow());
2909 tp.fitToWindow_actionPerformed(null);
2911 if (tree.getFontName() != null)
2913 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2914 .getFontStyle(), tree.getFontSize()));
2918 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2919 .getFontStyle(), tree.getFontSize()));
2922 tp.showPlaceholders(tree.getMarkUnlinked());
2923 tp.showBootstrap(tree.getShowBootstrap());
2924 tp.showDistances(tree.getShowDistances());
2926 tp.treeCanvas.threshold = tree.getThreshold();
2928 if (tree.getCurrentTree())
2930 af.viewport.setCurrentTree(tp.getTree());
2934 } catch (Exception ex)
2936 ex.printStackTrace();
2940 // //LOAD STRUCTURES
2941 if (loadTreesAndStructures)
2943 // run through all PDB ids on the alignment, and collect mappings between
2944 // jmol view ids and all sequences referring to it
2945 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2947 for (int i = 0; i < JSEQ.length; i++)
2949 if (JSEQ[i].getPdbidsCount() > 0)
2951 Pdbids[] ids = JSEQ[i].getPdbids();
2952 for (int p = 0; p < ids.length; p++)
2954 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2956 // check to see if we haven't already created this structure view
2957 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2958 : ids[p].getStructureState(s).getViewId()
2960 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2961 // Originally : ids[p].getFile()
2962 // : TODO: verify external PDB file recovery still works in normal
2963 // jalview project load
2964 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2965 jpdb.setId(ids[p].getId());
2967 int x = ids[p].getStructureState(s).getXpos();
2968 int y = ids[p].getStructureState(s).getYpos();
2969 int width = ids[p].getStructureState(s).getWidth();
2970 int height = ids[p].getStructureState(s).getHeight();
2972 // Probably don't need to do this anymore...
2973 // Desktop.desktop.getComponentAt(x, y);
2974 // TODO: NOW: check that this recovers the PDB file correctly.
2975 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2976 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2977 .get(JSEQ[i].getId() + "");
2978 if (sviewid == null)
2980 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2983 if (!jmolViewIds.containsKey(sviewid))
2985 jmolViewIds.put(sviewid, new Object[]
2987 { x, y, width, height }, "",
2988 new Hashtable<String, Object[]>(), new boolean[]
2989 { false, false, true } });
2990 // Legacy pre-2.7 conversion JAL-823 :
2991 // do not assume any view has to be linked for colour by
2995 // assemble String[] { pdb files }, String[] { id for each
2996 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2997 // seqs_file 2}, boolean[] {
2998 // linkAlignPanel,superposeWithAlignpanel}} from hash
2999 Object[] jmoldat = jmolViewIds.get(sviewid);
3000 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
3001 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
3002 s).getAlignwithAlignPanel() : false;
3003 // never colour by linked panel if not specified
3004 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
3005 .hasColourwithAlignPanel() ? ids[p]
3006 .getStructureState(s).getColourwithAlignPanel()
3008 // default for pre-2.7 projects is that Jmol colouring is enabled
3009 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
3010 .hasColourByJmol() ? ids[p].getStructureState(s)
3011 .getColourByJmol() : true;
3013 if (((String) jmoldat[1]).length() < ids[p]
3014 .getStructureState(s).getContent().length())
3017 jmoldat[1] = ids[p].getStructureState(s).getContent();
3020 if (ids[p].getFile() != null)
3022 File mapkey = new File(ids[p].getFile());
3023 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3025 if (seqstrmaps == null)
3027 ((Hashtable) jmoldat[2]).put(mapkey,
3028 seqstrmaps = new Object[]
3029 { pdbFile, ids[p].getId(), new Vector(),
3032 if (!((Vector) seqstrmaps[2]).contains(seq))
3034 ((Vector) seqstrmaps[2]).addElement(seq);
3035 // ((Vector)seqstrmaps[3]).addElement(n) :
3036 // in principle, chains
3037 // should be stored here : do we need to
3038 // TODO: store and recover seq/pdb_id :
3044 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");
3053 // Instantiate the associated Jmol views
3054 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3056 String sviewid = entry.getKey();
3057 Object[] svattrib = entry.getValue();
3058 int[] geom = (int[]) svattrib[0];
3059 String state = (String) svattrib[1];
3060 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3061 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3062 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3063 // collate the pdbfile -> sequence mappings from this view
3064 Vector<String> pdbfilenames = new Vector<String>();
3065 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3066 Vector<String> pdbids = new Vector<String>();
3068 // Search to see if we've already created this Jmol view
3069 AppJmol comp = null;
3070 JInternalFrame[] frames = null;
3075 frames = Desktop.desktop.getAllFrames();
3076 } catch (ArrayIndexOutOfBoundsException e)
3078 // occasional No such child exceptions are thrown here...
3083 } catch (Exception f)
3088 } while (frames == null);
3089 // search for any Jmol windows already open from other
3090 // alignment views that exactly match the stored structure state
3091 for (int f = 0; comp == null && f < frames.length; f++)
3093 if (frames[f] instanceof AppJmol)
3096 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3098 // post jalview 2.4 schema includes structure view id
3099 comp = (AppJmol) frames[f];
3101 else if (frames[f].getX() == x && frames[f].getY() == y
3102 && frames[f].getHeight() == height
3103 && frames[f].getWidth() == width)
3105 comp = (AppJmol) frames[f];
3112 // create a new Jmol window.
3113 // First parse the Jmol state to translate filenames loaded into the
3114 // view, and record the order in which files are shown in the Jmol
3115 // view, so we can add the sequence mappings in same order.
3116 StringBuffer newFileLoc = null;
3117 int cp = 0, ncp, ecp;
3118 while ((ncp = state.indexOf("load ", cp)) > -1)
3120 if (newFileLoc == null)
3122 newFileLoc = new StringBuffer();
3126 // look for next filename in load statement
3127 newFileLoc.append(state.substring(cp,
3128 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3129 String oldfilenam = state.substring(ncp,
3130 ecp = state.indexOf("\"", ncp));
3131 // recover the new mapping data for this old filename
3132 // have to normalize filename - since Jmol and jalview do
3134 // translation differently.
3135 Object[] filedat = oldFiles.get(new File(oldfilenam));
3136 newFileLoc.append(Platform
3137 .escapeString((String) filedat[0]));
3138 pdbfilenames.addElement((String) filedat[0]);
3139 pdbids.addElement((String) filedat[1]);
3140 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3141 .toArray(new SequenceI[0]));
3142 newFileLoc.append("\"");
3143 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3144 // look for next file statement.
3145 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3149 // just append rest of state
3150 newFileLoc.append(state.substring(cp));
3155 .print("Ignoring incomplete Jmol state for PDB ids: ");
3156 newFileLoc = new StringBuffer(state);
3157 newFileLoc.append("; load append ");
3158 for (File id : oldFiles.keySet())
3160 // add this and any other pdb files that should be present in
3162 Object[] filedat = oldFiles.get(id);
3164 newFileLoc.append(((String) filedat[0]));
3165 pdbfilenames.addElement((String) filedat[0]);
3166 pdbids.addElement((String) filedat[1]);
3167 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3168 .toArray(new SequenceI[0]));
3169 newFileLoc.append(" \"");
3170 newFileLoc.append((String) filedat[0]);
3171 newFileLoc.append("\"");
3174 newFileLoc.append(";");
3177 if (newFileLoc != null)
3179 int histbug = newFileLoc.indexOf("history = ");
3181 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3183 String val = (diff == -1) ? null : newFileLoc.substring(
3185 if (val != null && val.length() >= 4)
3187 if (val.contains("e"))
3189 if (val.trim().equals("true"))
3197 newFileLoc.replace(histbug, diff, val);
3200 // TODO: assemble String[] { pdb files }, String[] { id for each
3201 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3202 // seqs_file 2}} from hash
3203 final String[] pdbf = pdbfilenames
3204 .toArray(new String[pdbfilenames.size()]), id = pdbids
3205 .toArray(new String[pdbids.size()]);
3206 final SequenceI[][] sq = seqmaps
3207 .toArray(new SequenceI[seqmaps.size()][]);
3208 final String fileloc = newFileLoc.toString(), vid = sviewid;
3209 final AlignFrame alf = af;
3210 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3214 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3219 JalviewStructureDisplayI sview = null;
3222 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3223 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3224 useinJmolsuperpos, usetoColourbyseq,
3225 jmolColouring, fileloc, rect, vid);
3226 addNewStructureViewer(sview);
3227 } catch (OutOfMemoryError ex)
3229 new OOMWarning("restoring structure view for PDB id "
3230 + id, (OutOfMemoryError) ex.getCause());
3231 if (sview != null && sview.isVisible())
3233 sview.closeViewer();
3234 sview.setVisible(false);
3240 } catch (InvocationTargetException ex)
3242 warn("Unexpected error when opening Jmol view.", ex);
3244 } catch (InterruptedException e)
3246 // e.printStackTrace();
3252 // if (comp != null)
3254 // NOTE: if the jalview project is part of a shared session then
3255 // view synchronization should/could be done here.
3257 // add mapping for sequences in this view to an already open Jmol
3259 for (File id : oldFiles.keySet())
3261 // add this and any other pdb files that should be present in the
3263 Object[] filedat = oldFiles.get(id);
3264 String pdbFile = (String) filedat[0];
3265 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3266 .toArray(new SequenceI[0]);
3267 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3268 jalview.io.AppletFormatAdapter.FILE);
3269 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3271 // and add the AlignmentPanel's reference to the Jmol view
3272 comp.addAlignmentPanel(ap);
3273 if (useinJmolsuperpos)
3275 comp.useAlignmentPanelForSuperposition(ap);
3279 comp.excludeAlignmentPanelForSuperposition(ap);
3281 if (usetoColourbyseq)
3283 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3287 comp.excludeAlignmentPanelForColourbyseq(ap);
3293 // and finally return.
3300 * - minimum version we are comparing against
3302 * - version of data being processsed.
3303 * @return true if version is development/null or evaluates to the same or
3304 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3306 private boolean isVersionStringLaterThan(String supported, String version)
3308 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3309 || version.equalsIgnoreCase("Test")
3310 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3312 System.err.println("Assuming project file with "
3313 + (version == null ? "null" : version)
3314 + " is compatible with Jalview version " + supported);
3319 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3321 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3323 // convert b to decimal to catch bugfix releases within a series
3324 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3325 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3328 if (Float.valueOf(curT) > Float.valueOf(fileT))
3330 // current version is newer than the version that wrote the file
3333 } catch (NumberFormatException nfe)
3336 .println("** WARNING: Version comparison failed for tokens ("
3340 + ")\n** Current: '"
3341 + supported + "' and Version: '" + version + "'");
3344 if (currentV.hasMoreElements())
3346 // fileV has no minor version but identical series to current
3353 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3355 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3357 if (newStructureViewers != null)
3359 sview.getBinding().setFinishedLoadingFromArchive(false);
3360 newStructureViewers.add(sview);
3364 protected void setLoadingFinishedForNewStructureViewers()
3366 if (newStructureViewers != null)
3368 for (JalviewStructureDisplayI sview : newStructureViewers)
3370 sview.getBinding().setFinishedLoadingFromArchive(true);
3372 newStructureViewers.clear();
3373 newStructureViewers = null;
3377 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3378 Alignment al, JalviewModelSequence jms, Viewport view,
3379 String uniqueSeqSetId, String viewId,
3380 ArrayList<JvAnnotRow> autoAlan)
3382 AlignFrame af = null;
3383 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3384 uniqueSeqSetId, viewId);
3386 af.setFileName(file, "Jalview");
3388 for (int i = 0; i < JSEQ.length; i++)
3390 af.viewport.setSequenceColour(af.viewport.getAlignment()
3391 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3394 af.viewport.gatherViewsHere = view.getGatheredViews();
3396 if (view.getSequenceSetId() != null)
3398 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3399 .get(uniqueSeqSetId);
3401 af.viewport.setSequenceSetId(uniqueSeqSetId);
3404 // propagate shared settings to this new view
3405 af.viewport.historyList = av.historyList;
3406 af.viewport.redoList = av.redoList;
3410 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3412 // TODO: check if this method can be called repeatedly without
3413 // side-effects if alignpanel already registered.
3414 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3416 // apply Hidden regions to view.
3417 if (hiddenSeqs != null)
3419 for (int s = 0; s < JSEQ.length; s++)
3421 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3423 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3426 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3428 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3431 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3434 for (int s = 0; s < hiddenSeqs.size(); s++)
3436 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3439 af.viewport.hideSequence(hseqs);
3442 // recover view properties and display parameters
3443 if (view.getViewName() != null)
3445 af.viewport.viewName = view.getViewName();
3446 af.setInitialTabVisible();
3448 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3451 af.viewport.setShowAnnotation(view.getShowAnnotation());
3452 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3454 af.viewport.setColourText(view.getShowColourText());
3456 af.viewport.setConservationSelected(view.getConservationSelected());
3457 af.viewport.setShowJVSuffix(view.getShowFullId());
3458 af.viewport.rightAlignIds = view.getRightAlignIds();
3459 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3460 .getFontStyle(), view.getFontSize()));
3461 af.alignPanel.fontChanged();
3462 af.viewport.setRenderGaps(view.getRenderGaps());
3463 af.viewport.setWrapAlignment(view.getWrapAlignment());
3464 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3465 af.viewport.setShowAnnotation(view.getShowAnnotation());
3466 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3468 af.viewport.setShowBoxes(view.getShowBoxes());
3470 af.viewport.setShowText(view.getShowText());
3472 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3473 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3474 af.viewport.thresholdTextColour = view.getTextColThreshold();
3475 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3476 .isShowUnconserved() : false);
3477 af.viewport.setStartRes(view.getStartRes());
3478 af.viewport.setStartSeq(view.getStartSeq());
3480 ColourSchemeI cs = null;
3481 // apply colourschemes
3482 if (view.getBgColour() != null)
3484 if (view.getBgColour().startsWith("ucs"))
3486 cs = GetUserColourScheme(jms, view.getBgColour());
3488 else if (view.getBgColour().startsWith("Annotation"))
3490 AnnotationColours viewAnnColour = view.getAnnotationColours();
3491 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3498 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3503 cs.setThreshold(view.getPidThreshold(), true);
3504 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3508 af.viewport.setGlobalColourScheme(cs);
3509 af.viewport.setColourAppliesToAllGroups(false);
3511 if (view.getConservationSelected() && cs != null)
3513 cs.setConservationInc(view.getConsThreshold());
3516 af.changeColour(cs);
3518 af.viewport.setColourAppliesToAllGroups(true);
3520 if (view.getShowSequenceFeatures())
3522 af.viewport.showSequenceFeatures = true;
3524 if (view.hasCentreColumnLabels())
3526 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3528 if (view.hasIgnoreGapsinConsensus())
3530 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3533 if (view.hasFollowHighlight())
3535 af.viewport.followHighlight = view.getFollowHighlight();
3537 if (view.hasFollowSelection())
3539 af.viewport.followSelection = view.getFollowSelection();
3541 if (view.hasShowConsensusHistogram())
3543 af.viewport.setShowConsensusHistogram(view
3544 .getShowConsensusHistogram());
3548 af.viewport.setShowConsensusHistogram(true);
3550 if (view.hasShowSequenceLogo())
3552 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3556 af.viewport.setShowSequenceLogo(false);
3558 if (view.hasNormaliseSequenceLogo())
3560 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3562 if (view.hasShowDbRefTooltip())
3564 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3566 if (view.hasShowNPfeatureTooltip())
3568 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3570 if (view.hasShowGroupConsensus())
3572 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3576 af.viewport.setShowGroupConsensus(false);
3578 if (view.hasShowGroupConservation())
3580 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3584 af.viewport.setShowGroupConservation(false);
3587 // recover featre settings
3588 if (jms.getFeatureSettings() != null)
3590 af.viewport.featuresDisplayed = new Hashtable();
3591 String[] renderOrder = new String[jms.getFeatureSettings()
3592 .getSettingCount()];
3593 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3595 Setting setting = jms.getFeatureSettings().getSetting(fs);
3596 if (setting.hasMincolour())
3598 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3599 new java.awt.Color(setting.getMincolour()),
3600 new java.awt.Color(setting.getColour()),
3601 setting.getMin(), setting.getMax()) : new GraduatedColor(
3602 new java.awt.Color(setting.getMincolour()),
3603 new java.awt.Color(setting.getColour()), 0, 1);
3604 if (setting.hasThreshold())
3606 gc.setThresh(setting.getThreshold());
3607 gc.setThreshType(setting.getThreshstate());
3609 gc.setAutoScaled(true); // default
3610 if (setting.hasAutoScale())
3612 gc.setAutoScaled(setting.getAutoScale());
3614 if (setting.hasColourByLabel())
3616 gc.setColourByLabel(setting.getColourByLabel());
3618 // and put in the feature colour table.
3619 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3620 setting.getType(), gc);
3624 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3626 new java.awt.Color(setting.getColour()));
3628 renderOrder[fs] = setting.getType();
3629 if (setting.hasOrder())
3631 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3632 setting.getType(), setting.getOrder());
3636 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3638 fs / jms.getFeatureSettings().getSettingCount());
3640 if (setting.getDisplay())
3642 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3643 setting.getColour()));
3646 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3648 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3649 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3651 Group grp = jms.getFeatureSettings().getGroup(gs);
3652 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3656 if (view.getHiddenColumnsCount() > 0)
3658 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3660 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3661 .getHiddenColumns(c).getEnd() // +1
3665 if (view.getCalcIdParam() != null)
3667 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3669 if (calcIdParam != null)
3671 if (recoverCalcIdParam(calcIdParam, af.viewport))
3676 warn("Couldn't recover parameters for "
3677 + calcIdParam.getCalcId());
3682 af.setMenusFromViewport(af.viewport);
3683 // TODO: we don't need to do this if the viewport is aready visible.
3684 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3686 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3687 reorderAutoannotation(af, al, autoAlan);
3688 af.alignPanel.alignmentChanged();
3692 private ColourSchemeI constructAnnotationColour(
3693 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3694 JalviewModelSequence jms, boolean checkGroupAnnColour)
3696 boolean propagateAnnColour = false;
3697 ColourSchemeI cs = null;
3698 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3699 if (checkGroupAnnColour && al.getGroups() != null
3700 && al.getGroups().size() > 0)
3702 // pre 2.8.1 behaviour
3703 // check to see if we should transfer annotation colours
3704 propagateAnnColour = true;
3705 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3707 if (sg.cs instanceof AnnotationColourGradient)
3709 propagateAnnColour = false;
3713 // int find annotation
3714 if (annAlignment.getAlignmentAnnotation() != null)
3716 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3718 if (annAlignment.getAlignmentAnnotation()[i].label
3719 .equals(viewAnnColour.getAnnotation()))
3721 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3723 annAlignment.getAlignmentAnnotation()[i]
3724 .setThreshold(new jalview.datamodel.GraphLine(
3725 viewAnnColour.getThreshold(), "Threshold",
3726 java.awt.Color.black)
3731 if (viewAnnColour.getColourScheme().equals("None"))
3733 cs = new AnnotationColourGradient(
3734 annAlignment.getAlignmentAnnotation()[i],
3735 new java.awt.Color(viewAnnColour.getMinColour()),
3736 new java.awt.Color(viewAnnColour.getMaxColour()),
3737 viewAnnColour.getAboveThreshold());
3739 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3741 cs = new AnnotationColourGradient(
3742 annAlignment.getAlignmentAnnotation()[i],
3743 GetUserColourScheme(jms,
3744 viewAnnColour.getColourScheme()),
3745 viewAnnColour.getAboveThreshold());
3749 cs = new AnnotationColourGradient(
3750 annAlignment.getAlignmentAnnotation()[i],
3751 ColourSchemeProperty.getColour(al,
3752 viewAnnColour.getColourScheme()),
3753 viewAnnColour.getAboveThreshold());
3755 if (viewAnnColour.hasPerSequence())
3757 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3760 if (viewAnnColour.hasPredefinedColours())
3762 ((AnnotationColourGradient) cs)
3763 .setPredefinedColours(viewAnnColour
3764 .isPredefinedColours());
3766 if (propagateAnnColour && al.getGroups() != null)
3768 // Also use these settings for all the groups
3769 for (int g = 0; g < al.getGroups().size(); g++)
3771 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3779 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3780 * new AnnotationColourGradient(
3781 * annAlignment.getAlignmentAnnotation()[i], new
3782 * java.awt.Color(viewAnnColour. getMinColour()), new
3783 * java.awt.Color(viewAnnColour. getMaxColour()),
3784 * viewAnnColour.getAboveThreshold()); } else
3787 sg.cs = new AnnotationColourGradient(
3788 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3789 viewAnnColour.getAboveThreshold());
3790 if (cs instanceof AnnotationColourGradient)
3792 if (viewAnnColour.hasPerSequence())
3794 ((AnnotationColourGradient) cs)
3795 .setSeqAssociated(viewAnnColour.isPerSequence());
3797 if (viewAnnColour.hasPredefinedColours())
3799 ((AnnotationColourGradient) cs)
3800 .setPredefinedColours(viewAnnColour
3801 .isPredefinedColours());
3817 private void reorderAutoannotation(AlignFrame af, Alignment al,
3818 ArrayList<JvAnnotRow> autoAlan)
3820 // copy over visualization settings for autocalculated annotation in the
3822 if (al.getAlignmentAnnotation() != null)
3825 * Kludge for magic autoannotation names (see JAL-811)
3827 String[] magicNames = new String[]
3828 { "Consensus", "Quality", "Conservation" };
3829 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3830 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3831 for (String nm : magicNames)
3833 visan.put(nm, nullAnnot);
3835 for (JvAnnotRow auan : autoAlan)
3837 visan.put(auan.template.label
3838 + (auan.template.getCalcId() == null ? "" : "\t"
3839 + auan.template.getCalcId()), auan);
3841 int hSize = al.getAlignmentAnnotation().length;
3842 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3843 // work through any autoCalculated annotation already on the view
3844 // removing it if it should be placed in a different location on the
3845 // annotation panel.
3846 List<String> remains = new ArrayList(visan.keySet());
3847 for (int h = 0; h < hSize; h++)
3849 jalview.datamodel.AlignmentAnnotation jalan = al
3850 .getAlignmentAnnotation()[h];
3851 if (jalan.autoCalculated)
3854 JvAnnotRow valan = visan.get(k = jalan.label);
3855 if (jalan.getCalcId() != null)
3857 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3862 // delete the auto calculated row from the alignment
3863 al.deleteAnnotation(jalan, false);
3867 if (valan != nullAnnot)
3869 if (jalan != valan.template)
3871 // newly created autoannotation row instance
3872 // so keep a reference to the visible annotation row
3873 // and copy over all relevant attributes
3874 if (valan.template.graphHeight >= 0)
3877 jalan.graphHeight = valan.template.graphHeight;
3879 jalan.visible = valan.template.visible;
3881 reorder.add(new JvAnnotRow(valan.order, jalan));
3886 // Add any (possibly stale) autocalculated rows that were not appended to
3887 // the view during construction
3888 for (String other : remains)
3890 JvAnnotRow othera = visan.get(other);
3891 if (othera != nullAnnot && othera.template.getCalcId() != null
3892 && othera.template.getCalcId().length() > 0)
3894 reorder.add(othera);
3897 // now put the automatic annotation in its correct place
3898 int s = 0, srt[] = new int[reorder.size()];
3899 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3900 for (JvAnnotRow jvar : reorder)
3903 srt[s++] = jvar.order;
3906 jalview.util.QuickSort.sort(srt, rws);
3907 // and re-insert the annotation at its correct position
3908 for (JvAnnotRow jvar : rws)
3910 al.addAnnotation(jvar.template, jvar.order);
3912 af.alignPanel.adjustAnnotationHeight();
3916 Hashtable skipList = null;
3919 * TODO remove this method
3922 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3923 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3924 * throw new Error("Implementation Error. No skipList defined for this
3925 * Jalview2XML instance."); } return (AlignFrame)
3926 * skipList.get(view.getSequenceSetId()); }
3930 * Check if the Jalview view contained in object should be skipped or not.
3933 * @return true if view's sequenceSetId is a key in skipList
3935 private boolean skipViewport(JalviewModel object)
3937 if (skipList == null)
3942 if (skipList.containsKey(id = object.getJalviewModelSequence()
3943 .getViewport()[0].getSequenceSetId()))
3945 if (Cache.log != null && Cache.log.isDebugEnabled())
3947 Cache.log.debug("Skipping seuqence set id " + id);
3954 public void AddToSkipList(AlignFrame af)
3956 if (skipList == null)
3958 skipList = new Hashtable();
3960 skipList.put(af.getViewport().getSequenceSetId(), af);
3963 public void clearSkipList()
3965 if (skipList != null)
3972 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3974 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3975 Vector dseqs = null;
3978 // create a list of new dataset sequences
3979 dseqs = new Vector();
3981 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3983 Sequence vamsasSeq = vamsasSet.getSequence(i);
3984 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3986 // create a new dataset
3989 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3990 dseqs.copyInto(dsseqs);
3991 ds = new jalview.datamodel.Alignment(dsseqs);
3992 debug("Created new dataset " + vamsasSet.getDatasetId()
3993 + " for alignment " + System.identityHashCode(al));
3994 addDatasetRef(vamsasSet.getDatasetId(), ds);
3996 // set the dataset for the newly imported alignment.
3997 if (al.getDataset() == null)
4006 * sequence definition to create/merge dataset sequence for
4010 * vector to add new dataset sequence to
4012 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4013 AlignmentI ds, Vector dseqs)
4015 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4017 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4018 .get(vamsasSeq.getId());
4019 jalview.datamodel.SequenceI dsq = null;
4020 if (sq != null && sq.getDatasetSequence() != null)
4022 dsq = sq.getDatasetSequence();
4025 String sqid = vamsasSeq.getDsseqid();
4028 // need to create or add a new dataset sequence reference to this sequence
4031 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4036 // make a new dataset sequence
4037 dsq = sq.createDatasetSequence();
4040 // make up a new dataset reference for this sequence
4041 sqid = seqHash(dsq);
4043 dsq.setVamsasId(uniqueSetSuffix + sqid);
4044 seqRefIds.put(sqid, dsq);
4049 dseqs.addElement(dsq);
4054 ds.addSequence(dsq);
4060 { // make this dataset sequence sq's dataset sequence
4061 sq.setDatasetSequence(dsq);
4062 // and update the current dataset alignment
4067 if (!dseqs.contains(dsq))
4074 if (ds.findIndex(dsq) < 0)
4076 ds.addSequence(dsq);
4083 // TODO: refactor this as a merge dataset sequence function
4084 // now check that sq (the dataset sequence) sequence really is the union of
4085 // all references to it
4086 // boolean pre = sq.getStart() < dsq.getStart();
4087 // boolean post = sq.getEnd() > dsq.getEnd();
4091 StringBuffer sb = new StringBuffer();
4092 String newres = jalview.analysis.AlignSeq.extractGaps(
4093 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4094 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4095 && newres.length() > dsq.getLength())
4097 // Update with the longer sequence.
4101 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4102 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4103 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4104 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4106 dsq.setSequence(newres);
4108 // TODO: merges will never happen if we 'know' we have the real dataset
4109 // sequence - this should be detected when id==dssid
4111 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4112 // + (pre ? "prepended" : "") + " "
4113 // + (post ? "appended" : ""));
4118 java.util.Hashtable datasetIds = null;
4120 java.util.IdentityHashMap dataset2Ids = null;
4122 private Alignment getDatasetFor(String datasetId)
4124 if (datasetIds == null)
4126 datasetIds = new Hashtable();
4129 if (datasetIds.containsKey(datasetId))
4131 return (Alignment) datasetIds.get(datasetId);
4136 private void addDatasetRef(String datasetId, Alignment dataset)
4138 if (datasetIds == null)
4140 datasetIds = new Hashtable();
4142 datasetIds.put(datasetId, dataset);
4146 * make a new dataset ID for this jalview dataset alignment
4151 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4153 if (dataset.getDataset() != null)
4155 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4157 String datasetId = makeHashCode(dataset, null);
4158 if (datasetId == null)
4160 // make a new datasetId and record it
4161 if (dataset2Ids == null)
4163 dataset2Ids = new IdentityHashMap();
4167 datasetId = (String) dataset2Ids.get(dataset);
4169 if (datasetId == null)
4171 datasetId = "ds" + dataset2Ids.size() + 1;
4172 dataset2Ids.put(dataset, datasetId);
4178 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4180 for (int d = 0; d < sequence.getDBRefCount(); d++)
4182 DBRef dr = sequence.getDBRef(d);
4183 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4184 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4185 .getVersion(), sequence.getDBRef(d).getAccessionId());
4186 if (dr.getMapping() != null)
4188 entry.setMap(addMapping(dr.getMapping()));
4190 datasetSequence.addDBRef(entry);
4194 private jalview.datamodel.Mapping addMapping(Mapping m)
4196 SequenceI dsto = null;
4197 // Mapping m = dr.getMapping();
4198 int fr[] = new int[m.getMapListFromCount() * 2];
4199 Enumeration f = m.enumerateMapListFrom();
4200 for (int _i = 0; f.hasMoreElements(); _i += 2)
4202 MapListFrom mf = (MapListFrom) f.nextElement();
4203 fr[_i] = mf.getStart();
4204 fr[_i + 1] = mf.getEnd();
4206 int fto[] = new int[m.getMapListToCount() * 2];
4207 f = m.enumerateMapListTo();
4208 for (int _i = 0; f.hasMoreElements(); _i += 2)
4210 MapListTo mf = (MapListTo) f.nextElement();
4211 fto[_i] = mf.getStart();
4212 fto[_i + 1] = mf.getEnd();
4214 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4215 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4216 if (m.getMappingChoice() != null)
4218 MappingChoice mc = m.getMappingChoice();
4219 if (mc.getDseqFor() != null)
4221 String dsfor = "" + mc.getDseqFor();
4222 if (seqRefIds.containsKey(dsfor))
4227 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4231 frefedSequence.add(new Object[]
4238 * local sequence definition
4240 Sequence ms = mc.getSequence();
4241 jalview.datamodel.Sequence djs = null;
4242 String sqid = ms.getDsseqid();
4243 if (sqid != null && sqid.length() > 0)
4246 * recover dataset sequence
4248 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4253 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4254 sqid = ((Object) ms).toString(); // make up a new hascode for
4255 // undefined dataset sequence hash
4256 // (unlikely to happen)
4262 * make a new dataset sequence and add it to refIds hash
4264 djs = new jalview.datamodel.Sequence(ms.getName(),
4266 djs.setStart(jmap.getMap().getToLowest());
4267 djs.setEnd(jmap.getMap().getToHighest());
4268 djs.setVamsasId(uniqueSetSuffix + sqid);
4270 seqRefIds.put(sqid, djs);
4273 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4282 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4283 boolean keepSeqRefs)
4286 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4292 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4296 uniqueSetSuffix = "";
4297 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4302 if (this.frefedSequence == null)
4304 frefedSequence = new Vector();
4307 viewportsAdded = new Hashtable();
4309 AlignFrame af = LoadFromObject(jm, null, false, null);
4310 af.alignPanels.clear();
4311 af.closeMenuItem_actionPerformed(true);
4314 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4315 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4316 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4317 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4318 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4321 return af.alignPanel;
4325 * flag indicating if hashtables should be cleared on finalization TODO this
4326 * flag may not be necessary
4328 private final boolean _cleartables = true;
4330 private Hashtable jvids2vobj;
4335 * @see java.lang.Object#finalize()
4338 protected void finalize() throws Throwable
4340 // really make sure we have no buried refs left.
4345 this.seqRefIds = null;
4346 this.seqsToIds = null;
4350 private void warn(String msg)
4355 private void warn(String msg, Exception e)
4357 if (Cache.log != null)
4361 Cache.log.warn(msg, e);
4365 Cache.log.warn(msg);
4370 System.err.println("Warning: " + msg);
4373 e.printStackTrace();
4378 private void debug(String string)
4380 debug(string, null);
4383 private void debug(String msg, Exception e)
4385 if (Cache.log != null)
4389 Cache.log.debug(msg, e);
4393 Cache.log.debug(msg);
4398 System.err.println("Warning: " + msg);
4401 e.printStackTrace();
4407 * set the object to ID mapping tables used to write/recover objects and XML
4408 * ID strings for the jalview project. If external tables are provided then
4409 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4410 * object goes out of scope. - also populates the datasetIds hashtable with
4411 * alignment objects containing dataset sequences
4414 * Map from ID strings to jalview datamodel
4416 * Map from jalview datamodel to ID strings
4420 public void setObjectMappingTables(Hashtable vobj2jv,
4421 IdentityHashMap jv2vobj)
4423 this.jv2vobj = jv2vobj;
4424 this.vobj2jv = vobj2jv;
4425 Iterator ds = jv2vobj.keySet().iterator();
4427 while (ds.hasNext())
4429 Object jvobj = ds.next();
4430 id = jv2vobj.get(jvobj).toString();
4431 if (jvobj instanceof jalview.datamodel.Alignment)
4433 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4435 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4438 else if (jvobj instanceof jalview.datamodel.Sequence)
4440 // register sequence object so the XML parser can recover it.
4441 if (seqRefIds == null)
4443 seqRefIds = new Hashtable();
4445 if (seqsToIds == null)
4447 seqsToIds = new IdentityHashMap();
4449 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4450 seqsToIds.put(jvobj, id);
4452 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4454 if (annotationIds == null)
4456 annotationIds = new Hashtable();
4459 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4460 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4461 if (jvann.annotationId == null)
4463 jvann.annotationId = anid;
4465 if (!jvann.annotationId.equals(anid))
4467 // TODO verify that this is the correct behaviour
4468 this.warn("Overriding Annotation ID for " + anid
4469 + " from different id : " + jvann.annotationId);
4470 jvann.annotationId = anid;
4473 else if (jvobj instanceof String)
4475 if (jvids2vobj == null)
4477 jvids2vobj = new Hashtable();
4478 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4483 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4489 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4490 * objects created from the project archive. If string is null (default for
4491 * construction) then suffix will be set automatically.
4495 public void setUniqueSetSuffix(String string)
4497 uniqueSetSuffix = string;
4502 * uses skipList2 as the skipList for skipping views on sequence sets
4503 * associated with keys in the skipList
4507 public void setSkipList(Hashtable skipList2)
4509 skipList = skipList2;