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.AlignedCodonFrame;
26 import jalview.datamodel.Alignment;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.SequenceI;
30 import jalview.schemabinding.version2.AlcodMap;
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 = af.alignPanels.get(ap);
406 String fileName = apSize == 1 ? shortName : ap + shortName;
407 if (!fileName.endsWith(".xml"))
409 fileName = fileName + ".xml";
412 SaveState(apanel, fileName, jout);
414 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
416 if (!dsses.containsKey(dssid))
418 dsses.put(dssid, af);
425 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
431 } catch (Exception foo)
436 } catch (Exception ex)
438 // TODO: inform user of the problem - they need to know if their data was
440 if (errorMessage == null)
442 errorMessage = "Couldn't write Jalview Archive - see error output for details";
444 ex.printStackTrace();
448 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
449 public boolean SaveAlignment(AlignFrame af, String jarFile,
454 int ap, apSize = af.alignPanels.size();
455 FileOutputStream fos = new FileOutputStream(jarFile);
456 JarOutputStream jout = new JarOutputStream(fos);
457 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
458 for (ap = 0; ap < apSize; ap++)
460 AlignmentPanel apanel = af.alignPanels
462 String jfileName = apSize == 1 ? fileName : fileName + ap;
463 if (!jfileName.endsWith(".xml"))
465 jfileName = jfileName + ".xml";
467 SaveState(apanel, jfileName, jout);
468 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
470 if (!dsses.containsKey(dssid))
472 dsses.put(dssid, af);
475 writeDatasetFor(dsses, fileName, jout);
479 } catch (Exception foo)
485 } catch (Exception ex)
487 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
488 ex.printStackTrace();
493 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
494 String fileName, JarOutputStream jout)
497 for (String dssids : dsses.keySet())
499 AlignFrame _af = dsses.get(dssids);
500 String jfileName = fileName + " Dataset for " + _af.getTitle();
501 if (!jfileName.endsWith(".xml"))
503 jfileName = jfileName + ".xml";
505 SaveState(_af.alignPanel, jfileName, true, jout);
510 * create a JalviewModel from an algnment view and marshall it to a
514 * panel to create jalview model for
516 * name of alignment panel written to output stream
522 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
523 JarOutputStream jout)
525 return SaveState(ap, fileName, false, jout);
529 * create a JalviewModel from an algnment view and marshall it to a
533 * panel to create jalview model for
535 * name of alignment panel written to output stream
537 * when true, only write the dataset for the alignment, not the data
538 * associated with the view.
544 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
545 boolean storeDS, JarOutputStream jout)
548 Vector jmolViewIds = new Vector(); //
549 Vector userColours = new Vector();
551 AlignViewport av = ap.av;
553 JalviewModel object = new JalviewModel();
554 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
556 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
557 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
558 "Development Build"));
560 jalview.datamodel.AlignmentI jal = av.getAlignment();
562 if (av.hasHiddenRows())
564 jal = jal.getHiddenSequences().getFullAlignment();
567 SequenceSet vamsasSet = new SequenceSet();
569 JalviewModelSequence jms = new JalviewModelSequence();
571 vamsasSet.setGapChar(jal.getGapCharacter() + "");
573 if (jal.getDataset() != null)
575 // dataset id is the dataset's hashcode
576 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
579 // switch jal and the dataset
580 jal = jal.getDataset();
583 if (jal.getProperties() != null)
585 Enumeration en = jal.getProperties().keys();
586 while (en.hasMoreElements())
588 String key = en.nextElement().toString();
589 SequenceSetProperties ssp = new SequenceSetProperties();
591 ssp.setValue(jal.getProperties().get(key).toString());
592 vamsasSet.addSequenceSetProperties(ssp);
597 Set<String> calcIdSet = new HashSet<String>();
601 jalview.datamodel.SequenceI jds, jdatasq;
602 for (int i = 0; i < jal.getHeight(); i++)
604 jds = jal.getSequenceAt(i);
605 jdatasq = jds.getDatasetSequence() == null ? jds : jds
606 .getDatasetSequence();
609 if (seqRefIds.get(id) != null)
611 // This happens for two reasons: 1. multiple views are being serialised.
612 // 2. the hashCode has collided with another sequence's code. This DOES
613 // HAPPEN! (PF00072.15.stk does this)
614 // JBPNote: Uncomment to debug writing out of files that do not read
615 // back in due to ArrayOutOfBoundExceptions.
616 // System.err.println("vamsasSeq backref: "+id+"");
617 // System.err.println(jds.getName()+"
618 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
619 // System.err.println("Hashcode: "+seqHash(jds));
620 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
621 // System.err.println(rsq.getName()+"
622 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
623 // System.err.println("Hashcode: "+seqHash(rsq));
627 vamsasSeq = createVamsasSequence(id, jds);
628 vamsasSet.addSequence(vamsasSeq);
629 seqRefIds.put(id, jds);
633 jseq.setStart(jds.getStart());
634 jseq.setEnd(jds.getEnd());
635 jseq.setColour(av.getSequenceColour(jds).getRGB());
637 jseq.setId(id); // jseq id should be a string not a number
640 // Store any sequences this sequence represents
641 if (av.hasHiddenRows())
643 jseq.setHidden(av.getAlignment().getHiddenSequences()
646 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
648 jalview.datamodel.SequenceI[] reps = av
649 .getRepresentedSequences(jal.getSequenceAt(i))
650 .getSequencesInOrder(jal);
652 for (int h = 0; h < reps.length; h++)
654 if (reps[h] != jal.getSequenceAt(i))
656 jseq.addHiddenSequences(jal.findIndex(reps[h]));
663 if (jdatasq.getSequenceFeatures() != null)
665 jalview.datamodel.SequenceFeature[] sf = jdatasq
666 .getSequenceFeatures();
668 while (index < sf.length)
670 Features features = new Features();
672 features.setBegin(sf[index].getBegin());
673 features.setEnd(sf[index].getEnd());
674 features.setDescription(sf[index].getDescription());
675 features.setType(sf[index].getType());
676 features.setFeatureGroup(sf[index].getFeatureGroup());
677 features.setScore(sf[index].getScore());
678 if (sf[index].links != null)
680 for (int l = 0; l < sf[index].links.size(); l++)
682 OtherData keyValue = new OtherData();
683 keyValue.setKey("LINK_" + l);
684 keyValue.setValue(sf[index].links.elementAt(l).toString());
685 features.addOtherData(keyValue);
688 if (sf[index].otherDetails != null)
691 Enumeration keys = sf[index].otherDetails.keys();
692 while (keys.hasMoreElements())
694 key = keys.nextElement().toString();
695 OtherData keyValue = new OtherData();
696 keyValue.setKey(key);
697 keyValue.setValue(sf[index].otherDetails.get(key).toString());
698 features.addOtherData(keyValue);
702 jseq.addFeatures(features);
707 if (jdatasq.getPDBId() != null)
709 Enumeration en = jdatasq.getPDBId().elements();
710 while (en.hasMoreElements())
712 Pdbids pdb = new Pdbids();
713 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
716 pdb.setId(entry.getId());
717 pdb.setType(entry.getType());
719 // store any JMol views associated with this seqeunce
720 // this section copes with duplicate entries in the project, so a
721 // dataset only view *should* be coped with sensibly
723 // This must have been loaded, is it still visible?
724 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
725 String matchedFile = null;
726 for (int f = frames.length - 1; f > -1; f--)
728 if (frames[f] instanceof AppJmol)
730 jmol = (AppJmol) frames[f];
731 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
733 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
734 && !(entry.getId().length() > 4 && entry
738 jmol.jmb.pdbentry[peid].getId()
743 if (matchedFile == null)
745 matchedFile = jmol.jmb.pdbentry[peid].getFile();
747 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
751 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
752 + jmol.jmb.pdbentry[peid].getFile());
756 // can get at it if the ID
757 // match is ambiguous (e.g.
759 String statestring = jmol.jmb.viewer.getStateInfo();
761 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
763 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
764 if (jds == jmol.jmb.sequence[peid][smap])
766 StructureState state = new StructureState();
767 state.setVisible(true);
768 state.setXpos(jmol.getX());
769 state.setYpos(jmol.getY());
770 state.setWidth(jmol.getWidth());
771 state.setHeight(jmol.getHeight());
772 state.setViewId(jmol.getViewId());
773 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
774 state.setColourwithAlignPanel(jmol
775 .isUsedforcolourby(ap));
776 state.setColourByJmol(jmol.isColouredByJmol());
777 if (!jmolViewIds.contains(state.getViewId()))
779 // Make sure we only store a Jmol state once in each XML
781 jmolViewIds.addElement(state.getViewId());
782 state.setContent(statestring.replaceAll("\n", ""));
786 state.setContent("# duplicate state");
788 pdb.addStructureState(state);
796 if (matchedFile != null || entry.getFile() != null)
798 if (entry.getFile() != null)
801 matchedFile = entry.getFile();
803 pdb.setFile(matchedFile); // entry.getFile());
804 if (pdbfiles == null)
806 pdbfiles = new Vector();
809 if (!pdbfiles.contains(entry.getId()))
811 pdbfiles.addElement(entry.getId());
814 File file = new File(matchedFile);
815 if (file.exists() && jout != null)
817 byte[] data = new byte[(int) file.length()];
818 jout.putNextEntry(new JarEntry(entry.getId()));
819 DataInputStream dis = new DataInputStream(
820 new FileInputStream(file));
823 DataOutputStream dout = new DataOutputStream(jout);
824 dout.write(data, 0, data.length);
828 } catch (Exception ex)
830 ex.printStackTrace();
836 if (entry.getProperty() != null)
838 PdbentryItem item = new PdbentryItem();
839 Hashtable properties = entry.getProperty();
840 Enumeration en2 = properties.keys();
841 while (en2.hasMoreElements())
843 Property prop = new Property();
844 String key = en2.nextElement().toString();
846 prop.setValue(properties.get(key).toString());
847 item.addProperty(prop);
849 pdb.addPdbentryItem(item);
859 if (!storeDS && av.hasHiddenRows())
861 jal = av.getAlignment();
864 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
866 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
867 for (int i = 0; i < jac.length; i++)
869 AlcodonFrame alc = new AlcodonFrame();
870 vamsasSet.addAlcodonFrame(alc);
871 if (jac[i].getProtMappings() != null
872 && jac[i].getProtMappings().length > 0)
874 SequenceI[] dnas = jac[i].getdnaSeqs();
875 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
876 for (int m = 0; m < pmaps.length; m++)
878 AlcodMap alcmap = new AlcodMap();
879 alcmap.setDnasq(seqHash(dnas[m]));
880 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
882 alc.addAlcodMap(alcmap);
889 // /////////////////////////////////
890 if (!storeDS && av.currentTree != null)
892 // FIND ANY ASSOCIATED TREES
893 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
894 if (Desktop.desktop != null)
896 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
898 for (int t = 0; t < frames.length; t++)
900 if (frames[t] instanceof TreePanel)
902 TreePanel tp = (TreePanel) frames[t];
904 if (tp.treeCanvas.av.getAlignment() == jal)
906 Tree tree = new Tree();
907 tree.setTitle(tp.getTitle());
908 tree.setCurrentTree((av.currentTree == tp.getTree()));
909 tree.setNewick(tp.getTree().toString());
910 tree.setThreshold(tp.treeCanvas.threshold);
912 tree.setFitToWindow(tp.fitToWindow.getState());
913 tree.setFontName(tp.getTreeFont().getName());
914 tree.setFontSize(tp.getTreeFont().getSize());
915 tree.setFontStyle(tp.getTreeFont().getStyle());
916 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
918 tree.setShowBootstrap(tp.bootstrapMenu.getState());
919 tree.setShowDistances(tp.distanceMenu.getState());
921 tree.setHeight(tp.getHeight());
922 tree.setWidth(tp.getWidth());
923 tree.setXpos(tp.getX());
924 tree.setYpos(tp.getY());
925 tree.setId(makeHashCode(tp, null));
934 * store forward refs from an annotationRow to any groups
936 IdentityHashMap groupRefs = new IdentityHashMap();
939 for (SequenceI sq : jal.getSequences())
941 // Store annotation on dataset sequences only
942 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
943 if (aa != null && aa.length > 0)
945 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
952 if (jal.getAlignmentAnnotation() != null)
954 // Store the annotation shown on the alignment.
955 jalview.datamodel.AlignmentAnnotation[] aa = jal
956 .getAlignmentAnnotation();
957 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
962 if (jal.getGroups() != null)
964 JGroup[] groups = new JGroup[jal.getGroups().size()];
966 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
968 groups[++i] = new JGroup();
970 groups[i].setStart(sg.getStartRes());
971 groups[i].setEnd(sg.getEndRes());
972 groups[i].setName(sg.getName());
973 if (groupRefs.containsKey(sg))
975 // group has references so set it's ID field
976 groups[i].setId(groupRefs.get(sg).toString());
980 if (sg.cs.conservationApplied())
982 groups[i].setConsThreshold(sg.cs.getConservationInc());
984 if (sg.cs instanceof jalview.schemes.UserColourScheme)
986 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
992 .setColour(ColourSchemeProperty.getColourName(sg.cs));
995 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
997 groups[i].setColour("AnnotationColourGradient");
998 groups[i].setAnnotationColours(constructAnnotationColours(
999 (jalview.schemes.AnnotationColourGradient) sg.cs,
1002 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1005 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
1009 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1012 groups[i].setPidThreshold(sg.cs.getThreshold());
1015 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1016 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1017 groups[i].setDisplayText(sg.getDisplayText());
1018 groups[i].setColourText(sg.getColourText());
1019 groups[i].setTextCol1(sg.textColour.getRGB());
1020 groups[i].setTextCol2(sg.textColour2.getRGB());
1021 groups[i].setTextColThreshold(sg.thresholdTextColour);
1022 groups[i].setShowUnconserved(sg.getShowNonconserved());
1023 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1024 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1025 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1026 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1027 for (int s = 0; s < sg.getSize(); s++)
1029 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1031 groups[i].addSeq(seqHash(seq));
1035 jms.setJGroup(groups);
1039 // /////////SAVE VIEWPORT
1040 Viewport view = new Viewport();
1041 view.setTitle(ap.alignFrame.getTitle());
1042 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1043 av.getSequenceSetId()));
1044 view.setId(av.getViewId());
1045 view.setViewName(av.viewName);
1046 view.setGatheredViews(av.gatherViewsHere);
1048 if (ap.av.explodedPosition != null)
1050 view.setXpos(av.explodedPosition.x);
1051 view.setYpos(av.explodedPosition.y);
1052 view.setWidth(av.explodedPosition.width);
1053 view.setHeight(av.explodedPosition.height);
1057 view.setXpos(ap.alignFrame.getBounds().x);
1058 view.setYpos(ap.alignFrame.getBounds().y);
1059 view.setWidth(ap.alignFrame.getBounds().width);
1060 view.setHeight(ap.alignFrame.getBounds().height);
1063 view.setStartRes(av.startRes);
1064 view.setStartSeq(av.startSeq);
1066 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1068 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1071 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1073 AnnotationColours ac = constructAnnotationColours(
1074 (jalview.schemes.AnnotationColourGradient) av
1075 .getGlobalColourScheme(),
1078 view.setAnnotationColours(ac);
1079 view.setBgColour("AnnotationColourGradient");
1083 view.setBgColour(ColourSchemeProperty.getColourName(av
1084 .getGlobalColourScheme()));
1087 ColourSchemeI cs = av.getGlobalColourScheme();
1091 if (cs.conservationApplied())
1093 view.setConsThreshold(cs.getConservationInc());
1094 if (cs instanceof jalview.schemes.UserColourScheme)
1096 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1100 if (cs instanceof ResidueColourScheme)
1102 view.setPidThreshold(cs.getThreshold());
1106 view.setConservationSelected(av.getConservationSelected());
1107 view.setPidSelected(av.getAbovePIDThreshold());
1108 view.setFontName(av.font.getName());
1109 view.setFontSize(av.font.getSize());
1110 view.setFontStyle(av.font.getStyle());
1111 view.setRenderGaps(av.renderGaps);
1112 view.setShowAnnotation(av.getShowAnnotation());
1113 view.setShowBoxes(av.getShowBoxes());
1114 view.setShowColourText(av.getColourText());
1115 view.setShowFullId(av.getShowJVSuffix());
1116 view.setRightAlignIds(av.rightAlignIds);
1117 view.setShowSequenceFeatures(av.showSequenceFeatures);
1118 view.setShowText(av.getShowText());
1119 view.setShowUnconserved(av.getShowUnconserved());
1120 view.setWrapAlignment(av.getWrapAlignment());
1121 view.setTextCol1(av.textColour.getRGB());
1122 view.setTextCol2(av.textColour2.getRGB());
1123 view.setTextColThreshold(av.thresholdTextColour);
1124 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1125 view.setShowSequenceLogo(av.isShowSequenceLogo());
1126 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1127 view.setShowGroupConsensus(av.isShowGroupConsensus());
1128 view.setShowGroupConservation(av.isShowGroupConservation());
1129 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1130 view.setShowDbRefTooltip(av.isShowDbRefs());
1131 view.setFollowHighlight(av.followHighlight);
1132 view.setFollowSelection(av.followSelection);
1133 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1134 if (av.featuresDisplayed != null)
1136 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1138 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1140 Vector settingsAdded = new Vector();
1141 Object gstyle = null;
1142 GraduatedColor gcol = null;
1143 if (renderOrder != null)
1145 for (int ro = 0; ro < renderOrder.length; ro++)
1147 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1148 .getFeatureStyle(renderOrder[ro]);
1149 Setting setting = new Setting();
1150 setting.setType(renderOrder[ro]);
1151 if (gstyle instanceof GraduatedColor)
1153 gcol = (GraduatedColor) gstyle;
1154 setting.setColour(gcol.getMaxColor().getRGB());
1155 setting.setMincolour(gcol.getMinColor().getRGB());
1156 setting.setMin(gcol.getMin());
1157 setting.setMax(gcol.getMax());
1158 setting.setColourByLabel(gcol.isColourByLabel());
1159 setting.setAutoScale(gcol.isAutoScale());
1160 setting.setThreshold(gcol.getThresh());
1161 setting.setThreshstate(gcol.getThreshType());
1165 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1166 .getColour(renderOrder[ro]).getRGB());
1169 setting.setDisplay(av.featuresDisplayed
1170 .containsKey(renderOrder[ro]));
1171 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1172 .getOrder(renderOrder[ro]);
1175 setting.setOrder(rorder);
1177 fs.addSetting(setting);
1178 settingsAdded.addElement(renderOrder[ro]);
1182 // Make sure we save none displayed feature settings
1183 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1184 .keySet().iterator();
1185 while (en.hasNext())
1187 String key = en.next().toString();
1188 if (settingsAdded.contains(key))
1193 Setting setting = new Setting();
1194 setting.setType(key);
1195 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1196 .getColour(key).getRGB());
1198 setting.setDisplay(false);
1199 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1203 setting.setOrder(rorder);
1205 fs.addSetting(setting);
1206 settingsAdded.addElement(key);
1208 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1209 .keySet().iterator();
1210 Vector groupsAdded = new Vector();
1211 while (en.hasNext())
1213 String grp = en.next().toString();
1214 if (groupsAdded.contains(grp))
1218 Group g = new Group();
1220 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas
1221 .getFeatureRenderer().featureGroups.get(grp))
1224 groupsAdded.addElement(grp);
1226 jms.setFeatureSettings(fs);
1230 if (av.hasHiddenColumns())
1232 if (av.getColumnSelection() == null
1233 || av.getColumnSelection().getHiddenColumns() == null)
1235 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1239 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1242 int[] region = (int[]) av.getColumnSelection()
1243 .getHiddenColumns().elementAt(c);
1244 HiddenColumns hc = new HiddenColumns();
1245 hc.setStart(region[0]);
1246 hc.setEnd(region[1]);
1247 view.addHiddenColumns(hc);
1251 if (calcIdSet.size() > 0)
1253 for (String calcId : calcIdSet)
1255 if (calcId.trim().length() > 0)
1257 CalcIdParam cidp = createCalcIdParam(calcId, av);
1258 // Some calcIds have no parameters.
1261 view.addCalcIdParam(cidp);
1267 jms.addViewport(view);
1269 object.setJalviewModelSequence(jms);
1270 object.getVamsasModel().addSequenceSet(vamsasSet);
1272 if (jout != null && fileName != null)
1274 // We may not want to write the object to disk,
1275 // eg we can copy the alignViewport to a new view object
1276 // using save and then load
1279 JarEntry entry = new JarEntry(fileName);
1280 jout.putNextEntry(entry);
1281 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1283 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1285 marshaller.marshal(object);
1288 } catch (Exception ex)
1290 // TODO: raise error in GUI if marshalling failed.
1291 ex.printStackTrace();
1297 private AnnotationColours constructAnnotationColours(
1298 AnnotationColourGradient acg, Vector userColours,
1299 JalviewModelSequence jms)
1301 AnnotationColours ac = new AnnotationColours();
1302 ac.setAboveThreshold(acg.getAboveThreshold());
1303 ac.setThreshold(acg.getAnnotationThreshold());
1304 ac.setAnnotation(acg.getAnnotation());
1305 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1307 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1312 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1316 ac.setMaxColour(acg.getMaxColour().getRGB());
1317 ac.setMinColour(acg.getMinColour().getRGB());
1318 ac.setPerSequence(acg.isSeqAssociated());
1319 ac.setPredefinedColours(acg.isPredefinedColours());
1323 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1324 IdentityHashMap groupRefs, AlignmentViewport av,
1325 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1328 for (int i = 0; i < aa.length; i++)
1330 Annotation an = new Annotation();
1332 if (aa[i].annotationId != null)
1334 annotationIds.put(aa[i].annotationId, aa[i]);
1337 an.setId(aa[i].annotationId);
1339 an.setVisible(aa[i].visible);
1341 an.setDescription(aa[i].description);
1343 if (aa[i].sequenceRef != null)
1345 // TODO later annotation sequenceRef should be the XML ID of the
1346 // sequence rather than its display name
1347 an.setSequenceRef(aa[i].sequenceRef.getName());
1349 if (aa[i].groupRef != null)
1351 Object groupIdr = groupRefs.get(aa[i].groupRef);
1352 if (groupIdr == null)
1354 // make a locally unique String
1355 groupRefs.put(aa[i].groupRef,
1356 groupIdr = ("" + System.currentTimeMillis()
1357 + aa[i].groupRef.getName() + groupRefs.size()));
1359 an.setGroupRef(groupIdr.toString());
1362 // store all visualization attributes for annotation
1363 an.setGraphHeight(aa[i].graphHeight);
1364 an.setCentreColLabels(aa[i].centreColLabels);
1365 an.setScaleColLabels(aa[i].scaleColLabel);
1366 an.setShowAllColLabels(aa[i].showAllColLabels);
1367 an.setBelowAlignment(aa[i].belowAlignment);
1369 if (aa[i].graph > 0)
1372 an.setGraphType(aa[i].graph);
1373 an.setGraphGroup(aa[i].graphGroup);
1374 if (aa[i].getThreshold() != null)
1376 ThresholdLine line = new ThresholdLine();
1377 line.setLabel(aa[i].getThreshold().label);
1378 line.setValue(aa[i].getThreshold().value);
1379 line.setColour(aa[i].getThreshold().colour.getRGB());
1380 an.setThresholdLine(line);
1388 an.setLabel(aa[i].label);
1390 if (aa[i] == av.getAlignmentQualityAnnot()
1391 || aa[i] == av.getAlignmentConservationAnnotation()
1392 || aa[i] == av.getAlignmentConsensusAnnotation()
1393 || aa[i].autoCalculated)
1395 // new way of indicating autocalculated annotation -
1396 an.setAutoCalculated(aa[i].autoCalculated);
1398 if (aa[i].hasScore())
1400 an.setScore(aa[i].getScore());
1403 if (aa[i].getCalcId() != null)
1405 calcIdSet.add(aa[i].getCalcId());
1406 an.setCalcId(aa[i].getCalcId());
1408 if (aa[i].hasProperties())
1410 for (String pr : aa[i].getProperties())
1412 Property prop = new Property();
1414 prop.setValue(aa[i].getProperty(pr));
1415 an.addProperty(prop);
1418 AnnotationElement ae;
1419 if (aa[i].annotations != null)
1421 an.setScoreOnly(false);
1422 for (int a = 0; a < aa[i].annotations.length; a++)
1424 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1429 ae = new AnnotationElement();
1430 if (aa[i].annotations[a].description != null)
1432 ae.setDescription(aa[i].annotations[a].description);
1434 if (aa[i].annotations[a].displayCharacter != null)
1436 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1439 if (!Float.isNaN(aa[i].annotations[a].value))
1441 ae.setValue(aa[i].annotations[a].value);
1445 if (aa[i].annotations[a].secondaryStructure > ' ')
1447 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1451 if (aa[i].annotations[a].colour != null
1452 && aa[i].annotations[a].colour != java.awt.Color.black)
1454 ae.setColour(aa[i].annotations[a].colour.getRGB());
1457 an.addAnnotationElement(ae);
1458 if (aa[i].autoCalculated)
1460 // only write one non-null entry into the annotation row -
1461 // sufficient to get the visualization attributes necessary to
1469 an.setScoreOnly(true);
1471 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1473 // skip autocalculated annotation - these are only provided for
1475 vamsasSet.addAnnotation(an);
1481 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1483 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1484 if (settings != null)
1486 CalcIdParam vCalcIdParam = new CalcIdParam();
1487 vCalcIdParam.setCalcId(calcId);
1488 vCalcIdParam.addServiceURL(settings.getServiceURI());
1489 // generic URI allowing a third party to resolve another instance of the
1490 // service used for this calculation
1491 for (String urls : settings.getServiceURLs())
1493 vCalcIdParam.addServiceURL(urls);
1495 vCalcIdParam.setVersion("1.0");
1496 if (settings.getPreset() != null)
1498 WsParamSetI setting = settings.getPreset();
1499 vCalcIdParam.setName(setting.getName());
1500 vCalcIdParam.setDescription(setting.getDescription());
1504 vCalcIdParam.setName("");
1505 vCalcIdParam.setDescription("Last used parameters");
1507 // need to be able to recover 1) settings 2) user-defined presets or
1508 // recreate settings from preset 3) predefined settings provided by
1509 // service - or settings that can be transferred (or discarded)
1510 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1512 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1513 // todo - decide if updateImmediately is needed for any projects.
1515 return vCalcIdParam;
1520 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1523 if (calcIdParam.getVersion().equals("1.0"))
1525 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1526 .getPreferredServiceFor(calcIdParam.getServiceURL());
1527 if (service != null)
1529 WsParamSetI parmSet = null;
1532 parmSet = service.getParamStore().parseServiceParameterFile(
1533 calcIdParam.getName(), calcIdParam.getDescription(),
1534 calcIdParam.getServiceURL(),
1535 calcIdParam.getParameters().replace("|\\n|", "\n"));
1536 } catch (IOException x)
1538 warn("Couldn't parse parameter data for "
1539 + calcIdParam.getCalcId(), x);
1542 List<ArgumentI> argList = null;
1543 if (calcIdParam.getName().length() > 0)
1545 parmSet = service.getParamStore()
1546 .getPreset(calcIdParam.getName());
1547 if (parmSet != null)
1549 // TODO : check we have a good match with settings in AACon -
1550 // otherwise we'll need to create a new preset
1555 argList = parmSet.getArguments();
1558 AAConSettings settings = new AAConSettings(
1559 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1560 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1561 calcIdParam.isNeedsUpdate());
1566 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1570 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1574 * External mapping between jalview objects and objects yielding a valid and
1575 * unique object ID string. This is null for normal Jalview project IO, but
1576 * non-null when a jalview project is being read or written as part of a
1579 IdentityHashMap jv2vobj = null;
1582 * Construct a unique ID for jvobj using either existing bindings or if none
1583 * exist, the result of the hashcode call for the object.
1586 * jalview data object
1587 * @return unique ID for referring to jvobj
1589 private String makeHashCode(Object jvobj, String altCode)
1591 if (jv2vobj != null)
1593 Object id = jv2vobj.get(jvobj);
1596 return id.toString();
1598 // check string ID mappings
1599 if (jvids2vobj != null && jvobj instanceof String)
1601 id = jvids2vobj.get(jvobj);
1605 return id.toString();
1607 // give up and warn that something has gone wrong
1608 warn("Cannot find ID for object in external mapping : " + jvobj);
1614 * return local jalview object mapped to ID, if it exists
1618 * @return null or object bound to idcode
1620 private Object retrieveExistingObj(String idcode)
1622 if (idcode != null && vobj2jv != null)
1624 return vobj2jv.get(idcode);
1630 * binding from ID strings from external mapping table to jalview data model
1633 private Hashtable vobj2jv;
1635 private Sequence createVamsasSequence(String id, SequenceI jds)
1637 return createVamsasSequence(true, id, jds, null);
1640 private Sequence createVamsasSequence(boolean recurse, String id,
1641 SequenceI jds, SequenceI parentseq)
1643 Sequence vamsasSeq = new Sequence();
1644 vamsasSeq.setId(id);
1645 vamsasSeq.setName(jds.getName());
1646 vamsasSeq.setSequence(jds.getSequenceAsString());
1647 vamsasSeq.setDescription(jds.getDescription());
1648 jalview.datamodel.DBRefEntry[] dbrefs = null;
1649 if (jds.getDatasetSequence() != null)
1651 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1652 if (jds.getDatasetSequence().getDBRef() != null)
1654 dbrefs = jds.getDatasetSequence().getDBRef();
1659 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1660 // dataset sequences only
1661 dbrefs = jds.getDBRef();
1665 for (int d = 0; d < dbrefs.length; d++)
1667 DBRef dbref = new DBRef();
1668 dbref.setSource(dbrefs[d].getSource());
1669 dbref.setVersion(dbrefs[d].getVersion());
1670 dbref.setAccessionId(dbrefs[d].getAccessionId());
1671 if (dbrefs[d].hasMap())
1673 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1675 dbref.setMapping(mp);
1677 vamsasSeq.addDBRef(dbref);
1683 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1684 SequenceI parentseq, SequenceI jds, boolean recurse)
1687 if (jmp.getMap() != null)
1691 jalview.util.MapList mlst = jmp.getMap();
1692 int r[] = mlst.getFromRanges();
1693 for (int s = 0; s < r.length; s += 2)
1695 MapListFrom mfrom = new MapListFrom();
1696 mfrom.setStart(r[s]);
1697 mfrom.setEnd(r[s + 1]);
1698 mp.addMapListFrom(mfrom);
1700 r = mlst.getToRanges();
1701 for (int s = 0; s < r.length; s += 2)
1703 MapListTo mto = new MapListTo();
1705 mto.setEnd(r[s + 1]);
1706 mp.addMapListTo(mto);
1708 mp.setMapFromUnit(mlst.getFromRatio());
1709 mp.setMapToUnit(mlst.getToRatio());
1710 if (jmp.getTo() != null)
1712 MappingChoice mpc = new MappingChoice();
1714 && (parentseq != jmp.getTo() || parentseq
1715 .getDatasetSequence() != jmp.getTo()))
1717 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1723 SequenceI ps = null;
1724 if (parentseq != jmp.getTo()
1725 && parentseq.getDatasetSequence() != jmp.getTo())
1727 // chaining dbref rather than a handshaking one
1728 jmpid = seqHash(ps = jmp.getTo());
1732 jmpid = seqHash(ps = parentseq);
1734 mpc.setDseqFor(jmpid);
1735 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1737 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1738 seqRefIds.put(mpc.getDseqFor(), ps);
1742 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1745 mp.setMappingChoice(mpc);
1751 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1752 Vector userColours, JalviewModelSequence jms)
1755 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1756 boolean newucs = false;
1757 if (!userColours.contains(ucs))
1759 userColours.add(ucs);
1762 id = "ucs" + userColours.indexOf(ucs);
1765 // actually create the scheme's entry in the XML model
1766 java.awt.Color[] colours = ucs.getColours();
1767 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1768 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1770 for (int i = 0; i < colours.length; i++)
1772 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1773 col.setName(ResidueProperties.aa[i]);
1774 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1775 jbucs.addColour(col);
1777 if (ucs.getLowerCaseColours() != null)
1779 colours = ucs.getLowerCaseColours();
1780 for (int i = 0; i < colours.length; i++)
1782 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1783 col.setName(ResidueProperties.aa[i].toLowerCase());
1784 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1785 jbucs.addColour(col);
1790 uc.setUserColourScheme(jbucs);
1791 jms.addUserColours(uc);
1797 jalview.schemes.UserColourScheme GetUserColourScheme(
1798 JalviewModelSequence jms, String id)
1800 UserColours[] uc = jms.getUserColours();
1801 UserColours colours = null;
1803 for (int i = 0; i < uc.length; i++)
1805 if (uc[i].getId().equals(id))
1813 java.awt.Color[] newColours = new java.awt.Color[24];
1815 for (int i = 0; i < 24; i++)
1817 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1818 .getUserColourScheme().getColour(i).getRGB(), 16));
1821 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1824 if (colours.getUserColourScheme().getColourCount() > 24)
1826 newColours = new java.awt.Color[23];
1827 for (int i = 0; i < 23; i++)
1829 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1830 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1832 ucs.setLowerCaseColours(newColours);
1839 * contains last error message (if any) encountered by XML loader.
1841 String errorMessage = null;
1844 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1845 * exceptions are raised during project XML parsing
1847 public boolean attemptversion1parse = true;
1850 * Load a jalview project archive from a jar file
1853 * - HTTP URL or filename
1855 public AlignFrame LoadJalviewAlign(final String file)
1858 jalview.gui.AlignFrame af = null;
1862 // create list to store references for any new Jmol viewers created
1863 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1864 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1865 // Workaround is to make sure caller implements the JarInputStreamProvider
1867 // so we can re-open the jar input stream for each entry.
1869 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1870 af = LoadJalviewAlign(jprovider);
1872 } catch (MalformedURLException e)
1874 errorMessage = "Invalid URL format for '" + file + "'";
1880 SwingUtilities.invokeAndWait(new Runnable()
1884 setLoadingFinishedForNewStructureViewers();
1887 } catch (Exception x)
1895 private jarInputStreamProvider createjarInputStreamProvider(
1896 final String file) throws MalformedURLException
1899 errorMessage = null;
1900 uniqueSetSuffix = null;
1902 viewportsAdded = null;
1903 frefedSequence = null;
1905 if (file.startsWith("http://"))
1907 url = new URL(file);
1909 final URL _url = url;
1910 return new jarInputStreamProvider()
1914 public JarInputStream getJarInputStream() throws IOException
1918 return new JarInputStream(_url.openStream());
1922 return new JarInputStream(new FileInputStream(file));
1927 public String getFilename()
1935 * Recover jalview session from a jalview project archive. Caller may
1936 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1937 * themselves. Any null fields will be initialised with default values,
1938 * non-null fields are left alone.
1943 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1945 errorMessage = null;
1946 if (uniqueSetSuffix == null)
1948 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1950 if (seqRefIds == null)
1952 seqRefIds = new Hashtable();
1954 if (viewportsAdded == null)
1956 viewportsAdded = new Hashtable();
1958 if (frefedSequence == null)
1960 frefedSequence = new Vector();
1963 jalview.gui.AlignFrame af = null, _af = null;
1964 Hashtable gatherToThisFrame = new Hashtable();
1965 final String file = jprovider.getFilename();
1968 JarInputStream jin = null;
1969 JarEntry jarentry = null;
1974 jin = jprovider.getJarInputStream();
1975 for (int i = 0; i < entryCount; i++)
1977 jarentry = jin.getNextJarEntry();
1980 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1982 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1983 JalviewModel object = new JalviewModel();
1985 Unmarshaller unmar = new Unmarshaller(object);
1986 unmar.setValidation(false);
1987 object = (JalviewModel) unmar.unmarshal(in);
1988 if (true) // !skipViewport(object))
1990 _af = LoadFromObject(object, file, true, jprovider);
1991 if (object.getJalviewModelSequence().getViewportCount() > 0)
1994 if (af.viewport.gatherViewsHere)
1996 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2002 else if (jarentry != null)
2004 // Some other file here.
2007 } while (jarentry != null);
2008 resolveFrefedSequences();
2009 } catch (java.io.FileNotFoundException ex)
2011 ex.printStackTrace();
2012 errorMessage = "Couldn't locate Jalview XML file : " + file;
2013 System.err.println("Exception whilst loading jalview XML file : "
2015 } catch (java.net.UnknownHostException 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 (Exception ex)
2023 System.err.println("Parsing as Jalview Version 2 file failed.");
2024 ex.printStackTrace(System.err);
2025 if (attemptversion1parse)
2027 // Is Version 1 Jar file?
2030 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2031 } catch (Exception ex2)
2033 System.err.println("Exception whilst loading as jalviewXMLV1:");
2034 ex2.printStackTrace();
2038 if (Desktop.instance != null)
2040 Desktop.instance.stopLoading();
2044 System.out.println("Successfully loaded archive file");
2047 ex.printStackTrace();
2049 System.err.println("Exception whilst loading jalview XML file : "
2051 } catch (OutOfMemoryError e)
2053 // Don't use the OOM Window here
2054 errorMessage = "Out of memory loading jalview XML file";
2055 System.err.println("Out of memory whilst loading jalview XML file");
2056 e.printStackTrace();
2059 if (Desktop.instance != null)
2061 Desktop.instance.stopLoading();
2064 Enumeration en = gatherToThisFrame.elements();
2065 while (en.hasMoreElements())
2067 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2069 if (errorMessage != null)
2077 * check errorMessage for a valid error message and raise an error box in the
2078 * GUI or write the current errorMessage to stderr and then clear the error
2081 protected void reportErrors()
2083 reportErrors(false);
2086 protected void reportErrors(final boolean saving)
2088 if (errorMessage != null)
2090 final String finalErrorMessage = errorMessage;
2093 javax.swing.SwingUtilities.invokeLater(new Runnable()
2098 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2099 finalErrorMessage, "Error "
2100 + (saving ? "saving" : "loading")
2101 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2107 System.err.println("Problem loading Jalview file: " + errorMessage);
2110 errorMessage = null;
2113 Hashtable<String, String> alreadyLoadedPDB;
2116 * when set, local views will be updated from view stored in JalviewXML
2117 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2118 * sync if this is set to true.
2120 private final boolean updateLocalViews = false;
2122 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2124 if (alreadyLoadedPDB == null)
2126 alreadyLoadedPDB = new Hashtable();
2129 if (alreadyLoadedPDB.containsKey(pdbId))
2131 return alreadyLoadedPDB.get(pdbId).toString();
2136 JarInputStream jin = jprovider.getJarInputStream();
2138 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2139 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2140 * FileInputStream(jprovider)); }
2143 JarEntry entry = null;
2146 entry = jin.getNextJarEntry();
2147 } while (entry != null && !entry.getName().equals(pdbId));
2150 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2151 File outFile = File.createTempFile("jalview_pdb", ".txt");
2152 outFile.deleteOnExit();
2153 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2156 while ((data = in.readLine()) != null)
2163 } catch (Exception foo)
2168 String t = outFile.getAbsolutePath();
2169 alreadyLoadedPDB.put(pdbId, t);
2174 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2176 } catch (Exception ex)
2178 ex.printStackTrace();
2184 private class JvAnnotRow
2186 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2193 * persisted version of annotation row from which to take vis properties
2195 public jalview.datamodel.AlignmentAnnotation template;
2198 * original position of the annotation row in the alignment
2204 * Load alignment frame from jalview XML DOM object
2209 * filename source string
2210 * @param loadTreesAndStructures
2211 * when false only create Viewport
2213 * data source provider
2214 * @return alignment frame created from view stored in DOM
2216 AlignFrame LoadFromObject(JalviewModel object, String file,
2217 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2219 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2220 Sequence[] vamsasSeq = vamsasSet.getSequence();
2222 JalviewModelSequence jms = object.getJalviewModelSequence();
2224 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2227 // ////////////////////////////////
2230 Vector hiddenSeqs = null;
2231 jalview.datamodel.Sequence jseq;
2233 ArrayList tmpseqs = new ArrayList();
2235 boolean multipleView = false;
2237 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2238 int vi = 0; // counter in vamsasSeq array
2239 for (int i = 0; i < JSEQ.length; i++)
2241 String seqId = JSEQ[i].getId();
2243 if (seqRefIds.get(seqId) != null)
2245 tmpseqs.add(seqRefIds.get(seqId));
2246 multipleView = true;
2250 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2251 vamsasSeq[vi].getSequence());
2252 jseq.setDescription(vamsasSeq[vi].getDescription());
2253 jseq.setStart(JSEQ[i].getStart());
2254 jseq.setEnd(JSEQ[i].getEnd());
2255 jseq.setVamsasId(uniqueSetSuffix + seqId);
2256 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2261 if (JSEQ[i].getHidden())
2263 if (hiddenSeqs == null)
2265 hiddenSeqs = new Vector();
2268 hiddenSeqs.addElement(seqRefIds.get(seqId));
2274 // Create the alignment object from the sequence set
2275 // ///////////////////////////////
2276 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2279 tmpseqs.toArray(orderedSeqs);
2281 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2284 // / Add the alignment properties
2285 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2287 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2288 al.setProperty(ssp.getKey(), ssp.getValue());
2292 // SequenceFeatures are added to the DatasetSequence,
2293 // so we must create or recover the dataset before loading features
2294 // ///////////////////////////////
2295 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2297 // older jalview projects do not have a dataset id.
2298 al.setDataset(null);
2302 // recover dataset - passing on flag indicating if this a 'viewless'
2303 // sequence set (a.k.a. a stored dataset for the project)
2304 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2305 .getViewportCount() == 0);
2307 // ///////////////////////////////
2309 Hashtable pdbloaded = new Hashtable();
2312 // load sequence features, database references and any associated PDB
2313 // structures for the alignment
2314 for (int i = 0; i < vamsasSeq.length; i++)
2316 if (JSEQ[i].getFeaturesCount() > 0)
2318 Features[] features = JSEQ[i].getFeatures();
2319 for (int f = 0; f < features.length; f++)
2321 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2322 features[f].getType(), features[f].getDescription(),
2323 features[f].getStatus(), features[f].getBegin(),
2324 features[f].getEnd(), features[f].getFeatureGroup());
2326 sf.setScore(features[f].getScore());
2327 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2329 OtherData keyValue = features[f].getOtherData(od);
2330 if (keyValue.getKey().startsWith("LINK"))
2332 sf.addLink(keyValue.getValue());
2336 sf.setValue(keyValue.getKey(), keyValue.getValue());
2341 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2344 if (vamsasSeq[i].getDBRefCount() > 0)
2346 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2348 if (JSEQ[i].getPdbidsCount() > 0)
2350 Pdbids[] ids = JSEQ[i].getPdbids();
2351 for (int p = 0; p < ids.length; p++)
2353 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2354 entry.setId(ids[p].getId());
2355 entry.setType(ids[p].getType());
2356 if (ids[p].getFile() != null)
2358 if (!pdbloaded.containsKey(ids[p].getFile()))
2360 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2364 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2367 StructureSelectionManager.getStructureSelectionManager(
2369 .registerPDBEntry(entry);
2370 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2374 } // end !multipleview
2376 // ///////////////////////////////
2377 // LOAD SEQUENCE MAPPINGS
2379 if (vamsasSet.getAlcodonFrameCount() > 0)
2381 // TODO Potentially this should only be done once for all views of an
2383 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2384 for (int i = 0; i < alc.length; i++)
2386 AlignedCodonFrame cf = new AlignedCodonFrame();
2387 if (alc[i].getAlcodMapCount() > 0)
2389 AlcodMap[] maps = alc[i].getAlcodMap();
2390 for (int m = 0; m < maps.length; m++)
2392 SequenceI dnaseq = (SequenceI) seqRefIds
2393 .get(maps[m].getDnasq());
2395 jalview.datamodel.Mapping mapping = null;
2396 // attach to dna sequence reference.
2397 if (maps[m].getMapping() != null)
2399 mapping = addMapping(maps[m].getMapping());
2403 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2408 frefedSequence.add(new Object[]
2409 { maps[m].getDnasq(), cf, mapping });
2413 al.addCodonFrame(cf);
2418 // ////////////////////////////////
2420 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2422 * store any annotations which forward reference a group's ID
2424 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2426 if (vamsasSet.getAnnotationCount() > 0)
2428 Annotation[] an = vamsasSet.getAnnotation();
2430 for (int i = 0; i < an.length; i++)
2433 * test if annotation is automatically calculated for this view only
2435 boolean autoForView = false;
2436 if (an[i].getLabel().equals("Quality")
2437 || an[i].getLabel().equals("Conservation")
2438 || an[i].getLabel().equals("Consensus"))
2440 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2442 if (!an[i].hasAutoCalculated())
2444 an[i].setAutoCalculated(true);
2448 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2450 // remove ID - we don't recover annotation from other views for
2451 // view-specific annotation
2455 // set visiblity for other annotation in this view
2456 if (an[i].getId() != null
2457 && annotationIds.containsKey(an[i].getId()))
2459 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2460 .get(an[i].getId());
2461 // in principle Visible should always be true for annotation displayed
2462 // in multiple views
2463 if (an[i].hasVisible())
2465 jda.visible = an[i].getVisible();
2468 al.addAnnotation(jda);
2472 // Construct new annotation from model.
2473 AnnotationElement[] ae = an[i].getAnnotationElement();
2474 jalview.datamodel.Annotation[] anot = null;
2475 java.awt.Color firstColour = null;
2477 if (!an[i].getScoreOnly())
2479 anot = new jalview.datamodel.Annotation[al.getWidth()];
2480 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2482 anpos = ae[aa].getPosition();
2484 if (anpos >= anot.length)
2489 anot[anpos] = new jalview.datamodel.Annotation(
2491 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2492 (ae[aa].getSecondaryStructure() == null || ae[aa]
2493 .getSecondaryStructure().length() == 0) ? ' '
2494 : ae[aa].getSecondaryStructure().charAt(0),
2498 // JBPNote: Consider verifying dataflow for IO of secondary
2499 // structure annotation read from Stockholm files
2500 // this was added to try to ensure that
2501 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2503 // anot[ae[aa].getPosition()].displayCharacter = "";
2505 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2506 if (firstColour == null)
2508 firstColour = anot[anpos].colour;
2512 jalview.datamodel.AlignmentAnnotation jaa = null;
2514 if (an[i].getGraph())
2516 float llim = 0, hlim = 0;
2517 // if (autoForView || an[i].isAutoCalculated()) {
2520 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2521 an[i].getDescription(), anot, llim, hlim,
2522 an[i].getGraphType());
2524 jaa.graphGroup = an[i].getGraphGroup();
2525 jaa._linecolour = firstColour;
2526 if (an[i].getThresholdLine() != null)
2528 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2529 .getThresholdLine().getValue(), an[i]
2530 .getThresholdLine().getLabel(), new java.awt.Color(
2531 an[i].getThresholdLine().getColour())));
2534 if (autoForView || an[i].isAutoCalculated())
2536 // Hardwire the symbol display line to ensure that labels for
2537 // histograms are displayed
2543 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2544 an[i].getDescription(), anot);
2545 jaa._linecolour = firstColour;
2547 // register new annotation
2548 if (an[i].getId() != null)
2550 annotationIds.put(an[i].getId(), jaa);
2551 jaa.annotationId = an[i].getId();
2553 // recover sequence association
2554 if (an[i].getSequenceRef() != null)
2556 if (al.findName(an[i].getSequenceRef()) != null)
2558 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2560 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2563 // and make a note of any group association
2564 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2566 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2567 .get(an[i].getGroupRef());
2570 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2571 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2576 if (an[i].hasScore())
2578 jaa.setScore(an[i].getScore());
2580 if (an[i].hasVisible())
2582 jaa.visible = an[i].getVisible();
2585 if (an[i].hasCentreColLabels())
2587 jaa.centreColLabels = an[i].getCentreColLabels();
2590 if (an[i].hasScaleColLabels())
2592 jaa.scaleColLabel = an[i].getScaleColLabels();
2594 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2596 // newer files have an 'autoCalculated' flag and store calculation
2597 // state in viewport properties
2598 jaa.autoCalculated = true; // means annotation will be marked for
2599 // update at end of load.
2601 if (an[i].hasGraphHeight())
2603 jaa.graphHeight = an[i].getGraphHeight();
2605 if (an[i].hasBelowAlignment())
2607 jaa.belowAlignment = an[i].isBelowAlignment();
2609 jaa.setCalcId(an[i].getCalcId());
2610 if (an[i].getPropertyCount() > 0)
2612 for (jalview.schemabinding.version2.Property prop : an[i]
2615 jaa.setProperty(prop.getName(), prop.getValue());
2618 if (jaa.autoCalculated)
2620 autoAlan.add(new JvAnnotRow(i, jaa));
2623 // if (!autoForView)
2625 // add autocalculated group annotation and any user created annotation
2627 al.addAnnotation(jaa);
2631 // ///////////////////////
2633 // Create alignment markup and styles for this view
2634 if (jms.getJGroupCount() > 0)
2636 JGroup[] groups = jms.getJGroup();
2637 boolean addAnnotSchemeGroup = false;
2638 for (int i = 0; i < groups.length; i++)
2640 ColourSchemeI cs = null;
2642 if (groups[i].getColour() != null)
2644 if (groups[i].getColour().startsWith("ucs"))
2646 cs = GetUserColourScheme(jms, groups[i].getColour());
2648 else if (groups[i].getColour().equals("AnnotationColourGradient")
2649 && groups[i].getAnnotationColours() != null)
2651 addAnnotSchemeGroup = true;
2656 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2661 cs.setThreshold(groups[i].getPidThreshold(), true);
2665 Vector seqs = new Vector();
2667 for (int s = 0; s < groups[i].getSeqCount(); s++)
2669 String seqId = groups[i].getSeq(s) + "";
2670 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2675 seqs.addElement(ts);
2679 if (seqs.size() < 1)
2684 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2685 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2686 groups[i].getDisplayText(), groups[i].getColourText(),
2687 groups[i].getStart(), groups[i].getEnd());
2689 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2691 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2692 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2693 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2694 .isShowUnconserved() : false);
2695 sg.thresholdTextColour = groups[i].getTextColThreshold();
2696 if (groups[i].hasShowConsensusHistogram())
2698 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2701 if (groups[i].hasShowSequenceLogo())
2703 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2705 if (groups[i].hasNormaliseSequenceLogo())
2707 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2709 if (groups[i].hasIgnoreGapsinConsensus())
2711 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2713 if (groups[i].getConsThreshold() != 0)
2715 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2716 "All", ResidueProperties.propHash, 3,
2717 sg.getSequences(null), 0, sg.getWidth() - 1);
2719 c.verdict(false, 25);
2720 sg.cs.setConservation(c);
2723 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2725 // re-instate unique group/annotation row reference
2726 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2727 .get(groups[i].getId());
2730 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2733 if (jaa.autoCalculated)
2735 // match up and try to set group autocalc alignment row for this
2737 if (jaa.label.startsWith("Consensus for "))
2739 sg.setConsensus(jaa);
2741 // match up and try to set group autocalc alignment row for this
2743 if (jaa.label.startsWith("Conservation for "))
2745 sg.setConservationRow(jaa);
2752 if (addAnnotSchemeGroup)
2754 // reconstruct the annotation colourscheme
2755 sg.cs = constructAnnotationColour(
2756 groups[i].getAnnotationColours(), null, al, jms, false);
2762 // only dataset in this model, so just return.
2765 // ///////////////////////////////
2768 // If we just load in the same jar file again, the sequenceSetId
2769 // will be the same, and we end up with multiple references
2770 // to the same sequenceSet. We must modify this id on load
2771 // so that each load of the file gives a unique id
2772 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2773 String viewId = (view.getId() == null ? null : view.getId()
2775 AlignFrame af = null;
2776 AlignViewport av = null;
2777 // now check to see if we really need to create a new viewport.
2778 if (multipleView && viewportsAdded.size() == 0)
2780 // We recovered an alignment for which a viewport already exists.
2781 // TODO: fix up any settings necessary for overlaying stored state onto
2782 // state recovered from another document. (may not be necessary).
2783 // we may need a binding from a viewport in memory to one recovered from
2785 // and then recover its containing af to allow the settings to be applied.
2786 // TODO: fix for vamsas demo
2788 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2790 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2791 if (seqsetobj != null)
2793 if (seqsetobj instanceof String)
2795 uniqueSeqSetId = (String) seqsetobj;
2797 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2803 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2809 * indicate that annotation colours are applied across all groups (pre
2810 * Jalview 2.8.1 behaviour)
2812 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2813 object.getVersion());
2815 AlignmentPanel ap = null;
2816 boolean isnewview = true;
2819 // Check to see if this alignment already has a view id == viewId
2820 jalview.gui.AlignmentPanel views[] = Desktop
2821 .getAlignmentPanels(uniqueSeqSetId);
2822 if (views != null && views.length > 0)
2824 for (int v = 0; v < views.length; v++)
2826 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2828 // recover the existing alignpanel, alignframe, viewport
2829 af = views[v].alignFrame;
2832 // TODO: could even skip resetting view settings if we don't want to
2833 // change the local settings from other jalview processes
2842 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2843 uniqueSeqSetId, viewId, autoAlan);
2848 // /////////////////////////////////////
2849 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2853 for (int t = 0; t < jms.getTreeCount(); t++)
2856 Tree tree = jms.getTree(t);
2858 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2861 tp = af.ShowNewickTree(
2862 new jalview.io.NewickFile(tree.getNewick()),
2863 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2864 tree.getXpos(), tree.getYpos());
2865 if (tree.getId() != null)
2867 // perhaps bind the tree id to something ?
2872 // update local tree attributes ?
2873 // TODO: should check if tp has been manipulated by user - if so its
2874 // settings shouldn't be modified
2875 tp.setTitle(tree.getTitle());
2876 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2877 .getWidth(), tree.getHeight()));
2878 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2881 tp.treeCanvas.av = av; // af.viewport;
2882 tp.treeCanvas.ap = ap; // af.alignPanel;
2887 warn("There was a problem recovering stored Newick tree: \n"
2888 + tree.getNewick());
2892 tp.fitToWindow.setState(tree.getFitToWindow());
2893 tp.fitToWindow_actionPerformed(null);
2895 if (tree.getFontName() != null)
2897 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2898 .getFontStyle(), tree.getFontSize()));
2902 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2903 .getFontStyle(), tree.getFontSize()));
2906 tp.showPlaceholders(tree.getMarkUnlinked());
2907 tp.showBootstrap(tree.getShowBootstrap());
2908 tp.showDistances(tree.getShowDistances());
2910 tp.treeCanvas.threshold = tree.getThreshold();
2912 if (tree.getCurrentTree())
2914 af.viewport.setCurrentTree(tp.getTree());
2918 } catch (Exception ex)
2920 ex.printStackTrace();
2924 // //LOAD STRUCTURES
2925 if (loadTreesAndStructures)
2927 // run through all PDB ids on the alignment, and collect mappings between
2928 // jmol view ids and all sequences referring to it
2929 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2931 for (int i = 0; i < JSEQ.length; i++)
2933 if (JSEQ[i].getPdbidsCount() > 0)
2935 Pdbids[] ids = JSEQ[i].getPdbids();
2936 for (int p = 0; p < ids.length; p++)
2938 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2940 // check to see if we haven't already created this structure view
2941 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2942 : ids[p].getStructureState(s).getViewId()
2944 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2945 // Originally : ids[p].getFile()
2946 // : TODO: verify external PDB file recovery still works in normal
2947 // jalview project load
2948 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2949 jpdb.setId(ids[p].getId());
2951 int x = ids[p].getStructureState(s).getXpos();
2952 int y = ids[p].getStructureState(s).getYpos();
2953 int width = ids[p].getStructureState(s).getWidth();
2954 int height = ids[p].getStructureState(s).getHeight();
2956 // Probably don't need to do this anymore...
2957 // Desktop.desktop.getComponentAt(x, y);
2958 // TODO: NOW: check that this recovers the PDB file correctly.
2959 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2960 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2961 .get(JSEQ[i].getId() + "");
2962 if (sviewid == null)
2964 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2967 if (!jmolViewIds.containsKey(sviewid))
2969 jmolViewIds.put(sviewid, new Object[]
2971 { x, y, width, height }, "",
2972 new Hashtable<String, Object[]>(), new boolean[]
2973 { false, false, true } });
2974 // Legacy pre-2.7 conversion JAL-823 :
2975 // do not assume any view has to be linked for colour by
2979 // assemble String[] { pdb files }, String[] { id for each
2980 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2981 // seqs_file 2}, boolean[] {
2982 // linkAlignPanel,superposeWithAlignpanel}} from hash
2983 Object[] jmoldat = jmolViewIds.get(sviewid);
2984 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2985 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2986 s).getAlignwithAlignPanel() : false;
2987 // never colour by linked panel if not specified
2988 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2989 .hasColourwithAlignPanel() ? ids[p]
2990 .getStructureState(s).getColourwithAlignPanel()
2992 // default for pre-2.7 projects is that Jmol colouring is enabled
2993 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2994 .hasColourByJmol() ? ids[p].getStructureState(s)
2995 .getColourByJmol() : true;
2997 if (((String) jmoldat[1]).length() < ids[p]
2998 .getStructureState(s).getContent().length())
3001 jmoldat[1] = ids[p].getStructureState(s).getContent();
3004 if (ids[p].getFile() != null)
3006 File mapkey = new File(ids[p].getFile());
3007 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3009 if (seqstrmaps == null)
3011 ((Hashtable) jmoldat[2]).put(mapkey,
3012 seqstrmaps = new Object[]
3013 { pdbFile, ids[p].getId(), new Vector(),
3016 if (!((Vector) seqstrmaps[2]).contains(seq))
3018 ((Vector) seqstrmaps[2]).addElement(seq);
3019 // ((Vector)seqstrmaps[3]).addElement(n) :
3020 // in principle, chains
3021 // should be stored here : do we need to
3022 // TODO: store and recover seq/pdb_id :
3028 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");
3037 // Instantiate the associated Jmol views
3038 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3040 String sviewid = entry.getKey();
3041 Object[] svattrib = entry.getValue();
3042 int[] geom = (int[]) svattrib[0];
3043 String state = (String) svattrib[1];
3044 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3045 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3046 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3047 // collate the pdbfile -> sequence mappings from this view
3048 Vector<String> pdbfilenames = new Vector<String>();
3049 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3050 Vector<String> pdbids = new Vector<String>();
3052 // Search to see if we've already created this Jmol view
3053 AppJmol comp = null;
3054 JInternalFrame[] frames = null;
3059 frames = Desktop.desktop.getAllFrames();
3060 } catch (ArrayIndexOutOfBoundsException e)
3062 // occasional No such child exceptions are thrown here...
3067 } catch (Exception f)
3072 } while (frames == null);
3073 // search for any Jmol windows already open from other
3074 // alignment views that exactly match the stored structure state
3075 for (int f = 0; comp == null && f < frames.length; f++)
3077 if (frames[f] instanceof AppJmol)
3080 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3082 // post jalview 2.4 schema includes structure view id
3083 comp = (AppJmol) frames[f];
3085 else if (frames[f].getX() == x && frames[f].getY() == y
3086 && frames[f].getHeight() == height
3087 && frames[f].getWidth() == width)
3089 comp = (AppJmol) frames[f];
3096 // create a new Jmol window.
3097 // First parse the Jmol state to translate filenames loaded into the
3098 // view, and record the order in which files are shown in the Jmol
3099 // view, so we can add the sequence mappings in same order.
3100 StringBuffer newFileLoc = null;
3101 int cp = 0, ncp, ecp;
3102 while ((ncp = state.indexOf("load ", cp)) > -1)
3104 if (newFileLoc == null)
3106 newFileLoc = new StringBuffer();
3110 // look for next filename in load statement
3111 newFileLoc.append(state.substring(cp,
3112 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3113 String oldfilenam = state.substring(ncp,
3114 ecp = state.indexOf("\"", ncp));
3115 // recover the new mapping data for this old filename
3116 // have to normalize filename - since Jmol and jalview do
3118 // translation differently.
3119 Object[] filedat = oldFiles.get(new File(oldfilenam));
3120 newFileLoc.append(Platform
3121 .escapeString((String) filedat[0]));
3122 pdbfilenames.addElement((String) filedat[0]);
3123 pdbids.addElement((String) filedat[1]);
3124 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3125 .toArray(new SequenceI[0]));
3126 newFileLoc.append("\"");
3127 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3128 // look for next file statement.
3129 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3133 // just append rest of state
3134 newFileLoc.append(state.substring(cp));
3139 .print("Ignoring incomplete Jmol state for PDB ids: ");
3140 newFileLoc = new StringBuffer(state);
3141 newFileLoc.append("; load append ");
3142 for (File id : oldFiles.keySet())
3144 // add this and any other pdb files that should be present in
3146 Object[] filedat = oldFiles.get(id);
3148 newFileLoc.append(((String) filedat[0]));
3149 pdbfilenames.addElement((String) filedat[0]);
3150 pdbids.addElement((String) filedat[1]);
3151 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3152 .toArray(new SequenceI[0]));
3153 newFileLoc.append(" \"");
3154 newFileLoc.append((String) filedat[0]);
3155 newFileLoc.append("\"");
3158 newFileLoc.append(";");
3161 if (newFileLoc != null)
3163 int histbug = newFileLoc.indexOf("history = ");
3165 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3167 String val = (diff == -1) ? null : newFileLoc.substring(
3169 if (val != null && val.length() >= 4)
3171 if (val.contains("e"))
3173 if (val.trim().equals("true"))
3181 newFileLoc.replace(histbug, diff, val);
3184 // TODO: assemble String[] { pdb files }, String[] { id for each
3185 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3186 // seqs_file 2}} from hash
3187 final String[] pdbf = pdbfilenames
3188 .toArray(new String[pdbfilenames.size()]), id = pdbids
3189 .toArray(new String[pdbids.size()]);
3190 final SequenceI[][] sq = seqmaps
3191 .toArray(new SequenceI[seqmaps.size()][]);
3192 final String fileloc = newFileLoc.toString(), vid = sviewid;
3193 final AlignFrame alf = af;
3194 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3198 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3203 JalviewStructureDisplayI sview = null;
3206 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3207 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3208 useinJmolsuperpos, usetoColourbyseq,
3209 jmolColouring, fileloc, rect, vid);
3210 addNewStructureViewer(sview);
3211 } catch (OutOfMemoryError ex)
3213 new OOMWarning("restoring structure view for PDB id "
3214 + id, (OutOfMemoryError) ex.getCause());
3215 if (sview != null && sview.isVisible())
3217 sview.closeViewer();
3218 sview.setVisible(false);
3224 } catch (InvocationTargetException ex)
3226 warn("Unexpected error when opening Jmol view.", ex);
3228 } catch (InterruptedException e)
3230 // e.printStackTrace();
3236 // if (comp != null)
3238 // NOTE: if the jalview project is part of a shared session then
3239 // view synchronization should/could be done here.
3241 // add mapping for sequences in this view to an already open Jmol
3243 for (File id : oldFiles.keySet())
3245 // add this and any other pdb files that should be present in the
3247 Object[] filedat = oldFiles.get(id);
3248 String pdbFile = (String) filedat[0];
3249 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3250 .toArray(new SequenceI[0]);
3251 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3252 jalview.io.AppletFormatAdapter.FILE);
3253 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3255 // and add the AlignmentPanel's reference to the Jmol view
3256 comp.addAlignmentPanel(ap);
3257 if (useinJmolsuperpos)
3259 comp.useAlignmentPanelForSuperposition(ap);
3263 comp.excludeAlignmentPanelForSuperposition(ap);
3265 if (usetoColourbyseq)
3267 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3271 comp.excludeAlignmentPanelForColourbyseq(ap);
3277 // and finally return.
3284 * - minimum version we are comparing against
3286 * - version of data being processsed.
3287 * @return true if version is development/null or evaluates to the same or
3288 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3290 private boolean isVersionStringLaterThan(String supported, String version)
3292 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3293 || version.equalsIgnoreCase("Test")
3294 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3296 System.err.println("Assuming project file with "
3297 + (version == null ? "null" : version)
3298 + " is compatible with Jalview version " + supported);
3303 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3305 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3307 // convert b to decimal to catch bugfix releases within a series
3308 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3309 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3312 if (Float.valueOf(curT) > Float.valueOf(fileT))
3314 // current version is newer than the version that wrote the file
3317 } catch (NumberFormatException nfe)
3320 .println("** WARNING: Version comparison failed for tokens ("
3324 + ")\n** Current: '"
3325 + supported + "' and Version: '" + version + "'");
3328 if (currentV.hasMoreElements())
3330 // fileV has no minor version but identical series to current
3337 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3339 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3341 if (newStructureViewers != null)
3343 sview.getBinding().setFinishedLoadingFromArchive(false);
3344 newStructureViewers.add(sview);
3348 protected void setLoadingFinishedForNewStructureViewers()
3350 if (newStructureViewers != null)
3352 for (JalviewStructureDisplayI sview : newStructureViewers)
3354 sview.getBinding().setFinishedLoadingFromArchive(true);
3356 newStructureViewers.clear();
3357 newStructureViewers = null;
3361 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3362 Alignment al, JalviewModelSequence jms, Viewport view,
3363 String uniqueSeqSetId, String viewId,
3364 ArrayList<JvAnnotRow> autoAlan)
3366 AlignFrame af = null;
3367 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3368 uniqueSeqSetId, viewId);
3370 af.setFileName(file, "Jalview");
3372 for (int i = 0; i < JSEQ.length; i++)
3374 af.viewport.setSequenceColour(af.viewport.getAlignment()
3375 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3378 af.viewport.gatherViewsHere = view.getGatheredViews();
3380 if (view.getSequenceSetId() != null)
3382 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3383 .get(uniqueSeqSetId);
3385 af.viewport.setSequenceSetId(uniqueSeqSetId);
3388 // propagate shared settings to this new view
3389 af.viewport.setHistoryList(av.getHistoryList());
3390 af.viewport.setRedoList(av.getRedoList());
3394 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3396 // TODO: check if this method can be called repeatedly without
3397 // side-effects if alignpanel already registered.
3398 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3400 // apply Hidden regions to view.
3401 if (hiddenSeqs != null)
3403 for (int s = 0; s < JSEQ.length; s++)
3405 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3407 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3410 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3412 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3415 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3418 for (int s = 0; s < hiddenSeqs.size(); s++)
3420 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3423 af.viewport.hideSequence(hseqs);
3426 // recover view properties and display parameters
3427 if (view.getViewName() != null)
3429 af.viewport.viewName = view.getViewName();
3430 af.setInitialTabVisible();
3432 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3435 af.viewport.setShowAnnotation(view.getShowAnnotation());
3436 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3438 af.viewport.setColourText(view.getShowColourText());
3440 af.viewport.setConservationSelected(view.getConservationSelected());
3441 af.viewport.setShowJVSuffix(view.getShowFullId());
3442 af.viewport.rightAlignIds = view.getRightAlignIds();
3443 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3444 .getFontStyle(), view.getFontSize()));
3445 af.alignPanel.fontChanged();
3446 af.viewport.setRenderGaps(view.getRenderGaps());
3447 af.viewport.setWrapAlignment(view.getWrapAlignment());
3448 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3449 af.viewport.setShowAnnotation(view.getShowAnnotation());
3450 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3452 af.viewport.setShowBoxes(view.getShowBoxes());
3454 af.viewport.setShowText(view.getShowText());
3456 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3457 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3458 af.viewport.thresholdTextColour = view.getTextColThreshold();
3459 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3460 .isShowUnconserved() : false);
3461 af.viewport.setStartRes(view.getStartRes());
3462 af.viewport.setStartSeq(view.getStartSeq());
3464 ColourSchemeI cs = null;
3465 // apply colourschemes
3466 if (view.getBgColour() != null)
3468 if (view.getBgColour().startsWith("ucs"))
3470 cs = GetUserColourScheme(jms, view.getBgColour());
3472 else if (view.getBgColour().startsWith("Annotation"))
3474 AnnotationColours viewAnnColour = view.getAnnotationColours();
3475 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3482 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3487 cs.setThreshold(view.getPidThreshold(), true);
3488 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3492 af.viewport.setGlobalColourScheme(cs);
3493 af.viewport.setColourAppliesToAllGroups(false);
3495 if (view.getConservationSelected() && cs != null)
3497 cs.setConservationInc(view.getConsThreshold());
3500 af.changeColour(cs);
3502 af.viewport.setColourAppliesToAllGroups(true);
3504 if (view.getShowSequenceFeatures())
3506 af.viewport.showSequenceFeatures = true;
3508 if (view.hasCentreColumnLabels())
3510 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3512 if (view.hasIgnoreGapsinConsensus())
3514 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3517 if (view.hasFollowHighlight())
3519 af.viewport.followHighlight = view.getFollowHighlight();
3521 if (view.hasFollowSelection())
3523 af.viewport.followSelection = view.getFollowSelection();
3525 if (view.hasShowConsensusHistogram())
3527 af.viewport.setShowConsensusHistogram(view
3528 .getShowConsensusHistogram());
3532 af.viewport.setShowConsensusHistogram(true);
3534 if (view.hasShowSequenceLogo())
3536 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3540 af.viewport.setShowSequenceLogo(false);
3542 if (view.hasNormaliseSequenceLogo())
3544 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3546 if (view.hasShowDbRefTooltip())
3548 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3550 if (view.hasShowNPfeatureTooltip())
3552 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3554 if (view.hasShowGroupConsensus())
3556 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3560 af.viewport.setShowGroupConsensus(false);
3562 if (view.hasShowGroupConservation())
3564 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3568 af.viewport.setShowGroupConservation(false);
3571 // recover featre settings
3572 if (jms.getFeatureSettings() != null)
3574 af.viewport.featuresDisplayed = new Hashtable();
3575 String[] renderOrder = new String[jms.getFeatureSettings()
3576 .getSettingCount()];
3577 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3579 Setting setting = jms.getFeatureSettings().getSetting(fs);
3580 if (setting.hasMincolour())
3582 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3583 new java.awt.Color(setting.getMincolour()),
3584 new java.awt.Color(setting.getColour()),
3585 setting.getMin(), setting.getMax()) : new GraduatedColor(
3586 new java.awt.Color(setting.getMincolour()),
3587 new java.awt.Color(setting.getColour()), 0, 1);
3588 if (setting.hasThreshold())
3590 gc.setThresh(setting.getThreshold());
3591 gc.setThreshType(setting.getThreshstate());
3593 gc.setAutoScaled(true); // default
3594 if (setting.hasAutoScale())
3596 gc.setAutoScaled(setting.getAutoScale());
3598 if (setting.hasColourByLabel())
3600 gc.setColourByLabel(setting.getColourByLabel());
3602 // and put in the feature colour table.
3603 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3604 setting.getType(), gc);
3608 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3610 new java.awt.Color(setting.getColour()));
3612 renderOrder[fs] = setting.getType();
3613 if (setting.hasOrder())
3615 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3616 setting.getType(), setting.getOrder());
3620 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3622 fs / jms.getFeatureSettings().getSettingCount());
3624 if (setting.getDisplay())
3626 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3627 setting.getColour()));
3630 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3632 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3633 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3635 Group grp = jms.getFeatureSettings().getGroup(gs);
3636 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3640 if (view.getHiddenColumnsCount() > 0)
3642 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3644 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3645 .getHiddenColumns(c).getEnd() // +1
3649 if (view.getCalcIdParam() != null)
3651 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3653 if (calcIdParam != null)
3655 if (recoverCalcIdParam(calcIdParam, af.viewport))
3660 warn("Couldn't recover parameters for "
3661 + calcIdParam.getCalcId());
3666 af.setMenusFromViewport(af.viewport);
3667 // TODO: we don't need to do this if the viewport is aready visible.
3668 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3670 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3671 reorderAutoannotation(af, al, autoAlan);
3672 af.alignPanel.alignmentChanged();
3676 private ColourSchemeI constructAnnotationColour(
3677 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3678 JalviewModelSequence jms, boolean checkGroupAnnColour)
3680 boolean propagateAnnColour = false;
3681 ColourSchemeI cs = null;
3682 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3683 if (checkGroupAnnColour && al.getGroups() != null
3684 && al.getGroups().size() > 0)
3686 // pre 2.8.1 behaviour
3687 // check to see if we should transfer annotation colours
3688 propagateAnnColour = true;
3689 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3691 if (sg.cs instanceof AnnotationColourGradient)
3693 propagateAnnColour = false;
3697 // int find annotation
3698 if (annAlignment.getAlignmentAnnotation() != null)
3700 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3702 if (annAlignment.getAlignmentAnnotation()[i].label
3703 .equals(viewAnnColour.getAnnotation()))
3705 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3707 annAlignment.getAlignmentAnnotation()[i]
3708 .setThreshold(new jalview.datamodel.GraphLine(
3709 viewAnnColour.getThreshold(), "Threshold",
3710 java.awt.Color.black)
3715 if (viewAnnColour.getColourScheme().equals("None"))
3717 cs = new AnnotationColourGradient(
3718 annAlignment.getAlignmentAnnotation()[i],
3719 new java.awt.Color(viewAnnColour.getMinColour()),
3720 new java.awt.Color(viewAnnColour.getMaxColour()),
3721 viewAnnColour.getAboveThreshold());
3723 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3725 cs = new AnnotationColourGradient(
3726 annAlignment.getAlignmentAnnotation()[i],
3727 GetUserColourScheme(jms,
3728 viewAnnColour.getColourScheme()),
3729 viewAnnColour.getAboveThreshold());
3733 cs = new AnnotationColourGradient(
3734 annAlignment.getAlignmentAnnotation()[i],
3735 ColourSchemeProperty.getColour(al,
3736 viewAnnColour.getColourScheme()),
3737 viewAnnColour.getAboveThreshold());
3739 if (viewAnnColour.hasPerSequence())
3741 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3744 if (viewAnnColour.hasPredefinedColours())
3746 ((AnnotationColourGradient) cs)
3747 .setPredefinedColours(viewAnnColour
3748 .isPredefinedColours());
3750 if (propagateAnnColour && al.getGroups() != null)
3752 // Also use these settings for all the groups
3753 for (int g = 0; g < al.getGroups().size(); g++)
3755 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3763 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3764 * new AnnotationColourGradient(
3765 * annAlignment.getAlignmentAnnotation()[i], new
3766 * java.awt.Color(viewAnnColour. getMinColour()), new
3767 * java.awt.Color(viewAnnColour. getMaxColour()),
3768 * viewAnnColour.getAboveThreshold()); } else
3771 sg.cs = new AnnotationColourGradient(
3772 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3773 viewAnnColour.getAboveThreshold());
3774 if (cs instanceof AnnotationColourGradient)
3776 if (viewAnnColour.hasPerSequence())
3778 ((AnnotationColourGradient) cs)
3779 .setSeqAssociated(viewAnnColour.isPerSequence());
3781 if (viewAnnColour.hasPredefinedColours())
3783 ((AnnotationColourGradient) cs)
3784 .setPredefinedColours(viewAnnColour
3785 .isPredefinedColours());
3801 private void reorderAutoannotation(AlignFrame af, Alignment al,
3802 ArrayList<JvAnnotRow> autoAlan)
3804 // copy over visualization settings for autocalculated annotation in the
3806 if (al.getAlignmentAnnotation() != null)
3809 * Kludge for magic autoannotation names (see JAL-811)
3811 String[] magicNames = new String[]
3812 { "Consensus", "Quality", "Conservation" };
3813 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3814 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3815 for (String nm : magicNames)
3817 visan.put(nm, nullAnnot);
3819 for (JvAnnotRow auan : autoAlan)
3821 visan.put(auan.template.label
3822 + (auan.template.getCalcId() == null ? "" : "\t"
3823 + auan.template.getCalcId()), auan);
3825 int hSize = al.getAlignmentAnnotation().length;
3826 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3827 // work through any autoCalculated annotation already on the view
3828 // removing it if it should be placed in a different location on the
3829 // annotation panel.
3830 List<String> remains = new ArrayList(visan.keySet());
3831 for (int h = 0; h < hSize; h++)
3833 jalview.datamodel.AlignmentAnnotation jalan = al
3834 .getAlignmentAnnotation()[h];
3835 if (jalan.autoCalculated)
3838 JvAnnotRow valan = visan.get(k = jalan.label);
3839 if (jalan.getCalcId() != null)
3841 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3846 // delete the auto calculated row from the alignment
3847 al.deleteAnnotation(jalan, false);
3851 if (valan != nullAnnot)
3853 if (jalan != valan.template)
3855 // newly created autoannotation row instance
3856 // so keep a reference to the visible annotation row
3857 // and copy over all relevant attributes
3858 if (valan.template.graphHeight >= 0)
3861 jalan.graphHeight = valan.template.graphHeight;
3863 jalan.visible = valan.template.visible;
3865 reorder.add(new JvAnnotRow(valan.order, jalan));
3870 // Add any (possibly stale) autocalculated rows that were not appended to
3871 // the view during construction
3872 for (String other : remains)
3874 JvAnnotRow othera = visan.get(other);
3875 if (othera != nullAnnot && othera.template.getCalcId() != null
3876 && othera.template.getCalcId().length() > 0)
3878 reorder.add(othera);
3881 // now put the automatic annotation in its correct place
3882 int s = 0, srt[] = new int[reorder.size()];
3883 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3884 for (JvAnnotRow jvar : reorder)
3887 srt[s++] = jvar.order;
3890 jalview.util.QuickSort.sort(srt, rws);
3891 // and re-insert the annotation at its correct position
3892 for (JvAnnotRow jvar : rws)
3894 al.addAnnotation(jvar.template, jvar.order);
3896 af.alignPanel.adjustAnnotationHeight();
3900 Hashtable skipList = null;
3903 * TODO remove this method
3906 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3907 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3908 * throw new Error("Implementation Error. No skipList defined for this
3909 * Jalview2XML instance."); } return (AlignFrame)
3910 * skipList.get(view.getSequenceSetId()); }
3914 * Check if the Jalview view contained in object should be skipped or not.
3917 * @return true if view's sequenceSetId is a key in skipList
3919 private boolean skipViewport(JalviewModel object)
3921 if (skipList == null)
3926 if (skipList.containsKey(id = object.getJalviewModelSequence()
3927 .getViewport()[0].getSequenceSetId()))
3929 if (Cache.log != null && Cache.log.isDebugEnabled())
3931 Cache.log.debug("Skipping seuqence set id " + id);
3938 public void AddToSkipList(AlignFrame af)
3940 if (skipList == null)
3942 skipList = new Hashtable();
3944 skipList.put(af.getViewport().getSequenceSetId(), af);
3947 public void clearSkipList()
3949 if (skipList != null)
3956 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
3957 boolean ignoreUnrefed)
3959 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3960 Vector dseqs = null;
3963 // create a list of new dataset sequences
3964 dseqs = new Vector();
3966 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3968 Sequence vamsasSeq = vamsasSet.getSequence(i);
3969 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
3971 // create a new dataset
3974 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3975 dseqs.copyInto(dsseqs);
3976 ds = new jalview.datamodel.Alignment(dsseqs);
3977 debug("Created new dataset " + vamsasSet.getDatasetId()
3978 + " for alignment " + System.identityHashCode(al));
3979 addDatasetRef(vamsasSet.getDatasetId(), ds);
3981 // set the dataset for the newly imported alignment.
3982 if (al.getDataset() == null && !ignoreUnrefed)
3991 * sequence definition to create/merge dataset sequence for
3995 * vector to add new dataset sequence to
3997 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3998 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4000 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4002 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4003 .get(vamsasSeq.getId());
4004 jalview.datamodel.SequenceI dsq = null;
4005 if (sq != null && sq.getDatasetSequence() != null)
4007 dsq = sq.getDatasetSequence();
4009 if (sq == null && ignoreUnrefed)
4013 String sqid = vamsasSeq.getDsseqid();
4016 // need to create or add a new dataset sequence reference to this sequence
4019 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4024 // make a new dataset sequence
4025 dsq = sq.createDatasetSequence();
4028 // make up a new dataset reference for this sequence
4029 sqid = seqHash(dsq);
4031 dsq.setVamsasId(uniqueSetSuffix + sqid);
4032 seqRefIds.put(sqid, dsq);
4037 dseqs.addElement(dsq);
4042 ds.addSequence(dsq);
4048 { // make this dataset sequence sq's dataset sequence
4049 sq.setDatasetSequence(dsq);
4050 // and update the current dataset alignment
4055 if (!dseqs.contains(dsq))
4062 if (ds.findIndex(dsq) < 0)
4064 ds.addSequence(dsq);
4071 // TODO: refactor this as a merge dataset sequence function
4072 // now check that sq (the dataset sequence) sequence really is the union of
4073 // all references to it
4074 // boolean pre = sq.getStart() < dsq.getStart();
4075 // boolean post = sq.getEnd() > dsq.getEnd();
4079 StringBuffer sb = new StringBuffer();
4080 String newres = jalview.analysis.AlignSeq.extractGaps(
4081 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4082 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4083 && newres.length() > dsq.getLength())
4085 // Update with the longer sequence.
4089 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4090 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4091 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4092 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4094 dsq.setSequence(newres);
4096 // TODO: merges will never happen if we 'know' we have the real dataset
4097 // sequence - this should be detected when id==dssid
4099 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4100 // + (pre ? "prepended" : "") + " "
4101 // + (post ? "appended" : ""));
4106 java.util.Hashtable datasetIds = null;
4108 java.util.IdentityHashMap dataset2Ids = null;
4110 private Alignment getDatasetFor(String datasetId)
4112 if (datasetIds == null)
4114 datasetIds = new Hashtable();
4117 if (datasetIds.containsKey(datasetId))
4119 return (Alignment) datasetIds.get(datasetId);
4124 private void addDatasetRef(String datasetId, Alignment dataset)
4126 if (datasetIds == null)
4128 datasetIds = new Hashtable();
4130 datasetIds.put(datasetId, dataset);
4134 * make a new dataset ID for this jalview dataset alignment
4139 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4141 if (dataset.getDataset() != null)
4143 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4145 String datasetId = makeHashCode(dataset, null);
4146 if (datasetId == null)
4148 // make a new datasetId and record it
4149 if (dataset2Ids == null)
4151 dataset2Ids = new IdentityHashMap();
4155 datasetId = (String) dataset2Ids.get(dataset);
4157 if (datasetId == null)
4159 datasetId = "ds" + dataset2Ids.size() + 1;
4160 dataset2Ids.put(dataset, datasetId);
4166 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4168 for (int d = 0; d < sequence.getDBRefCount(); d++)
4170 DBRef dr = sequence.getDBRef(d);
4171 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4172 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4173 .getVersion(), sequence.getDBRef(d).getAccessionId());
4174 if (dr.getMapping() != null)
4176 entry.setMap(addMapping(dr.getMapping()));
4178 datasetSequence.addDBRef(entry);
4182 private jalview.datamodel.Mapping addMapping(Mapping m)
4184 SequenceI dsto = null;
4185 // Mapping m = dr.getMapping();
4186 int fr[] = new int[m.getMapListFromCount() * 2];
4187 Enumeration f = m.enumerateMapListFrom();
4188 for (int _i = 0; f.hasMoreElements(); _i += 2)
4190 MapListFrom mf = (MapListFrom) f.nextElement();
4191 fr[_i] = mf.getStart();
4192 fr[_i + 1] = mf.getEnd();
4194 int fto[] = new int[m.getMapListToCount() * 2];
4195 f = m.enumerateMapListTo();
4196 for (int _i = 0; f.hasMoreElements(); _i += 2)
4198 MapListTo mf = (MapListTo) f.nextElement();
4199 fto[_i] = mf.getStart();
4200 fto[_i + 1] = mf.getEnd();
4202 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4203 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4204 if (m.getMappingChoice() != null)
4206 MappingChoice mc = m.getMappingChoice();
4207 if (mc.getDseqFor() != null)
4209 String dsfor = "" + mc.getDseqFor();
4210 if (seqRefIds.containsKey(dsfor))
4215 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4219 frefedSequence.add(new Object[]
4226 * local sequence definition
4228 Sequence ms = mc.getSequence();
4229 jalview.datamodel.Sequence djs = null;
4230 String sqid = ms.getDsseqid();
4231 if (sqid != null && sqid.length() > 0)
4234 * recover dataset sequence
4236 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4241 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4242 sqid = ((Object) ms).toString(); // make up a new hascode for
4243 // undefined dataset sequence hash
4244 // (unlikely to happen)
4250 * make a new dataset sequence and add it to refIds hash
4252 djs = new jalview.datamodel.Sequence(ms.getName(),
4254 djs.setStart(jmap.getMap().getToLowest());
4255 djs.setEnd(jmap.getMap().getToHighest());
4256 djs.setVamsasId(uniqueSetSuffix + sqid);
4258 seqRefIds.put(sqid, djs);
4261 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4270 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4271 boolean keepSeqRefs)
4274 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4280 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4284 uniqueSetSuffix = "";
4285 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4290 if (this.frefedSequence == null)
4292 frefedSequence = new Vector();
4295 viewportsAdded = new Hashtable();
4297 AlignFrame af = LoadFromObject(jm, null, false, null);
4298 af.alignPanels.clear();
4299 af.closeMenuItem_actionPerformed(true);
4302 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4303 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4304 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4305 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4306 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4309 return af.alignPanel;
4313 * flag indicating if hashtables should be cleared on finalization TODO this
4314 * flag may not be necessary
4316 private final boolean _cleartables = true;
4318 private Hashtable jvids2vobj;
4323 * @see java.lang.Object#finalize()
4326 protected void finalize() throws Throwable
4328 // really make sure we have no buried refs left.
4333 this.seqRefIds = null;
4334 this.seqsToIds = null;
4338 private void warn(String msg)
4343 private void warn(String msg, Exception e)
4345 if (Cache.log != null)
4349 Cache.log.warn(msg, e);
4353 Cache.log.warn(msg);
4358 System.err.println("Warning: " + msg);
4361 e.printStackTrace();
4366 private void debug(String string)
4368 debug(string, null);
4371 private void debug(String msg, Exception e)
4373 if (Cache.log != null)
4377 Cache.log.debug(msg, e);
4381 Cache.log.debug(msg);
4386 System.err.println("Warning: " + msg);
4389 e.printStackTrace();
4395 * set the object to ID mapping tables used to write/recover objects and XML
4396 * ID strings for the jalview project. If external tables are provided then
4397 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4398 * object goes out of scope. - also populates the datasetIds hashtable with
4399 * alignment objects containing dataset sequences
4402 * Map from ID strings to jalview datamodel
4404 * Map from jalview datamodel to ID strings
4408 public void setObjectMappingTables(Hashtable vobj2jv,
4409 IdentityHashMap jv2vobj)
4411 this.jv2vobj = jv2vobj;
4412 this.vobj2jv = vobj2jv;
4413 Iterator ds = jv2vobj.keySet().iterator();
4415 while (ds.hasNext())
4417 Object jvobj = ds.next();
4418 id = jv2vobj.get(jvobj).toString();
4419 if (jvobj instanceof jalview.datamodel.Alignment)
4421 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4423 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4426 else if (jvobj instanceof jalview.datamodel.Sequence)
4428 // register sequence object so the XML parser can recover it.
4429 if (seqRefIds == null)
4431 seqRefIds = new Hashtable();
4433 if (seqsToIds == null)
4435 seqsToIds = new IdentityHashMap();
4437 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4438 seqsToIds.put(jvobj, id);
4440 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4442 if (annotationIds == null)
4444 annotationIds = new Hashtable();
4447 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4448 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4449 if (jvann.annotationId == null)
4451 jvann.annotationId = anid;
4453 if (!jvann.annotationId.equals(anid))
4455 // TODO verify that this is the correct behaviour
4456 this.warn("Overriding Annotation ID for " + anid
4457 + " from different id : " + jvann.annotationId);
4458 jvann.annotationId = anid;
4461 else if (jvobj instanceof String)
4463 if (jvids2vobj == null)
4465 jvids2vobj = new Hashtable();
4466 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4471 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4477 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4478 * objects created from the project archive. If string is null (default for
4479 * construction) then suffix will be set automatically.
4483 public void setUniqueSetSuffix(String string)
4485 uniqueSetSuffix = string;
4490 * uses skipList2 as the skipList for skipping views on sequence sets
4491 * associated with keys in the skipList
4495 public void setSkipList(Hashtable skipList2)
4497 skipList = skipList2;