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());
2371 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2375 } // end !multipleview
2377 // ///////////////////////////////
2378 // LOAD SEQUENCE MAPPINGS
2380 if (vamsasSet.getAlcodonFrameCount() > 0)
2382 // TODO Potentially this should only be done once for all views of an
2384 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2385 for (int i = 0; i < alc.length; i++)
2387 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2388 alc[i].getAlcodonCount());
2389 if (alc[i].getAlcodonCount() > 0)
2391 Alcodon[] alcods = alc[i].getAlcodon();
2392 for (int p = 0; p < cf.codons.length; p++)
2394 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2395 && alcods[p].hasPos3())
2397 // translated codons require three valid positions
2398 cf.codons[p] = new int[3];
2399 cf.codons[p][0] = (int) alcods[p].getPos1();
2400 cf.codons[p][1] = (int) alcods[p].getPos2();
2401 cf.codons[p][2] = (int) alcods[p].getPos3();
2405 cf.codons[p] = null;
2409 if (alc[i].getAlcodMapCount() > 0)
2411 AlcodMap[] maps = alc[i].getAlcodMap();
2412 for (int m = 0; m < maps.length; m++)
2414 SequenceI dnaseq = (SequenceI) seqRefIds
2415 .get(maps[m].getDnasq());
2417 jalview.datamodel.Mapping mapping = null;
2418 // attach to dna sequence reference.
2419 if (maps[m].getMapping() != null)
2421 mapping = addMapping(maps[m].getMapping());
2425 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2430 frefedSequence.add(new Object[]
2431 { maps[m].getDnasq(), cf, mapping });
2435 al.addCodonFrame(cf);
2440 // ////////////////////////////////
2442 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2444 * store any annotations which forward reference a group's ID
2446 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2448 if (vamsasSet.getAnnotationCount() > 0)
2450 Annotation[] an = vamsasSet.getAnnotation();
2452 for (int i = 0; i < an.length; i++)
2455 * test if annotation is automatically calculated for this view only
2457 boolean autoForView = false;
2458 if (an[i].getLabel().equals("Quality")
2459 || an[i].getLabel().equals("Conservation")
2460 || an[i].getLabel().equals("Consensus"))
2462 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2464 if (!an[i].hasAutoCalculated())
2466 an[i].setAutoCalculated(true);
2470 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2472 // remove ID - we don't recover annotation from other views for
2473 // view-specific annotation
2477 // set visiblity for other annotation in this view
2478 if (an[i].getId() != null
2479 && annotationIds.containsKey(an[i].getId()))
2481 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2482 .get(an[i].getId());
2483 // in principle Visible should always be true for annotation displayed
2484 // in multiple views
2485 if (an[i].hasVisible())
2487 jda.visible = an[i].getVisible();
2490 al.addAnnotation(jda);
2494 // Construct new annotation from model.
2495 AnnotationElement[] ae = an[i].getAnnotationElement();
2496 jalview.datamodel.Annotation[] anot = null;
2497 java.awt.Color firstColour = null;
2499 if (!an[i].getScoreOnly())
2501 anot = new jalview.datamodel.Annotation[al.getWidth()];
2502 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2504 anpos = ae[aa].getPosition();
2506 if (anpos >= anot.length)
2511 anot[anpos] = new jalview.datamodel.Annotation(
2513 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2514 (ae[aa].getSecondaryStructure() == null || ae[aa]
2515 .getSecondaryStructure().length() == 0) ? ' '
2516 : ae[aa].getSecondaryStructure().charAt(0),
2520 // JBPNote: Consider verifying dataflow for IO of secondary
2521 // structure annotation read from Stockholm files
2522 // this was added to try to ensure that
2523 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2525 // anot[ae[aa].getPosition()].displayCharacter = "";
2527 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2528 if (firstColour == null)
2530 firstColour = anot[anpos].colour;
2534 jalview.datamodel.AlignmentAnnotation jaa = null;
2536 if (an[i].getGraph())
2538 float llim = 0, hlim = 0;
2539 // if (autoForView || an[i].isAutoCalculated()) {
2542 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2543 an[i].getDescription(), anot, llim, hlim,
2544 an[i].getGraphType());
2546 jaa.graphGroup = an[i].getGraphGroup();
2547 jaa._linecolour = firstColour;
2548 if (an[i].getThresholdLine() != null)
2550 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2551 .getThresholdLine().getValue(), an[i]
2552 .getThresholdLine().getLabel(), new java.awt.Color(
2553 an[i].getThresholdLine().getColour())));
2556 if (autoForView || an[i].isAutoCalculated())
2558 // Hardwire the symbol display line to ensure that labels for
2559 // histograms are displayed
2565 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2566 an[i].getDescription(), anot);
2567 jaa._linecolour = firstColour;
2569 // register new annotation
2570 if (an[i].getId() != null)
2572 annotationIds.put(an[i].getId(), jaa);
2573 jaa.annotationId = an[i].getId();
2575 // recover sequence association
2576 if (an[i].getSequenceRef() != null)
2578 if (al.findName(an[i].getSequenceRef()) != null)
2580 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2582 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2585 // and make a note of any group association
2586 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2588 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2589 .get(an[i].getGroupRef());
2592 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2593 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2598 if (an[i].hasScore())
2600 jaa.setScore(an[i].getScore());
2602 if (an[i].hasVisible())
2604 jaa.visible = an[i].getVisible();
2607 if (an[i].hasCentreColLabels())
2609 jaa.centreColLabels = an[i].getCentreColLabels();
2612 if (an[i].hasScaleColLabels())
2614 jaa.scaleColLabel = an[i].getScaleColLabels();
2616 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2618 // newer files have an 'autoCalculated' flag and store calculation
2619 // state in viewport properties
2620 jaa.autoCalculated = true; // means annotation will be marked for
2621 // update at end of load.
2623 if (an[i].hasGraphHeight())
2625 jaa.graphHeight = an[i].getGraphHeight();
2627 if (an[i].hasBelowAlignment())
2629 jaa.belowAlignment = an[i].isBelowAlignment();
2631 jaa.setCalcId(an[i].getCalcId());
2632 if (jaa.autoCalculated)
2634 autoAlan.add(new JvAnnotRow(i, jaa));
2637 // if (!autoForView)
2639 // add autocalculated group annotation and any user created annotation
2641 al.addAnnotation(jaa);
2645 // ///////////////////////
2647 // Create alignment markup and styles for this view
2648 if (jms.getJGroupCount() > 0)
2650 JGroup[] groups = jms.getJGroup();
2651 boolean addAnnotSchemeGroup = false;
2652 for (int i = 0; i < groups.length; i++)
2654 ColourSchemeI cs = null;
2656 if (groups[i].getColour() != null)
2658 if (groups[i].getColour().startsWith("ucs"))
2660 cs = GetUserColourScheme(jms, groups[i].getColour());
2662 else if (groups[i].getColour().equals("AnnotationColourGradient")
2663 && groups[i].getAnnotationColours() != null)
2665 addAnnotSchemeGroup = true;
2670 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2675 cs.setThreshold(groups[i].getPidThreshold(), true);
2679 Vector seqs = new Vector();
2681 for (int s = 0; s < groups[i].getSeqCount(); s++)
2683 String seqId = groups[i].getSeq(s) + "";
2684 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2689 seqs.addElement(ts);
2693 if (seqs.size() < 1)
2698 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2699 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2700 groups[i].getDisplayText(), groups[i].getColourText(),
2701 groups[i].getStart(), groups[i].getEnd());
2703 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2705 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2706 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2707 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2708 .isShowUnconserved() : false);
2709 sg.thresholdTextColour = groups[i].getTextColThreshold();
2710 if (groups[i].hasShowConsensusHistogram())
2712 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2715 if (groups[i].hasShowSequenceLogo())
2717 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2719 if (groups[i].hasNormaliseSequenceLogo())
2721 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2723 if (groups[i].hasIgnoreGapsinConsensus())
2725 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2727 if (groups[i].getConsThreshold() != 0)
2729 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2730 "All", ResidueProperties.propHash, 3,
2731 sg.getSequences(null), 0, sg.getWidth() - 1);
2733 c.verdict(false, 25);
2734 sg.cs.setConservation(c);
2737 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2739 // re-instate unique group/annotation row reference
2740 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2741 .get(groups[i].getId());
2744 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2747 if (jaa.autoCalculated)
2749 // match up and try to set group autocalc alignment row for this
2751 if (jaa.label.startsWith("Consensus for "))
2753 sg.setConsensus(jaa);
2755 // match up and try to set group autocalc alignment row for this
2757 if (jaa.label.startsWith("Conservation for "))
2759 sg.setConservationRow(jaa);
2766 if (addAnnotSchemeGroup)
2768 // reconstruct the annotation colourscheme
2769 sg.cs = constructAnnotationColour(
2770 groups[i].getAnnotationColours(), null, al, jms, false);
2776 // only dataset in this model, so just return.
2779 // ///////////////////////////////
2782 // If we just load in the same jar file again, the sequenceSetId
2783 // will be the same, and we end up with multiple references
2784 // to the same sequenceSet. We must modify this id on load
2785 // so that each load of the file gives a unique id
2786 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2787 String viewId = (view.getId() == null ? null : view.getId()
2789 AlignFrame af = null;
2790 AlignViewport av = null;
2791 // now check to see if we really need to create a new viewport.
2792 if (multipleView && viewportsAdded.size() == 0)
2794 // We recovered an alignment for which a viewport already exists.
2795 // TODO: fix up any settings necessary for overlaying stored state onto
2796 // state recovered from another document. (may not be necessary).
2797 // we may need a binding from a viewport in memory to one recovered from
2799 // and then recover its containing af to allow the settings to be applied.
2800 // TODO: fix for vamsas demo
2802 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2804 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2805 if (seqsetobj != null)
2807 if (seqsetobj instanceof String)
2809 uniqueSeqSetId = (String) seqsetobj;
2811 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2817 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2823 * indicate that annotation colours are applied across all groups (pre
2824 * Jalview 2.8.1 behaviour)
2826 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2827 object.getVersion());
2829 AlignmentPanel ap = null;
2830 boolean isnewview = true;
2833 // Check to see if this alignment already has a view id == viewId
2834 jalview.gui.AlignmentPanel views[] = Desktop
2835 .getAlignmentPanels(uniqueSeqSetId);
2836 if (views != null && views.length > 0)
2838 for (int v = 0; v < views.length; v++)
2840 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2842 // recover the existing alignpanel, alignframe, viewport
2843 af = views[v].alignFrame;
2846 // TODO: could even skip resetting view settings if we don't want to
2847 // change the local settings from other jalview processes
2856 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2857 uniqueSeqSetId, viewId, autoAlan);
2862 // /////////////////////////////////////
2863 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2867 for (int t = 0; t < jms.getTreeCount(); t++)
2870 Tree tree = jms.getTree(t);
2872 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2875 tp = af.ShowNewickTree(
2876 new jalview.io.NewickFile(tree.getNewick()),
2877 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2878 tree.getXpos(), tree.getYpos());
2879 if (tree.getId() != null)
2881 // perhaps bind the tree id to something ?
2886 // update local tree attributes ?
2887 // TODO: should check if tp has been manipulated by user - if so its
2888 // settings shouldn't be modified
2889 tp.setTitle(tree.getTitle());
2890 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2891 .getWidth(), tree.getHeight()));
2892 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2895 tp.treeCanvas.av = av; // af.viewport;
2896 tp.treeCanvas.ap = ap; // af.alignPanel;
2901 warn("There was a problem recovering stored Newick tree: \n"
2902 + tree.getNewick());
2906 tp.fitToWindow.setState(tree.getFitToWindow());
2907 tp.fitToWindow_actionPerformed(null);
2909 if (tree.getFontName() != null)
2911 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2912 .getFontStyle(), tree.getFontSize()));
2916 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2917 .getFontStyle(), tree.getFontSize()));
2920 tp.showPlaceholders(tree.getMarkUnlinked());
2921 tp.showBootstrap(tree.getShowBootstrap());
2922 tp.showDistances(tree.getShowDistances());
2924 tp.treeCanvas.threshold = tree.getThreshold();
2926 if (tree.getCurrentTree())
2928 af.viewport.setCurrentTree(tp.getTree());
2932 } catch (Exception ex)
2934 ex.printStackTrace();
2938 // //LOAD STRUCTURES
2939 if (loadTreesAndStructures)
2941 // run through all PDB ids on the alignment, and collect mappings between
2942 // jmol view ids and all sequences referring to it
2943 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2945 for (int i = 0; i < JSEQ.length; i++)
2947 if (JSEQ[i].getPdbidsCount() > 0)
2949 Pdbids[] ids = JSEQ[i].getPdbids();
2950 for (int p = 0; p < ids.length; p++)
2952 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2954 // check to see if we haven't already created this structure view
2955 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2956 : ids[p].getStructureState(s).getViewId()
2958 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2959 // Originally : ids[p].getFile()
2960 // : TODO: verify external PDB file recovery still works in normal
2961 // jalview project load
2962 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2963 jpdb.setId(ids[p].getId());
2965 int x = ids[p].getStructureState(s).getXpos();
2966 int y = ids[p].getStructureState(s).getYpos();
2967 int width = ids[p].getStructureState(s).getWidth();
2968 int height = ids[p].getStructureState(s).getHeight();
2970 // Probably don't need to do this anymore...
2971 // Desktop.desktop.getComponentAt(x, y);
2972 // TODO: NOW: check that this recovers the PDB file correctly.
2973 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2974 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2975 .get(JSEQ[i].getId() + "");
2976 if (sviewid == null)
2978 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2981 if (!jmolViewIds.containsKey(sviewid))
2983 jmolViewIds.put(sviewid, new Object[]
2985 { x, y, width, height }, "",
2986 new Hashtable<String, Object[]>(), new boolean[]
2987 { false, false, true } });
2988 // Legacy pre-2.7 conversion JAL-823 :
2989 // do not assume any view has to be linked for colour by
2993 // assemble String[] { pdb files }, String[] { id for each
2994 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2995 // seqs_file 2}, boolean[] {
2996 // linkAlignPanel,superposeWithAlignpanel}} from hash
2997 Object[] jmoldat = jmolViewIds.get(sviewid);
2998 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2999 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
3000 s).getAlignwithAlignPanel() : false;
3001 // never colour by linked panel if not specified
3002 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
3003 .hasColourwithAlignPanel() ? ids[p]
3004 .getStructureState(s).getColourwithAlignPanel()
3006 // default for pre-2.7 projects is that Jmol colouring is enabled
3007 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
3008 .hasColourByJmol() ? ids[p].getStructureState(s)
3009 .getColourByJmol() : true;
3011 if (((String) jmoldat[1]).length() < ids[p]
3012 .getStructureState(s).getContent().length())
3015 jmoldat[1] = ids[p].getStructureState(s).getContent();
3018 if (ids[p].getFile() != null)
3020 File mapkey = new File(ids[p].getFile());
3021 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3023 if (seqstrmaps == null)
3025 ((Hashtable) jmoldat[2]).put(mapkey,
3026 seqstrmaps = new Object[]
3027 { pdbFile, ids[p].getId(), new Vector(),
3030 if (!((Vector) seqstrmaps[2]).contains(seq))
3032 ((Vector) seqstrmaps[2]).addElement(seq);
3033 // ((Vector)seqstrmaps[3]).addElement(n) :
3034 // in principle, chains
3035 // should be stored here : do we need to
3036 // TODO: store and recover seq/pdb_id :
3042 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");
3051 // Instantiate the associated Jmol views
3052 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3054 String sviewid = entry.getKey();
3055 Object[] svattrib = entry.getValue();
3056 int[] geom = (int[]) svattrib[0];
3057 String state = (String) svattrib[1];
3058 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3059 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3060 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3061 // collate the pdbfile -> sequence mappings from this view
3062 Vector<String> pdbfilenames = new Vector<String>();
3063 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3064 Vector<String> pdbids = new Vector<String>();
3066 // Search to see if we've already created this Jmol view
3067 AppJmol comp = null;
3068 JInternalFrame[] frames = null;
3073 frames = Desktop.desktop.getAllFrames();
3074 } catch (ArrayIndexOutOfBoundsException e)
3076 // occasional No such child exceptions are thrown here...
3081 } catch (Exception f)
3086 } while (frames == null);
3087 // search for any Jmol windows already open from other
3088 // alignment views that exactly match the stored structure state
3089 for (int f = 0; comp == null && f < frames.length; f++)
3091 if (frames[f] instanceof AppJmol)
3094 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3096 // post jalview 2.4 schema includes structure view id
3097 comp = (AppJmol) frames[f];
3099 else if (frames[f].getX() == x && frames[f].getY() == y
3100 && frames[f].getHeight() == height
3101 && frames[f].getWidth() == width)
3103 comp = (AppJmol) frames[f];
3110 // create a new Jmol window.
3111 // First parse the Jmol state to translate filenames loaded into the
3112 // view, and record the order in which files are shown in the Jmol
3113 // view, so we can add the sequence mappings in same order.
3114 StringBuffer newFileLoc = null;
3115 int cp = 0, ncp, ecp;
3116 while ((ncp = state.indexOf("load ", cp)) > -1)
3118 if (newFileLoc == null)
3120 newFileLoc = new StringBuffer();
3124 // look for next filename in load statement
3125 newFileLoc.append(state.substring(cp,
3126 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3127 String oldfilenam = state.substring(ncp,
3128 ecp = state.indexOf("\"", ncp));
3129 // recover the new mapping data for this old filename
3130 // have to normalize filename - since Jmol and jalview do
3132 // translation differently.
3133 Object[] filedat = oldFiles.get(new File(oldfilenam));
3134 newFileLoc.append(Platform
3135 .escapeString((String) filedat[0]));
3136 pdbfilenames.addElement((String) filedat[0]);
3137 pdbids.addElement((String) filedat[1]);
3138 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3139 .toArray(new SequenceI[0]));
3140 newFileLoc.append("\"");
3141 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3142 // look for next file statement.
3143 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3147 // just append rest of state
3148 newFileLoc.append(state.substring(cp));
3153 .print("Ignoring incomplete Jmol state for PDB ids: ");
3154 newFileLoc = new StringBuffer(state);
3155 newFileLoc.append("; load append ");
3156 for (File id : oldFiles.keySet())
3158 // add this and any other pdb files that should be present in
3160 Object[] filedat = oldFiles.get(id);
3162 newFileLoc.append(((String) filedat[0]));
3163 pdbfilenames.addElement((String) filedat[0]);
3164 pdbids.addElement((String) filedat[1]);
3165 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3166 .toArray(new SequenceI[0]));
3167 newFileLoc.append(" \"");
3168 newFileLoc.append((String) filedat[0]);
3169 newFileLoc.append("\"");
3172 newFileLoc.append(";");
3175 if (newFileLoc != null)
3177 int histbug = newFileLoc.indexOf("history = ");
3179 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3181 String val = (diff == -1) ? null : newFileLoc.substring(
3183 if (val != null && val.length() >= 4)
3185 if (val.contains("e"))
3187 if (val.trim().equals("true"))
3195 newFileLoc.replace(histbug, diff, val);
3198 // TODO: assemble String[] { pdb files }, String[] { id for each
3199 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3200 // seqs_file 2}} from hash
3201 final String[] pdbf = pdbfilenames
3202 .toArray(new String[pdbfilenames.size()]), id = pdbids
3203 .toArray(new String[pdbids.size()]);
3204 final SequenceI[][] sq = seqmaps
3205 .toArray(new SequenceI[seqmaps.size()][]);
3206 final String fileloc = newFileLoc.toString(), vid = sviewid;
3207 final AlignFrame alf = af;
3208 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3212 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3217 JalviewStructureDisplayI sview = null;
3220 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3221 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3222 useinJmolsuperpos, usetoColourbyseq,
3223 jmolColouring, fileloc, rect, vid);
3224 addNewStructureViewer(sview);
3225 } catch (OutOfMemoryError ex)
3227 new OOMWarning("restoring structure view for PDB id "
3228 + id, (OutOfMemoryError) ex.getCause());
3229 if (sview != null && sview.isVisible())
3231 sview.closeViewer();
3232 sview.setVisible(false);
3238 } catch (InvocationTargetException ex)
3240 warn("Unexpected error when opening Jmol view.", ex);
3242 } catch (InterruptedException e)
3244 // e.printStackTrace();
3250 // if (comp != null)
3252 // NOTE: if the jalview project is part of a shared session then
3253 // view synchronization should/could be done here.
3255 // add mapping for sequences in this view to an already open Jmol
3257 for (File id : oldFiles.keySet())
3259 // add this and any other pdb files that should be present in the
3261 Object[] filedat = oldFiles.get(id);
3262 String pdbFile = (String) filedat[0];
3263 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3264 .toArray(new SequenceI[0]);
3265 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3266 jalview.io.AppletFormatAdapter.FILE);
3267 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3269 // and add the AlignmentPanel's reference to the Jmol view
3270 comp.addAlignmentPanel(ap);
3271 if (useinJmolsuperpos)
3273 comp.useAlignmentPanelForSuperposition(ap);
3277 comp.excludeAlignmentPanelForSuperposition(ap);
3279 if (usetoColourbyseq)
3281 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3285 comp.excludeAlignmentPanelForColourbyseq(ap);
3291 // and finally return.
3298 * - minimum version we are comparing against
3300 * - version of data being processsed.
3301 * @return true if version is development/null or evaluates to the same or
3302 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3304 private boolean isVersionStringLaterThan(String supported, String version)
3306 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3307 || version.equalsIgnoreCase("Test")
3308 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3310 System.err.println("Assuming project file with "
3311 + (version == null ? "null" : version)
3312 + " is compatible with Jalview version " + supported);
3317 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3319 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3321 // convert b to decimal to catch bugfix releases within a series
3322 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3323 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3326 if (Float.valueOf(curT) > Float.valueOf(fileT))
3328 // current version is newer than the version that wrote the file
3331 } catch (NumberFormatException nfe)
3334 .println("** WARNING: Version comparison failed for tokens ("
3338 + ")\n** Current: '"
3339 + supported + "' and Version: '" + version + "'");
3342 if (currentV.hasMoreElements())
3344 // fileV has no minor version but identical series to current
3351 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3353 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3355 if (newStructureViewers != null)
3357 sview.getBinding().setFinishedLoadingFromArchive(false);
3358 newStructureViewers.add(sview);
3362 protected void setLoadingFinishedForNewStructureViewers()
3364 if (newStructureViewers != null)
3366 for (JalviewStructureDisplayI sview : newStructureViewers)
3368 sview.getBinding().setFinishedLoadingFromArchive(true);
3370 newStructureViewers.clear();
3371 newStructureViewers = null;
3375 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3376 Alignment al, JalviewModelSequence jms, Viewport view,
3377 String uniqueSeqSetId, String viewId,
3378 ArrayList<JvAnnotRow> autoAlan)
3380 AlignFrame af = null;
3381 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3382 uniqueSeqSetId, viewId);
3384 af.setFileName(file, "Jalview");
3386 for (int i = 0; i < JSEQ.length; i++)
3388 af.viewport.setSequenceColour(af.viewport.getAlignment()
3389 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3392 af.viewport.gatherViewsHere = view.getGatheredViews();
3394 if (view.getSequenceSetId() != null)
3396 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3397 .get(uniqueSeqSetId);
3399 af.viewport.setSequenceSetId(uniqueSeqSetId);
3402 // propagate shared settings to this new view
3403 af.viewport.historyList = av.historyList;
3404 af.viewport.redoList = av.redoList;
3408 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3410 // TODO: check if this method can be called repeatedly without
3411 // side-effects if alignpanel already registered.
3412 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3414 // apply Hidden regions to view.
3415 if (hiddenSeqs != null)
3417 for (int s = 0; s < JSEQ.length; s++)
3419 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3421 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3424 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3426 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3429 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3432 for (int s = 0; s < hiddenSeqs.size(); s++)
3434 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3437 af.viewport.hideSequence(hseqs);
3440 // recover view properties and display parameters
3441 if (view.getViewName() != null)
3443 af.viewport.viewName = view.getViewName();
3444 af.setInitialTabVisible();
3446 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3449 af.viewport.setShowAnnotation(view.getShowAnnotation());
3450 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3452 af.viewport.setColourText(view.getShowColourText());
3454 af.viewport.setConservationSelected(view.getConservationSelected());
3455 af.viewport.setShowJVSuffix(view.getShowFullId());
3456 af.viewport.rightAlignIds = view.getRightAlignIds();
3457 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3458 .getFontStyle(), view.getFontSize()));
3459 af.alignPanel.fontChanged();
3460 af.viewport.setRenderGaps(view.getRenderGaps());
3461 af.viewport.setWrapAlignment(view.getWrapAlignment());
3462 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3463 af.viewport.setShowAnnotation(view.getShowAnnotation());
3464 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3466 af.viewport.setShowBoxes(view.getShowBoxes());
3468 af.viewport.setShowText(view.getShowText());
3470 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3471 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3472 af.viewport.thresholdTextColour = view.getTextColThreshold();
3473 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3474 .isShowUnconserved() : false);
3475 af.viewport.setStartRes(view.getStartRes());
3476 af.viewport.setStartSeq(view.getStartSeq());
3478 ColourSchemeI cs = null;
3479 // apply colourschemes
3480 if (view.getBgColour() != null)
3482 if (view.getBgColour().startsWith("ucs"))
3484 cs = GetUserColourScheme(jms, view.getBgColour());
3486 else if (view.getBgColour().startsWith("Annotation"))
3488 AnnotationColours viewAnnColour = view.getAnnotationColours();
3489 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3496 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3501 cs.setThreshold(view.getPidThreshold(), true);
3502 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3506 af.viewport.setGlobalColourScheme(cs);
3507 af.viewport.setColourAppliesToAllGroups(false);
3509 if (view.getConservationSelected() && cs != null)
3511 cs.setConservationInc(view.getConsThreshold());
3514 af.changeColour(cs);
3516 af.viewport.setColourAppliesToAllGroups(true);
3518 if (view.getShowSequenceFeatures())
3520 af.viewport.showSequenceFeatures = true;
3522 if (view.hasCentreColumnLabels())
3524 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3526 if (view.hasIgnoreGapsinConsensus())
3528 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3531 if (view.hasFollowHighlight())
3533 af.viewport.followHighlight = view.getFollowHighlight();
3535 if (view.hasFollowSelection())
3537 af.viewport.followSelection = view.getFollowSelection();
3539 if (view.hasShowConsensusHistogram())
3541 af.viewport.setShowConsensusHistogram(view
3542 .getShowConsensusHistogram());
3546 af.viewport.setShowConsensusHistogram(true);
3548 if (view.hasShowSequenceLogo())
3550 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3554 af.viewport.setShowSequenceLogo(false);
3556 if (view.hasNormaliseSequenceLogo())
3558 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3560 if (view.hasShowDbRefTooltip())
3562 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3564 if (view.hasShowNPfeatureTooltip())
3566 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3568 if (view.hasShowGroupConsensus())
3570 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3574 af.viewport.setShowGroupConsensus(false);
3576 if (view.hasShowGroupConservation())
3578 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3582 af.viewport.setShowGroupConservation(false);
3585 // recover featre settings
3586 if (jms.getFeatureSettings() != null)
3588 af.viewport.featuresDisplayed = new Hashtable();
3589 String[] renderOrder = new String[jms.getFeatureSettings()
3590 .getSettingCount()];
3591 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3593 Setting setting = jms.getFeatureSettings().getSetting(fs);
3594 if (setting.hasMincolour())
3596 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3597 new java.awt.Color(setting.getMincolour()),
3598 new java.awt.Color(setting.getColour()),
3599 setting.getMin(), setting.getMax()) : new GraduatedColor(
3600 new java.awt.Color(setting.getMincolour()),
3601 new java.awt.Color(setting.getColour()), 0, 1);
3602 if (setting.hasThreshold())
3604 gc.setThresh(setting.getThreshold());
3605 gc.setThreshType(setting.getThreshstate());
3607 gc.setAutoScaled(true); // default
3608 if (setting.hasAutoScale())
3610 gc.setAutoScaled(setting.getAutoScale());
3612 if (setting.hasColourByLabel())
3614 gc.setColourByLabel(setting.getColourByLabel());
3616 // and put in the feature colour table.
3617 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3618 setting.getType(), gc);
3622 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3624 new java.awt.Color(setting.getColour()));
3626 renderOrder[fs] = setting.getType();
3627 if (setting.hasOrder())
3629 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3630 setting.getType(), setting.getOrder());
3634 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3636 fs / jms.getFeatureSettings().getSettingCount());
3638 if (setting.getDisplay())
3640 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3641 setting.getColour()));
3644 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3646 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3647 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3649 Group grp = jms.getFeatureSettings().getGroup(gs);
3650 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3654 if (view.getHiddenColumnsCount() > 0)
3656 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3658 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3659 .getHiddenColumns(c).getEnd() // +1
3663 if (view.getCalcIdParam() != null)
3665 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3667 if (calcIdParam != null)
3669 if (recoverCalcIdParam(calcIdParam, af.viewport))
3674 warn("Couldn't recover parameters for "
3675 + calcIdParam.getCalcId());
3680 af.setMenusFromViewport(af.viewport);
3681 // TODO: we don't need to do this if the viewport is aready visible.
3682 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3684 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3685 reorderAutoannotation(af, al, autoAlan);
3686 af.alignPanel.alignmentChanged();
3690 private ColourSchemeI constructAnnotationColour(
3691 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3692 JalviewModelSequence jms, boolean checkGroupAnnColour)
3694 boolean propagateAnnColour = false;
3695 ColourSchemeI cs = null;
3696 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3697 if (checkGroupAnnColour && al.getGroups() != null
3698 && al.getGroups().size() > 0)
3700 // pre 2.8.1 behaviour
3701 // check to see if we should transfer annotation colours
3702 propagateAnnColour = true;
3703 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3705 if (sg.cs instanceof AnnotationColourGradient)
3707 propagateAnnColour = false;
3711 // int find annotation
3712 if (annAlignment.getAlignmentAnnotation() != null)
3714 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3716 if (annAlignment.getAlignmentAnnotation()[i].label
3717 .equals(viewAnnColour.getAnnotation()))
3719 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3721 annAlignment.getAlignmentAnnotation()[i]
3722 .setThreshold(new jalview.datamodel.GraphLine(
3723 viewAnnColour.getThreshold(), "Threshold",
3724 java.awt.Color.black)
3729 if (viewAnnColour.getColourScheme().equals("None"))
3731 cs = new AnnotationColourGradient(
3732 annAlignment.getAlignmentAnnotation()[i],
3733 new java.awt.Color(viewAnnColour.getMinColour()),
3734 new java.awt.Color(viewAnnColour.getMaxColour()),
3735 viewAnnColour.getAboveThreshold());
3737 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3739 cs = new AnnotationColourGradient(
3740 annAlignment.getAlignmentAnnotation()[i],
3741 GetUserColourScheme(jms,
3742 viewAnnColour.getColourScheme()),
3743 viewAnnColour.getAboveThreshold());
3747 cs = new AnnotationColourGradient(
3748 annAlignment.getAlignmentAnnotation()[i],
3749 ColourSchemeProperty.getColour(al,
3750 viewAnnColour.getColourScheme()),
3751 viewAnnColour.getAboveThreshold());
3753 if (viewAnnColour.hasPerSequence())
3755 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3758 if (viewAnnColour.hasPredefinedColours())
3760 ((AnnotationColourGradient) cs)
3761 .setPredefinedColours(viewAnnColour
3762 .isPredefinedColours());
3764 if (propagateAnnColour && al.getGroups() != null)
3766 // Also use these settings for all the groups
3767 for (int g = 0; g < al.getGroups().size(); g++)
3769 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3777 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3778 * new AnnotationColourGradient(
3779 * annAlignment.getAlignmentAnnotation()[i], new
3780 * java.awt.Color(viewAnnColour. getMinColour()), new
3781 * java.awt.Color(viewAnnColour. getMaxColour()),
3782 * viewAnnColour.getAboveThreshold()); } else
3785 sg.cs = new AnnotationColourGradient(
3786 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3787 viewAnnColour.getAboveThreshold());
3788 if (cs instanceof AnnotationColourGradient)
3790 if (viewAnnColour.hasPerSequence())
3792 ((AnnotationColourGradient) cs)
3793 .setSeqAssociated(viewAnnColour.isPerSequence());
3795 if (viewAnnColour.hasPredefinedColours())
3797 ((AnnotationColourGradient) cs)
3798 .setPredefinedColours(viewAnnColour
3799 .isPredefinedColours());
3815 private void reorderAutoannotation(AlignFrame af, Alignment al,
3816 ArrayList<JvAnnotRow> autoAlan)
3818 // copy over visualization settings for autocalculated annotation in the
3820 if (al.getAlignmentAnnotation() != null)
3823 * Kludge for magic autoannotation names (see JAL-811)
3825 String[] magicNames = new String[]
3826 { "Consensus", "Quality", "Conservation" };
3827 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3828 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3829 for (String nm : magicNames)
3831 visan.put(nm, nullAnnot);
3833 for (JvAnnotRow auan : autoAlan)
3835 visan.put(auan.template.label
3836 + (auan.template.getCalcId() == null ? "" : "\t"
3837 + auan.template.getCalcId()), auan);
3839 int hSize = al.getAlignmentAnnotation().length;
3840 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3841 // work through any autoCalculated annotation already on the view
3842 // removing it if it should be placed in a different location on the
3843 // annotation panel.
3844 List<String> remains = new ArrayList(visan.keySet());
3845 for (int h = 0; h < hSize; h++)
3847 jalview.datamodel.AlignmentAnnotation jalan = al
3848 .getAlignmentAnnotation()[h];
3849 if (jalan.autoCalculated)
3852 JvAnnotRow valan = visan.get(k = jalan.label);
3853 if (jalan.getCalcId() != null)
3855 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3860 // delete the auto calculated row from the alignment
3861 al.deleteAnnotation(jalan, false);
3865 if (valan != nullAnnot)
3867 if (jalan != valan.template)
3869 // newly created autoannotation row instance
3870 // so keep a reference to the visible annotation row
3871 // and copy over all relevant attributes
3872 if (valan.template.graphHeight >= 0)
3875 jalan.graphHeight = valan.template.graphHeight;
3877 jalan.visible = valan.template.visible;
3879 reorder.add(new JvAnnotRow(valan.order, jalan));
3884 // Add any (possibly stale) autocalculated rows that were not appended to
3885 // the view during construction
3886 for (String other : remains)
3888 JvAnnotRow othera = visan.get(other);
3889 if (othera != nullAnnot && othera.template.getCalcId() != null
3890 && othera.template.getCalcId().length() > 0)
3892 reorder.add(othera);
3895 // now put the automatic annotation in its correct place
3896 int s = 0, srt[] = new int[reorder.size()];
3897 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3898 for (JvAnnotRow jvar : reorder)
3901 srt[s++] = jvar.order;
3904 jalview.util.QuickSort.sort(srt, rws);
3905 // and re-insert the annotation at its correct position
3906 for (JvAnnotRow jvar : rws)
3908 al.addAnnotation(jvar.template, jvar.order);
3910 af.alignPanel.adjustAnnotationHeight();
3914 Hashtable skipList = null;
3917 * TODO remove this method
3920 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3921 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3922 * throw new Error("Implementation Error. No skipList defined for this
3923 * Jalview2XML instance."); } return (AlignFrame)
3924 * skipList.get(view.getSequenceSetId()); }
3928 * Check if the Jalview view contained in object should be skipped or not.
3931 * @return true if view's sequenceSetId is a key in skipList
3933 private boolean skipViewport(JalviewModel object)
3935 if (skipList == null)
3940 if (skipList.containsKey(id = object.getJalviewModelSequence()
3941 .getViewport()[0].getSequenceSetId()))
3943 if (Cache.log != null && Cache.log.isDebugEnabled())
3945 Cache.log.debug("Skipping seuqence set id " + id);
3952 public void AddToSkipList(AlignFrame af)
3954 if (skipList == null)
3956 skipList = new Hashtable();
3958 skipList.put(af.getViewport().getSequenceSetId(), af);
3961 public void clearSkipList()
3963 if (skipList != null)
3970 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3972 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3973 Vector dseqs = null;
3976 // create a list of new dataset sequences
3977 dseqs = new Vector();
3979 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3981 Sequence vamsasSeq = vamsasSet.getSequence(i);
3982 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3984 // create a new dataset
3987 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3988 dseqs.copyInto(dsseqs);
3989 ds = new jalview.datamodel.Alignment(dsseqs);
3990 debug("Created new dataset " + vamsasSet.getDatasetId()
3991 + " for alignment " + System.identityHashCode(al));
3992 addDatasetRef(vamsasSet.getDatasetId(), ds);
3994 // set the dataset for the newly imported alignment.
3995 if (al.getDataset() == null)
4004 * sequence definition to create/merge dataset sequence for
4008 * vector to add new dataset sequence to
4010 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4011 AlignmentI ds, Vector dseqs)
4013 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4015 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4016 .get(vamsasSeq.getId());
4017 jalview.datamodel.SequenceI dsq = null;
4018 if (sq != null && sq.getDatasetSequence() != null)
4020 dsq = sq.getDatasetSequence();
4023 String sqid = vamsasSeq.getDsseqid();
4026 // need to create or add a new dataset sequence reference to this sequence
4029 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4034 // make a new dataset sequence
4035 dsq = sq.createDatasetSequence();
4038 // make up a new dataset reference for this sequence
4039 sqid = seqHash(dsq);
4041 dsq.setVamsasId(uniqueSetSuffix + sqid);
4042 seqRefIds.put(sqid, dsq);
4047 dseqs.addElement(dsq);
4052 ds.addSequence(dsq);
4058 { // make this dataset sequence sq's dataset sequence
4059 sq.setDatasetSequence(dsq);
4060 // and update the current dataset alignment
4065 if (!dseqs.contains(dsq))
4072 if (ds.findIndex(dsq) < 0)
4074 ds.addSequence(dsq);
4081 // TODO: refactor this as a merge dataset sequence function
4082 // now check that sq (the dataset sequence) sequence really is the union of
4083 // all references to it
4084 // boolean pre = sq.getStart() < dsq.getStart();
4085 // boolean post = sq.getEnd() > dsq.getEnd();
4089 StringBuffer sb = new StringBuffer();
4090 String newres = jalview.analysis.AlignSeq.extractGaps(
4091 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4092 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4093 && newres.length() > dsq.getLength())
4095 // Update with the longer sequence.
4099 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4100 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4101 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4102 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4104 dsq.setSequence(newres);
4106 // TODO: merges will never happen if we 'know' we have the real dataset
4107 // sequence - this should be detected when id==dssid
4109 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4110 // + (pre ? "prepended" : "") + " "
4111 // + (post ? "appended" : ""));
4116 java.util.Hashtable datasetIds = null;
4118 java.util.IdentityHashMap dataset2Ids = null;
4120 private Alignment getDatasetFor(String datasetId)
4122 if (datasetIds == null)
4124 datasetIds = new Hashtable();
4127 if (datasetIds.containsKey(datasetId))
4129 return (Alignment) datasetIds.get(datasetId);
4134 private void addDatasetRef(String datasetId, Alignment dataset)
4136 if (datasetIds == null)
4138 datasetIds = new Hashtable();
4140 datasetIds.put(datasetId, dataset);
4144 * make a new dataset ID for this jalview dataset alignment
4149 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4151 if (dataset.getDataset() != null)
4153 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4155 String datasetId = makeHashCode(dataset, null);
4156 if (datasetId == null)
4158 // make a new datasetId and record it
4159 if (dataset2Ids == null)
4161 dataset2Ids = new IdentityHashMap();
4165 datasetId = (String) dataset2Ids.get(dataset);
4167 if (datasetId == null)
4169 datasetId = "ds" + dataset2Ids.size() + 1;
4170 dataset2Ids.put(dataset, datasetId);
4176 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4178 for (int d = 0; d < sequence.getDBRefCount(); d++)
4180 DBRef dr = sequence.getDBRef(d);
4181 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4182 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4183 .getVersion(), sequence.getDBRef(d).getAccessionId());
4184 if (dr.getMapping() != null)
4186 entry.setMap(addMapping(dr.getMapping()));
4188 datasetSequence.addDBRef(entry);
4192 private jalview.datamodel.Mapping addMapping(Mapping m)
4194 SequenceI dsto = null;
4195 // Mapping m = dr.getMapping();
4196 int fr[] = new int[m.getMapListFromCount() * 2];
4197 Enumeration f = m.enumerateMapListFrom();
4198 for (int _i = 0; f.hasMoreElements(); _i += 2)
4200 MapListFrom mf = (MapListFrom) f.nextElement();
4201 fr[_i] = mf.getStart();
4202 fr[_i + 1] = mf.getEnd();
4204 int fto[] = new int[m.getMapListToCount() * 2];
4205 f = m.enumerateMapListTo();
4206 for (int _i = 0; f.hasMoreElements(); _i += 2)
4208 MapListTo mf = (MapListTo) f.nextElement();
4209 fto[_i] = mf.getStart();
4210 fto[_i + 1] = mf.getEnd();
4212 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4213 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4214 if (m.getMappingChoice() != null)
4216 MappingChoice mc = m.getMappingChoice();
4217 if (mc.getDseqFor() != null)
4219 String dsfor = "" + mc.getDseqFor();
4220 if (seqRefIds.containsKey(dsfor))
4225 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4229 frefedSequence.add(new Object[]
4236 * local sequence definition
4238 Sequence ms = mc.getSequence();
4239 jalview.datamodel.Sequence djs = null;
4240 String sqid = ms.getDsseqid();
4241 if (sqid != null && sqid.length() > 0)
4244 * recover dataset sequence
4246 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4251 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4252 sqid = ((Object) ms).toString(); // make up a new hascode for
4253 // undefined dataset sequence hash
4254 // (unlikely to happen)
4260 * make a new dataset sequence and add it to refIds hash
4262 djs = new jalview.datamodel.Sequence(ms.getName(),
4264 djs.setStart(jmap.getMap().getToLowest());
4265 djs.setEnd(jmap.getMap().getToHighest());
4266 djs.setVamsasId(uniqueSetSuffix + sqid);
4268 seqRefIds.put(sqid, djs);
4271 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4280 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4281 boolean keepSeqRefs)
4284 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4290 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4294 uniqueSetSuffix = "";
4295 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4300 if (this.frefedSequence == null)
4302 frefedSequence = new Vector();
4305 viewportsAdded = new Hashtable();
4307 AlignFrame af = LoadFromObject(jm, null, false, null);
4308 af.alignPanels.clear();
4309 af.closeMenuItem_actionPerformed(true);
4312 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4313 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4314 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4315 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4316 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4319 return af.alignPanel;
4323 * flag indicating if hashtables should be cleared on finalization TODO this
4324 * flag may not be necessary
4326 private final boolean _cleartables = true;
4328 private Hashtable jvids2vobj;
4333 * @see java.lang.Object#finalize()
4336 protected void finalize() throws Throwable
4338 // really make sure we have no buried refs left.
4343 this.seqRefIds = null;
4344 this.seqsToIds = null;
4348 private void warn(String msg)
4353 private void warn(String msg, Exception e)
4355 if (Cache.log != null)
4359 Cache.log.warn(msg, e);
4363 Cache.log.warn(msg);
4368 System.err.println("Warning: " + msg);
4371 e.printStackTrace();
4376 private void debug(String string)
4378 debug(string, null);
4381 private void debug(String msg, Exception e)
4383 if (Cache.log != null)
4387 Cache.log.debug(msg, e);
4391 Cache.log.debug(msg);
4396 System.err.println("Warning: " + msg);
4399 e.printStackTrace();
4405 * set the object to ID mapping tables used to write/recover objects and XML
4406 * ID strings for the jalview project. If external tables are provided then
4407 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4408 * object goes out of scope. - also populates the datasetIds hashtable with
4409 * alignment objects containing dataset sequences
4412 * Map from ID strings to jalview datamodel
4414 * Map from jalview datamodel to ID strings
4418 public void setObjectMappingTables(Hashtable vobj2jv,
4419 IdentityHashMap jv2vobj)
4421 this.jv2vobj = jv2vobj;
4422 this.vobj2jv = vobj2jv;
4423 Iterator ds = jv2vobj.keySet().iterator();
4425 while (ds.hasNext())
4427 Object jvobj = ds.next();
4428 id = jv2vobj.get(jvobj).toString();
4429 if (jvobj instanceof jalview.datamodel.Alignment)
4431 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4433 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4436 else if (jvobj instanceof jalview.datamodel.Sequence)
4438 // register sequence object so the XML parser can recover it.
4439 if (seqRefIds == null)
4441 seqRefIds = new Hashtable();
4443 if (seqsToIds == null)
4445 seqsToIds = new IdentityHashMap();
4447 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4448 seqsToIds.put(jvobj, id);
4450 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4452 if (annotationIds == null)
4454 annotationIds = new Hashtable();
4457 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4458 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4459 if (jvann.annotationId == null)
4461 jvann.annotationId = anid;
4463 if (!jvann.annotationId.equals(anid))
4465 // TODO verify that this is the correct behaviour
4466 this.warn("Overriding Annotation ID for " + anid
4467 + " from different id : " + jvann.annotationId);
4468 jvann.annotationId = anid;
4471 else if (jvobj instanceof String)
4473 if (jvids2vobj == null)
4475 jvids2vobj = new Hashtable();
4476 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4481 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4487 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4488 * objects created from the project archive. If string is null (default for
4489 * construction) then suffix will be set automatically.
4493 public void setUniqueSetSuffix(String string)
4495 uniqueSetSuffix = string;
4500 * uses skipList2 as the skipList for skipping views on sequence sets
4501 * associated with keys in the skipList
4505 public void setSkipList(Hashtable skipList2)
4507 skipList = skipList2;