2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.structures.JalviewStructureDisplayI;
24 import jalview.bin.Cache;
25 import jalview.datamodel.Alignment;
26 import jalview.datamodel.AlignmentAnnotation;
27 import jalview.datamodel.AlignmentI;
28 import jalview.datamodel.SequenceI;
29 import jalview.schemabinding.version2.AlcodMap;
30 import jalview.schemabinding.version2.Alcodon;
31 import jalview.schemabinding.version2.AlcodonFrame;
32 import jalview.schemabinding.version2.Annotation;
33 import jalview.schemabinding.version2.AnnotationColours;
34 import jalview.schemabinding.version2.AnnotationElement;
35 import jalview.schemabinding.version2.CalcIdParam;
36 import jalview.schemabinding.version2.DBRef;
37 import jalview.schemabinding.version2.Features;
38 import jalview.schemabinding.version2.Group;
39 import jalview.schemabinding.version2.HiddenColumns;
40 import jalview.schemabinding.version2.JGroup;
41 import jalview.schemabinding.version2.JSeq;
42 import jalview.schemabinding.version2.JalviewModel;
43 import jalview.schemabinding.version2.JalviewModelSequence;
44 import jalview.schemabinding.version2.MapListFrom;
45 import jalview.schemabinding.version2.MapListTo;
46 import jalview.schemabinding.version2.Mapping;
47 import jalview.schemabinding.version2.MappingChoice;
48 import jalview.schemabinding.version2.OtherData;
49 import jalview.schemabinding.version2.PdbentryItem;
50 import jalview.schemabinding.version2.Pdbids;
51 import jalview.schemabinding.version2.Property;
52 import jalview.schemabinding.version2.Sequence;
53 import jalview.schemabinding.version2.SequenceSet;
54 import jalview.schemabinding.version2.SequenceSetProperties;
55 import jalview.schemabinding.version2.Setting;
56 import jalview.schemabinding.version2.StructureState;
57 import jalview.schemabinding.version2.ThresholdLine;
58 import jalview.schemabinding.version2.Tree;
59 import jalview.schemabinding.version2.UserColours;
60 import jalview.schemabinding.version2.Viewport;
61 import jalview.schemes.AnnotationColourGradient;
62 import jalview.schemes.ColourSchemeI;
63 import jalview.schemes.ColourSchemeProperty;
64 import jalview.schemes.GraduatedColor;
65 import jalview.schemes.ResidueColourScheme;
66 import jalview.schemes.ResidueProperties;
67 import jalview.structure.StructureSelectionManager;
68 import jalview.util.MessageManager;
69 import jalview.util.Platform;
70 import jalview.util.jarInputStreamProvider;
71 import jalview.viewmodel.AlignmentViewport;
72 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
73 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
74 import jalview.ws.jws2.Jws2Discoverer;
75 import jalview.ws.jws2.dm.AAConSettings;
76 import jalview.ws.jws2.jabaws2.Jws2Instance;
77 import jalview.ws.params.ArgumentI;
78 import jalview.ws.params.AutoCalcSetting;
79 import jalview.ws.params.WsParamSetI;
81 import java.awt.Rectangle;
82 import java.io.BufferedReader;
83 import java.io.DataInputStream;
84 import java.io.DataOutputStream;
86 import java.io.FileInputStream;
87 import java.io.FileOutputStream;
88 import java.io.IOException;
89 import java.io.InputStreamReader;
90 import java.io.OutputStreamWriter;
91 import java.io.PrintWriter;
92 import java.lang.reflect.InvocationTargetException;
93 import java.net.MalformedURLException;
95 import java.util.ArrayList;
96 import java.util.Enumeration;
97 import java.util.HashSet;
98 import java.util.Hashtable;
99 import java.util.IdentityHashMap;
100 import java.util.Iterator;
101 import java.util.List;
102 import java.util.Map.Entry;
103 import java.util.Set;
104 import java.util.StringTokenizer;
105 import java.util.Vector;
106 import java.util.jar.JarEntry;
107 import java.util.jar.JarInputStream;
108 import java.util.jar.JarOutputStream;
110 import javax.swing.JInternalFrame;
111 import javax.swing.JOptionPane;
112 import javax.swing.SwingUtilities;
114 import org.exolab.castor.xml.Unmarshaller;
117 * Write out the current jalview desktop state as a Jalview XML stream.
119 * Note: the vamsas objects referred to here are primitive versions of the
120 * VAMSAS project schema elements - they are not the same and most likely never
124 * @version $Revision: 1.134 $
126 public class Jalview2XML
129 * create/return unique hash string for sq
132 * @return new or existing unique string for sq
134 String seqHash(SequenceI sq)
136 if (seqsToIds == null)
140 if (seqsToIds.containsKey(sq))
142 return (String) seqsToIds.get(sq);
146 // create sequential key
147 String key = "sq" + (seqsToIds.size() + 1);
148 key = makeHashCode(sq, key); // check we don't have an external reference
150 seqsToIds.put(sq, key);
159 if (seqRefIds != null)
163 if (seqsToIds != null)
173 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
174 // seqRefIds = new Hashtable();
175 // seqsToIds = new IdentityHashMap();
181 if (seqsToIds == null)
183 seqsToIds = new IdentityHashMap();
185 if (seqRefIds == null)
187 seqRefIds = new Hashtable();
192 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
193 * of sequence objects are created.
195 java.util.IdentityHashMap seqsToIds = null;
198 * jalview XML Sequence ID to jalview sequence object reference (both dataset
199 * and alignment sequences. Populated as XML reps of sequence objects are
202 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
204 Vector frefedSequence = null;
206 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
212 public Jalview2XML(boolean raiseGUI)
214 this.raiseGUI = raiseGUI;
217 public void resolveFrefedSequences()
219 if (frefedSequence.size() > 0)
221 int r = 0, rSize = frefedSequence.size();
224 Object[] ref = (Object[]) frefedSequence.elementAt(r);
227 String sref = (String) ref[0];
228 if (seqRefIds.containsKey(sref))
230 if (ref[1] instanceof jalview.datamodel.Mapping)
232 SequenceI seq = (SequenceI) seqRefIds.get(sref);
233 while (seq.getDatasetSequence() != null)
235 seq = seq.getDatasetSequence();
237 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
241 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
243 SequenceI seq = (SequenceI) seqRefIds.get(sref);
244 while (seq.getDatasetSequence() != null)
246 seq = seq.getDatasetSequence();
249 && ref[2] instanceof jalview.datamodel.Mapping)
251 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
252 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
253 seq, mp.getTo(), mp.getMap());
258 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
259 + ref[2].getClass() + " type objects.");
265 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
266 + ref[1].getClass() + " type objects.");
269 frefedSequence.remove(r);
275 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
277 + " with objecttype "
278 + ref[1].getClass());
285 frefedSequence.remove(r);
293 * This maintains a list of viewports, the key being the seqSetId. Important
294 * to set historyItem and redoList for multiple views
296 Hashtable viewportsAdded;
298 Hashtable annotationIds = new Hashtable();
300 String uniqueSetSuffix = "";
303 * List of pdbfiles added to Jar
305 Vector pdbfiles = null;
307 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
308 public void SaveState(File statefile)
312 FileOutputStream fos = new FileOutputStream(statefile);
313 JarOutputStream jout = new JarOutputStream(fos);
316 } catch (Exception e)
318 // TODO: inform user of the problem - they need to know if their data was
320 if (errorMessage == null)
322 errorMessage = "Couldn't write Jalview Archive to output file '"
323 + statefile + "' - See console error log for details";
327 errorMessage += "(output file was '" + statefile + "')";
335 * Writes a jalview project archive to the given Jar output stream.
339 public void SaveState(JarOutputStream jout)
341 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
348 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
353 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
354 // //////////////////////////////////////////////////
355 // NOTE ALSO new PrintWriter must be used for each new JarEntry
356 PrintWriter out = null;
358 Vector shortNames = new Vector();
361 for (int i = frames.length - 1; i > -1; i--)
363 if (frames[i] instanceof AlignFrame)
365 AlignFrame af = (AlignFrame) frames[i];
368 && skipList.containsKey(af.getViewport()
369 .getSequenceSetId()))
374 String shortName = af.getTitle();
376 if (shortName.indexOf(File.separatorChar) > -1)
378 shortName = shortName.substring(shortName
379 .lastIndexOf(File.separatorChar) + 1);
384 while (shortNames.contains(shortName))
386 if (shortName.endsWith("_" + (count - 1)))
388 shortName = shortName
389 .substring(0, shortName.lastIndexOf("_"));
392 shortName = shortName.concat("_" + count);
396 shortNames.addElement(shortName);
398 if (!shortName.endsWith(".xml"))
400 shortName = shortName + ".xml";
403 int ap, apSize = af.alignPanels.size();
405 for (ap = 0; ap < apSize; ap++)
407 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
409 String fileName = apSize == 1 ? shortName : ap + shortName;
410 if (!fileName.endsWith(".xml"))
412 fileName = fileName + ".xml";
415 SaveState(apanel, fileName, jout);
417 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
419 if (!dsses.containsKey(dssid))
421 dsses.put(dssid, af);
428 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
434 } catch (Exception foo)
439 } catch (Exception ex)
441 // TODO: inform user of the problem - they need to know if their data was
443 if (errorMessage == null)
445 errorMessage = "Couldn't write Jalview Archive - see error output for details";
447 ex.printStackTrace();
451 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
452 public boolean SaveAlignment(AlignFrame af, String jarFile,
457 int ap, apSize = af.alignPanels.size();
458 FileOutputStream fos = new FileOutputStream(jarFile);
459 JarOutputStream jout = new JarOutputStream(fos);
460 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
461 for (ap = 0; ap < apSize; ap++)
463 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
465 String jfileName = apSize == 1 ? fileName : fileName + ap;
466 if (!jfileName.endsWith(".xml"))
468 jfileName = jfileName + ".xml";
470 SaveState(apanel, jfileName, jout);
471 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
473 if (!dsses.containsKey(dssid))
475 dsses.put(dssid, af);
478 writeDatasetFor(dsses, fileName, jout);
482 } catch (Exception foo)
488 } catch (Exception ex)
490 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
491 ex.printStackTrace();
496 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
497 String fileName, JarOutputStream jout)
500 for (String dssids : dsses.keySet())
502 AlignFrame _af = dsses.get(dssids);
503 String jfileName = fileName + " Dataset for " + _af.getTitle();
504 if (!jfileName.endsWith(".xml"))
506 jfileName = jfileName + ".xml";
508 SaveState(_af.alignPanel, jfileName, true, jout);
513 * create a JalviewModel from an algnment view and marshall it to a
517 * panel to create jalview model for
519 * name of alignment panel written to output stream
525 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
526 JarOutputStream jout)
528 return SaveState(ap, fileName, false, jout);
532 * create a JalviewModel from an algnment view and marshall it to a
536 * panel to create jalview model for
538 * name of alignment panel written to output stream
540 * when true, only write the dataset for the alignment, not the data
541 * associated with the view.
547 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
548 boolean storeDS, JarOutputStream jout)
551 Vector jmolViewIds = new Vector(); //
552 Vector userColours = new Vector();
554 AlignViewport av = ap.av;
556 JalviewModel object = new JalviewModel();
557 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
559 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
560 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
561 "Development Build"));
563 jalview.datamodel.AlignmentI jal = av.getAlignment();
565 if (av.hasHiddenRows())
567 jal = jal.getHiddenSequences().getFullAlignment();
570 SequenceSet vamsasSet = new SequenceSet();
572 JalviewModelSequence jms = new JalviewModelSequence();
574 vamsasSet.setGapChar(jal.getGapCharacter() + "");
576 if (jal.getDataset() != null)
578 // dataset id is the dataset's hashcode
579 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
582 // switch jal and the dataset
583 jal = jal.getDataset();
586 if (jal.getProperties() != null)
588 Enumeration en = jal.getProperties().keys();
589 while (en.hasMoreElements())
591 String key = en.nextElement().toString();
592 SequenceSetProperties ssp = new SequenceSetProperties();
594 ssp.setValue(jal.getProperties().get(key).toString());
595 vamsasSet.addSequenceSetProperties(ssp);
600 Set<String> calcIdSet = new HashSet<String>();
604 jalview.datamodel.SequenceI jds, jdatasq;
605 for (int i = 0; i < jal.getHeight(); i++)
607 jds = jal.getSequenceAt(i);
608 jdatasq = jds.getDatasetSequence() == null ? jds : jds
609 .getDatasetSequence();
612 if (seqRefIds.get(id) != null)
614 // This happens for two reasons: 1. multiple views are being serialised.
615 // 2. the hashCode has collided with another sequence's code. This DOES
616 // HAPPEN! (PF00072.15.stk does this)
617 // JBPNote: Uncomment to debug writing out of files that do not read
618 // back in due to ArrayOutOfBoundExceptions.
619 // System.err.println("vamsasSeq backref: "+id+"");
620 // System.err.println(jds.getName()+"
621 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
622 // System.err.println("Hashcode: "+seqHash(jds));
623 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
624 // System.err.println(rsq.getName()+"
625 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
626 // System.err.println("Hashcode: "+seqHash(rsq));
630 vamsasSeq = createVamsasSequence(id, jds);
631 vamsasSet.addSequence(vamsasSeq);
632 seqRefIds.put(id, jds);
636 jseq.setStart(jds.getStart());
637 jseq.setEnd(jds.getEnd());
638 jseq.setColour(av.getSequenceColour(jds).getRGB());
640 jseq.setId(id); // jseq id should be a string not a number
643 // Store any sequences this sequence represents
644 if (av.hasHiddenRows())
646 jseq.setHidden(av.getAlignment().getHiddenSequences()
649 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
651 jalview.datamodel.SequenceI[] reps = av
652 .getRepresentedSequences(jal.getSequenceAt(i))
653 .getSequencesInOrder(jal);
655 for (int h = 0; h < reps.length; h++)
657 if (reps[h] != jal.getSequenceAt(i))
659 jseq.addHiddenSequences(jal.findIndex(reps[h]));
666 if (jdatasq.getSequenceFeatures() != null)
668 jalview.datamodel.SequenceFeature[] sf = jdatasq
669 .getSequenceFeatures();
671 while (index < sf.length)
673 Features features = new Features();
675 features.setBegin(sf[index].getBegin());
676 features.setEnd(sf[index].getEnd());
677 features.setDescription(sf[index].getDescription());
678 features.setType(sf[index].getType());
679 features.setFeatureGroup(sf[index].getFeatureGroup());
680 features.setScore(sf[index].getScore());
681 if (sf[index].links != null)
683 for (int l = 0; l < sf[index].links.size(); l++)
685 OtherData keyValue = new OtherData();
686 keyValue.setKey("LINK_" + l);
687 keyValue.setValue(sf[index].links.elementAt(l).toString());
688 features.addOtherData(keyValue);
691 if (sf[index].otherDetails != null)
694 Enumeration keys = sf[index].otherDetails.keys();
695 while (keys.hasMoreElements())
697 key = keys.nextElement().toString();
698 OtherData keyValue = new OtherData();
699 keyValue.setKey(key);
700 keyValue.setValue(sf[index].otherDetails.get(key).toString());
701 features.addOtherData(keyValue);
705 jseq.addFeatures(features);
710 if (jdatasq.getPDBId() != null)
712 Enumeration en = jdatasq.getPDBId().elements();
713 while (en.hasMoreElements())
715 Pdbids pdb = new Pdbids();
716 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
719 pdb.setId(entry.getId());
720 pdb.setType(entry.getType());
722 // store any JMol views associated with this seqeunce
723 // this section copes with duplicate entries in the project, so a
724 // dataset only view *should* be coped with sensibly
726 // This must have been loaded, is it still visible?
727 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
728 String matchedFile = null;
729 for (int f = frames.length - 1; f > -1; f--)
731 if (frames[f] instanceof AppJmol)
733 jmol = (AppJmol) frames[f];
734 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
736 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
737 && !(entry.getId().length() > 4 && entry
741 jmol.jmb.pdbentry[peid].getId()
746 if (matchedFile == null)
748 matchedFile = jmol.jmb.pdbentry[peid].getFile();
750 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
754 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
755 + jmol.jmb.pdbentry[peid].getFile());
759 // can get at it if the ID
760 // match is ambiguous (e.g.
762 String statestring = jmol.jmb.viewer.getStateInfo();
764 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
766 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
767 if (jds == jmol.jmb.sequence[peid][smap])
769 StructureState state = new StructureState();
770 state.setVisible(true);
771 state.setXpos(jmol.getX());
772 state.setYpos(jmol.getY());
773 state.setWidth(jmol.getWidth());
774 state.setHeight(jmol.getHeight());
775 state.setViewId(jmol.getViewId());
776 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
777 state.setColourwithAlignPanel(jmol
778 .isUsedforcolourby(ap));
779 state.setColourByJmol(jmol.isColouredByJmol());
780 if (!jmolViewIds.contains(state.getViewId()))
782 // Make sure we only store a Jmol state once in each XML
784 jmolViewIds.addElement(state.getViewId());
785 state.setContent(statestring.replaceAll("\n", ""));
789 state.setContent("# duplicate state");
791 pdb.addStructureState(state);
799 if (matchedFile != null || entry.getFile() != null)
801 if (entry.getFile() != null)
804 matchedFile = entry.getFile();
806 pdb.setFile(matchedFile); // entry.getFile());
807 if (pdbfiles == null)
809 pdbfiles = new Vector();
812 if (!pdbfiles.contains(entry.getId()))
814 pdbfiles.addElement(entry.getId());
817 File file = new File(matchedFile);
818 if (file.exists() && jout != null)
820 byte[] data = new byte[(int) file.length()];
821 jout.putNextEntry(new JarEntry(entry.getId()));
822 DataInputStream dis = new DataInputStream(
823 new FileInputStream(file));
826 DataOutputStream dout = new DataOutputStream(jout);
827 dout.write(data, 0, data.length);
831 } catch (Exception ex)
833 ex.printStackTrace();
839 if (entry.getProperty() != null)
841 PdbentryItem item = new PdbentryItem();
842 Hashtable properties = entry.getProperty();
843 Enumeration en2 = properties.keys();
844 while (en2.hasMoreElements())
846 Property prop = new Property();
847 String key = en2.nextElement().toString();
849 prop.setValue(properties.get(key).toString());
850 item.addProperty(prop);
852 pdb.addPdbentryItem(item);
862 if (!storeDS && av.hasHiddenRows())
864 jal = av.getAlignment();
867 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
869 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
870 for (int i = 0; i < jac.length; i++)
872 AlcodonFrame alc = new AlcodonFrame();
873 vamsasSet.addAlcodonFrame(alc);
874 for (int p = 0; p < jac[i].aaWidth; p++)
876 Alcodon cmap = new Alcodon();
877 if (jac[i].codons[p] != null)
879 // Null codons indicate a gapped column in the translated peptide
881 cmap.setPos1(jac[i].codons[p][0]);
882 cmap.setPos2(jac[i].codons[p][1]);
883 cmap.setPos3(jac[i].codons[p][2]);
885 alc.addAlcodon(cmap);
887 if (jac[i].getProtMappings() != null
888 && jac[i].getProtMappings().length > 0)
890 SequenceI[] dnas = jac[i].getdnaSeqs();
891 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
892 for (int m = 0; m < pmaps.length; m++)
894 AlcodMap alcmap = new AlcodMap();
895 alcmap.setDnasq(seqHash(dnas[m]));
896 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
898 alc.addAlcodMap(alcmap);
905 // /////////////////////////////////
906 if (!storeDS && av.currentTree != null)
908 // FIND ANY ASSOCIATED TREES
909 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
910 if (Desktop.desktop != null)
912 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
914 for (int t = 0; t < frames.length; t++)
916 if (frames[t] instanceof TreePanel)
918 TreePanel tp = (TreePanel) frames[t];
920 if (tp.treeCanvas.av.getAlignment() == jal)
922 Tree tree = new Tree();
923 tree.setTitle(tp.getTitle());
924 tree.setCurrentTree((av.currentTree == tp.getTree()));
925 tree.setNewick(tp.getTree().toString());
926 tree.setThreshold(tp.treeCanvas.threshold);
928 tree.setFitToWindow(tp.fitToWindow.getState());
929 tree.setFontName(tp.getTreeFont().getName());
930 tree.setFontSize(tp.getTreeFont().getSize());
931 tree.setFontStyle(tp.getTreeFont().getStyle());
932 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
934 tree.setShowBootstrap(tp.bootstrapMenu.getState());
935 tree.setShowDistances(tp.distanceMenu.getState());
937 tree.setHeight(tp.getHeight());
938 tree.setWidth(tp.getWidth());
939 tree.setXpos(tp.getX());
940 tree.setYpos(tp.getY());
941 tree.setId(makeHashCode(tp, null));
950 * store forward refs from an annotationRow to any groups
952 IdentityHashMap groupRefs = new IdentityHashMap();
955 for (SequenceI sq : jal.getSequences())
957 // Store annotation on dataset sequences only
958 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
959 if (aa != null && aa.length > 0)
961 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
968 if (jal.getAlignmentAnnotation() != null)
970 // Store the annotation shown on the alignment.
971 jalview.datamodel.AlignmentAnnotation[] aa = jal
972 .getAlignmentAnnotation();
973 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
978 if (jal.getGroups() != null)
980 JGroup[] groups = new JGroup[jal.getGroups().size()];
982 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
984 groups[++i] = new JGroup();
986 groups[i].setStart(sg.getStartRes());
987 groups[i].setEnd(sg.getEndRes());
988 groups[i].setName(sg.getName());
989 if (groupRefs.containsKey(sg))
991 // group has references so set it's ID field
992 groups[i].setId(groupRefs.get(sg).toString());
996 if (sg.cs.conservationApplied())
998 groups[i].setConsThreshold(sg.cs.getConservationInc());
1000 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1002 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
1008 .setColour(ColourSchemeProperty.getColourName(sg.cs));
1011 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1013 groups[i].setColour("AnnotationColourGradient");
1014 groups[i].setAnnotationColours(constructAnnotationColours(
1015 (jalview.schemes.AnnotationColourGradient) sg.cs,
1018 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1021 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
1025 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1028 groups[i].setPidThreshold(sg.cs.getThreshold());
1031 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1032 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1033 groups[i].setDisplayText(sg.getDisplayText());
1034 groups[i].setColourText(sg.getColourText());
1035 groups[i].setTextCol1(sg.textColour.getRGB());
1036 groups[i].setTextCol2(sg.textColour2.getRGB());
1037 groups[i].setTextColThreshold(sg.thresholdTextColour);
1038 groups[i].setShowUnconserved(sg.getShowNonconserved());
1039 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1040 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1041 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1042 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1043 for (int s = 0; s < sg.getSize(); s++)
1045 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1047 groups[i].addSeq(seqHash(seq));
1051 jms.setJGroup(groups);
1055 // /////////SAVE VIEWPORT
1056 Viewport view = new Viewport();
1057 view.setTitle(ap.alignFrame.getTitle());
1058 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1059 av.getSequenceSetId()));
1060 view.setId(av.getViewId());
1061 view.setViewName(av.viewName);
1062 view.setGatheredViews(av.gatherViewsHere);
1064 if (ap.av.explodedPosition != null)
1066 view.setXpos(av.explodedPosition.x);
1067 view.setYpos(av.explodedPosition.y);
1068 view.setWidth(av.explodedPosition.width);
1069 view.setHeight(av.explodedPosition.height);
1073 view.setXpos(ap.alignFrame.getBounds().x);
1074 view.setYpos(ap.alignFrame.getBounds().y);
1075 view.setWidth(ap.alignFrame.getBounds().width);
1076 view.setHeight(ap.alignFrame.getBounds().height);
1079 view.setStartRes(av.startRes);
1080 view.setStartSeq(av.startSeq);
1082 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1084 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1087 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1089 AnnotationColours ac = constructAnnotationColours(
1090 (jalview.schemes.AnnotationColourGradient) av
1091 .getGlobalColourScheme(),
1094 view.setAnnotationColours(ac);
1095 view.setBgColour("AnnotationColourGradient");
1099 view.setBgColour(ColourSchemeProperty.getColourName(av
1100 .getGlobalColourScheme()));
1103 ColourSchemeI cs = av.getGlobalColourScheme();
1107 if (cs.conservationApplied())
1109 view.setConsThreshold(cs.getConservationInc());
1110 if (cs instanceof jalview.schemes.UserColourScheme)
1112 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1116 if (cs instanceof ResidueColourScheme)
1118 view.setPidThreshold(cs.getThreshold());
1122 view.setConservationSelected(av.getConservationSelected());
1123 view.setPidSelected(av.getAbovePIDThreshold());
1124 view.setFontName(av.font.getName());
1125 view.setFontSize(av.font.getSize());
1126 view.setFontStyle(av.font.getStyle());
1127 view.setRenderGaps(av.renderGaps);
1128 view.setShowAnnotation(av.getShowAnnotation());
1129 view.setShowBoxes(av.getShowBoxes());
1130 view.setShowColourText(av.getColourText());
1131 view.setShowFullId(av.getShowJVSuffix());
1132 view.setRightAlignIds(av.isRightAlignIds());
1133 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1134 view.setShowText(av.getShowText());
1135 view.setShowUnconserved(av.getShowUnconserved());
1136 view.setWrapAlignment(av.getWrapAlignment());
1137 view.setTextCol1(av.textColour.getRGB());
1138 view.setTextCol2(av.textColour2.getRGB());
1139 view.setTextColThreshold(av.thresholdTextColour);
1140 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1141 view.setShowSequenceLogo(av.isShowSequenceLogo());
1142 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1143 view.setShowGroupConsensus(av.isShowGroupConsensus());
1144 view.setShowGroupConservation(av.isShowGroupConservation());
1145 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1146 view.setShowDbRefTooltip(av.isShowDbRefs());
1147 view.setFollowHighlight(av.followHighlight);
1148 view.setFollowSelection(av.followSelection);
1149 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1150 if (av.getFeaturesDisplayed() != null)
1152 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1154 String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1155 .getRenderOrder().toArray(new String[0]);
1157 Vector settingsAdded = new Vector();
1158 Object gstyle = null;
1159 GraduatedColor gcol = null;
1160 if (renderOrder != null)
1162 for (int ro = 0; ro < renderOrder.length; ro++)
1164 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1165 .getFeatureStyle(renderOrder[ro]);
1166 Setting setting = new Setting();
1167 setting.setType(renderOrder[ro]);
1168 if (gstyle instanceof GraduatedColor)
1170 gcol = (GraduatedColor) gstyle;
1171 setting.setColour(gcol.getMaxColor().getRGB());
1172 setting.setMincolour(gcol.getMinColor().getRGB());
1173 setting.setMin(gcol.getMin());
1174 setting.setMax(gcol.getMax());
1175 setting.setColourByLabel(gcol.isColourByLabel());
1176 setting.setAutoScale(gcol.isAutoScale());
1177 setting.setThreshold(gcol.getThresh());
1178 setting.setThreshstate(gcol.getThreshType());
1182 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1183 .getColour(renderOrder[ro]).getRGB());
1186 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1188 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1189 .getOrder(renderOrder[ro]);
1192 setting.setOrder(rorder);
1194 fs.addSetting(setting);
1195 settingsAdded.addElement(renderOrder[ro]);
1199 // Make sure we save none displayed feature settings
1200 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1201 .getFeatureColours().keySet().iterator();
1202 while (en.hasNext())
1204 String key = en.next().toString();
1205 if (settingsAdded.contains(key))
1210 Setting setting = new Setting();
1211 setting.setType(key);
1212 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1213 .getColour(key).getRGB());
1215 setting.setDisplay(false);
1216 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1220 setting.setOrder(rorder);
1222 fs.addSetting(setting);
1223 settingsAdded.addElement(key);
1225 // is groups actually supposed to be a map here ?
1226 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().getFeatureGroups()
1228 Vector groupsAdded = new Vector();
1229 while (en.hasNext())
1231 String grp = en.next().toString();
1232 if (groupsAdded.contains(grp))
1236 Group g = new Group();
1238 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1239 .getFeatureRenderer().checkGroupVisibility(grp, false))
1242 groupsAdded.addElement(grp);
1244 jms.setFeatureSettings(fs);
1248 if (av.hasHiddenColumns())
1250 if (av.getColumnSelection() == null
1251 || av.getColumnSelection().getHiddenColumns() == null)
1253 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1257 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1260 int[] region = (int[]) av.getColumnSelection()
1261 .getHiddenColumns().elementAt(c);
1262 HiddenColumns hc = new HiddenColumns();
1263 hc.setStart(region[0]);
1264 hc.setEnd(region[1]);
1265 view.addHiddenColumns(hc);
1269 if (calcIdSet.size() > 0)
1271 for (String calcId : calcIdSet)
1273 if (calcId.trim().length() > 0)
1275 CalcIdParam cidp = createCalcIdParam(calcId, av);
1276 // Some calcIds have no parameters.
1279 view.addCalcIdParam(cidp);
1285 jms.addViewport(view);
1287 object.setJalviewModelSequence(jms);
1288 object.getVamsasModel().addSequenceSet(vamsasSet);
1290 if (jout != null && fileName != null)
1292 // We may not want to write the object to disk,
1293 // eg we can copy the alignViewport to a new view object
1294 // using save and then load
1297 JarEntry entry = new JarEntry(fileName);
1298 jout.putNextEntry(entry);
1299 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1301 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1303 marshaller.marshal(object);
1306 } catch (Exception ex)
1308 // TODO: raise error in GUI if marshalling failed.
1309 ex.printStackTrace();
1315 private AnnotationColours constructAnnotationColours(
1316 AnnotationColourGradient acg, Vector userColours,
1317 JalviewModelSequence jms)
1319 AnnotationColours ac = new AnnotationColours();
1320 ac.setAboveThreshold(acg.getAboveThreshold());
1321 ac.setThreshold(acg.getAnnotationThreshold());
1322 ac.setAnnotation(acg.getAnnotation());
1323 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1325 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1330 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1334 ac.setMaxColour(acg.getMaxColour().getRGB());
1335 ac.setMinColour(acg.getMinColour().getRGB());
1336 ac.setPerSequence(acg.isSeqAssociated());
1337 ac.setPredefinedColours(acg.isPredefinedColours());
1341 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1342 IdentityHashMap groupRefs, AlignmentViewport av,
1343 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1346 for (int i = 0; i < aa.length; i++)
1348 Annotation an = new Annotation();
1350 if (aa[i].annotationId != null)
1352 annotationIds.put(aa[i].annotationId, aa[i]);
1355 an.setId(aa[i].annotationId);
1357 an.setVisible(aa[i].visible);
1359 an.setDescription(aa[i].description);
1361 if (aa[i].sequenceRef != null)
1363 // TODO later annotation sequenceRef should be the XML ID of the
1364 // sequence rather than its display name
1365 an.setSequenceRef(aa[i].sequenceRef.getName());
1367 if (aa[i].groupRef != null)
1369 Object groupIdr = groupRefs.get(aa[i].groupRef);
1370 if (groupIdr == null)
1372 // make a locally unique String
1373 groupRefs.put(aa[i].groupRef,
1374 groupIdr = ("" + System.currentTimeMillis()
1375 + aa[i].groupRef.getName() + groupRefs.size()));
1377 an.setGroupRef(groupIdr.toString());
1380 // store all visualization attributes for annotation
1381 an.setGraphHeight(aa[i].graphHeight);
1382 an.setCentreColLabels(aa[i].centreColLabels);
1383 an.setScaleColLabels(aa[i].scaleColLabel);
1384 an.setShowAllColLabels(aa[i].showAllColLabels);
1385 an.setBelowAlignment(aa[i].belowAlignment);
1387 if (aa[i].graph > 0)
1390 an.setGraphType(aa[i].graph);
1391 an.setGraphGroup(aa[i].graphGroup);
1392 if (aa[i].getThreshold() != null)
1394 ThresholdLine line = new ThresholdLine();
1395 line.setLabel(aa[i].getThreshold().label);
1396 line.setValue(aa[i].getThreshold().value);
1397 line.setColour(aa[i].getThreshold().colour.getRGB());
1398 an.setThresholdLine(line);
1406 an.setLabel(aa[i].label);
1408 if (aa[i] == av.getAlignmentQualityAnnot()
1409 || aa[i] == av.getAlignmentConservationAnnotation()
1410 || aa[i] == av.getAlignmentConsensusAnnotation()
1411 || aa[i].autoCalculated)
1413 // new way of indicating autocalculated annotation -
1414 an.setAutoCalculated(aa[i].autoCalculated);
1416 if (aa[i].hasScore())
1418 an.setScore(aa[i].getScore());
1421 if (aa[i].getCalcId() != null)
1423 calcIdSet.add(aa[i].getCalcId());
1424 an.setCalcId(aa[i].getCalcId());
1426 if (aa[i].hasProperties())
1428 for (String pr : aa[i].getProperties())
1430 Property prop = new Property();
1432 prop.setValue(aa[i].getProperty(pr));
1433 an.addProperty(prop);
1437 AnnotationElement ae;
1438 if (aa[i].annotations != null)
1440 an.setScoreOnly(false);
1441 for (int a = 0; a < aa[i].annotations.length; a++)
1443 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1448 ae = new AnnotationElement();
1449 if (aa[i].annotations[a].description != null)
1451 ae.setDescription(aa[i].annotations[a].description);
1453 if (aa[i].annotations[a].displayCharacter != null)
1455 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1458 if (!Float.isNaN(aa[i].annotations[a].value))
1460 ae.setValue(aa[i].annotations[a].value);
1464 if (aa[i].annotations[a].secondaryStructure > ' ')
1466 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1470 if (aa[i].annotations[a].colour != null
1471 && aa[i].annotations[a].colour != java.awt.Color.black)
1473 ae.setColour(aa[i].annotations[a].colour.getRGB());
1476 an.addAnnotationElement(ae);
1477 if (aa[i].autoCalculated)
1479 // only write one non-null entry into the annotation row -
1480 // sufficient to get the visualization attributes necessary to
1488 an.setScoreOnly(true);
1490 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1492 // skip autocalculated annotation - these are only provided for
1494 vamsasSet.addAnnotation(an);
1500 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1502 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1503 if (settings != null)
1505 CalcIdParam vCalcIdParam = new CalcIdParam();
1506 vCalcIdParam.setCalcId(calcId);
1507 vCalcIdParam.addServiceURL(settings.getServiceURI());
1508 // generic URI allowing a third party to resolve another instance of the
1509 // service used for this calculation
1510 for (String urls : settings.getServiceURLs())
1512 vCalcIdParam.addServiceURL(urls);
1514 vCalcIdParam.setVersion("1.0");
1515 if (settings.getPreset() != null)
1517 WsParamSetI setting = settings.getPreset();
1518 vCalcIdParam.setName(setting.getName());
1519 vCalcIdParam.setDescription(setting.getDescription());
1523 vCalcIdParam.setName("");
1524 vCalcIdParam.setDescription("Last used parameters");
1526 // need to be able to recover 1) settings 2) user-defined presets or
1527 // recreate settings from preset 3) predefined settings provided by
1528 // service - or settings that can be transferred (or discarded)
1529 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1531 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1532 // todo - decide if updateImmediately is needed for any projects.
1534 return vCalcIdParam;
1539 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1542 if (calcIdParam.getVersion().equals("1.0"))
1544 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1545 .getPreferredServiceFor(calcIdParam.getServiceURL());
1546 if (service != null)
1548 WsParamSetI parmSet = null;
1551 parmSet = service.getParamStore().parseServiceParameterFile(
1552 calcIdParam.getName(), calcIdParam.getDescription(),
1553 calcIdParam.getServiceURL(),
1554 calcIdParam.getParameters().replace("|\\n|", "\n"));
1555 } catch (IOException x)
1557 warn("Couldn't parse parameter data for "
1558 + calcIdParam.getCalcId(), x);
1561 List<ArgumentI> argList = null;
1562 if (calcIdParam.getName().length() > 0)
1564 parmSet = service.getParamStore()
1565 .getPreset(calcIdParam.getName());
1566 if (parmSet != null)
1568 // TODO : check we have a good match with settings in AACon -
1569 // otherwise we'll need to create a new preset
1574 argList = parmSet.getArguments();
1577 AAConSettings settings = new AAConSettings(
1578 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1579 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1580 calcIdParam.isNeedsUpdate());
1585 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1589 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1593 * External mapping between jalview objects and objects yielding a valid and
1594 * unique object ID string. This is null for normal Jalview project IO, but
1595 * non-null when a jalview project is being read or written as part of a
1598 IdentityHashMap jv2vobj = null;
1601 * Construct a unique ID for jvobj using either existing bindings or if none
1602 * exist, the result of the hashcode call for the object.
1605 * jalview data object
1606 * @return unique ID for referring to jvobj
1608 private String makeHashCode(Object jvobj, String altCode)
1610 if (jv2vobj != null)
1612 Object id = jv2vobj.get(jvobj);
1615 return id.toString();
1617 // check string ID mappings
1618 if (jvids2vobj != null && jvobj instanceof String)
1620 id = jvids2vobj.get(jvobj);
1624 return id.toString();
1626 // give up and warn that something has gone wrong
1627 warn("Cannot find ID for object in external mapping : " + jvobj);
1633 * return local jalview object mapped to ID, if it exists
1637 * @return null or object bound to idcode
1639 private Object retrieveExistingObj(String idcode)
1641 if (idcode != null && vobj2jv != null)
1643 return vobj2jv.get(idcode);
1649 * binding from ID strings from external mapping table to jalview data model
1652 private Hashtable vobj2jv;
1654 private Sequence createVamsasSequence(String id, SequenceI jds)
1656 return createVamsasSequence(true, id, jds, null);
1659 private Sequence createVamsasSequence(boolean recurse, String id,
1660 SequenceI jds, SequenceI parentseq)
1662 Sequence vamsasSeq = new Sequence();
1663 vamsasSeq.setId(id);
1664 vamsasSeq.setName(jds.getName());
1665 vamsasSeq.setSequence(jds.getSequenceAsString());
1666 vamsasSeq.setDescription(jds.getDescription());
1667 jalview.datamodel.DBRefEntry[] dbrefs = null;
1668 if (jds.getDatasetSequence() != null)
1670 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1671 if (jds.getDatasetSequence().getDBRef() != null)
1673 dbrefs = jds.getDatasetSequence().getDBRef();
1678 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1679 // dataset sequences only
1680 dbrefs = jds.getDBRef();
1684 for (int d = 0; d < dbrefs.length; d++)
1686 DBRef dbref = new DBRef();
1687 dbref.setSource(dbrefs[d].getSource());
1688 dbref.setVersion(dbrefs[d].getVersion());
1689 dbref.setAccessionId(dbrefs[d].getAccessionId());
1690 if (dbrefs[d].hasMap())
1692 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1694 dbref.setMapping(mp);
1696 vamsasSeq.addDBRef(dbref);
1702 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1703 SequenceI parentseq, SequenceI jds, boolean recurse)
1706 if (jmp.getMap() != null)
1710 jalview.util.MapList mlst = jmp.getMap();
1711 int r[] = mlst.getFromRanges();
1712 for (int s = 0; s < r.length; s += 2)
1714 MapListFrom mfrom = new MapListFrom();
1715 mfrom.setStart(r[s]);
1716 mfrom.setEnd(r[s + 1]);
1717 mp.addMapListFrom(mfrom);
1719 r = mlst.getToRanges();
1720 for (int s = 0; s < r.length; s += 2)
1722 MapListTo mto = new MapListTo();
1724 mto.setEnd(r[s + 1]);
1725 mp.addMapListTo(mto);
1727 mp.setMapFromUnit(mlst.getFromRatio());
1728 mp.setMapToUnit(mlst.getToRatio());
1729 if (jmp.getTo() != null)
1731 MappingChoice mpc = new MappingChoice();
1733 && (parentseq != jmp.getTo() || parentseq
1734 .getDatasetSequence() != jmp.getTo()))
1736 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1742 SequenceI ps = null;
1743 if (parentseq != jmp.getTo()
1744 && parentseq.getDatasetSequence() != jmp.getTo())
1746 // chaining dbref rather than a handshaking one
1747 jmpid = seqHash(ps = jmp.getTo());
1751 jmpid = seqHash(ps = parentseq);
1753 mpc.setDseqFor(jmpid);
1754 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1756 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1757 seqRefIds.put(mpc.getDseqFor(), ps);
1761 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1764 mp.setMappingChoice(mpc);
1770 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1771 Vector userColours, JalviewModelSequence jms)
1774 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1775 boolean newucs = false;
1776 if (!userColours.contains(ucs))
1778 userColours.add(ucs);
1781 id = "ucs" + userColours.indexOf(ucs);
1784 // actually create the scheme's entry in the XML model
1785 java.awt.Color[] colours = ucs.getColours();
1786 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1787 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1789 for (int i = 0; i < colours.length; i++)
1791 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1792 col.setName(ResidueProperties.aa[i]);
1793 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1794 jbucs.addColour(col);
1796 if (ucs.getLowerCaseColours() != null)
1798 colours = ucs.getLowerCaseColours();
1799 for (int i = 0; i < colours.length; i++)
1801 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1802 col.setName(ResidueProperties.aa[i].toLowerCase());
1803 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1804 jbucs.addColour(col);
1809 uc.setUserColourScheme(jbucs);
1810 jms.addUserColours(uc);
1816 jalview.schemes.UserColourScheme GetUserColourScheme(
1817 JalviewModelSequence jms, String id)
1819 UserColours[] uc = jms.getUserColours();
1820 UserColours colours = null;
1822 for (int i = 0; i < uc.length; i++)
1824 if (uc[i].getId().equals(id))
1832 java.awt.Color[] newColours = new java.awt.Color[24];
1834 for (int i = 0; i < 24; i++)
1836 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1837 .getUserColourScheme().getColour(i).getRGB(), 16));
1840 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1843 if (colours.getUserColourScheme().getColourCount() > 24)
1845 newColours = new java.awt.Color[23];
1846 for (int i = 0; i < 23; i++)
1848 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1849 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1851 ucs.setLowerCaseColours(newColours);
1858 * contains last error message (if any) encountered by XML loader.
1860 String errorMessage = null;
1863 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1864 * exceptions are raised during project XML parsing
1866 public boolean attemptversion1parse = true;
1869 * Load a jalview project archive from a jar file
1872 * - HTTP URL or filename
1874 public AlignFrame LoadJalviewAlign(final String file)
1877 jalview.gui.AlignFrame af = null;
1881 // create list to store references for any new Jmol viewers created
1882 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1883 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1884 // Workaround is to make sure caller implements the JarInputStreamProvider
1886 // so we can re-open the jar input stream for each entry.
1888 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1889 af = LoadJalviewAlign(jprovider);
1891 } catch (MalformedURLException e)
1893 errorMessage = "Invalid URL format for '" + file + "'";
1899 SwingUtilities.invokeAndWait(new Runnable()
1903 setLoadingFinishedForNewStructureViewers();
1906 } catch (Exception x)
1914 private jarInputStreamProvider createjarInputStreamProvider(
1915 final String file) throws MalformedURLException
1918 errorMessage = null;
1919 uniqueSetSuffix = null;
1921 viewportsAdded = null;
1922 frefedSequence = null;
1924 if (file.startsWith("http://"))
1926 url = new URL(file);
1928 final URL _url = url;
1929 return new jarInputStreamProvider()
1933 public JarInputStream getJarInputStream() throws IOException
1937 return new JarInputStream(_url.openStream());
1941 return new JarInputStream(new FileInputStream(file));
1946 public String getFilename()
1954 * Recover jalview session from a jalview project archive. Caller may
1955 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1956 * themselves. Any null fields will be initialised with default values,
1957 * non-null fields are left alone.
1962 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1964 errorMessage = null;
1965 if (uniqueSetSuffix == null)
1967 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1969 if (seqRefIds == null)
1971 seqRefIds = new Hashtable();
1973 if (viewportsAdded == null)
1975 viewportsAdded = new Hashtable();
1977 if (frefedSequence == null)
1979 frefedSequence = new Vector();
1982 jalview.gui.AlignFrame af = null, _af = null;
1983 Hashtable gatherToThisFrame = new Hashtable();
1984 final String file = jprovider.getFilename();
1987 JarInputStream jin = null;
1988 JarEntry jarentry = null;
1993 jin = jprovider.getJarInputStream();
1994 for (int i = 0; i < entryCount; i++)
1996 jarentry = jin.getNextJarEntry();
1999 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2001 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2002 JalviewModel object = new JalviewModel();
2004 Unmarshaller unmar = new Unmarshaller(object);
2005 unmar.setValidation(false);
2006 object = (JalviewModel) unmar.unmarshal(in);
2007 if (true) // !skipViewport(object))
2009 _af = LoadFromObject(object, file, true, jprovider);
2010 if (object.getJalviewModelSequence().getViewportCount() > 0)
2013 if (af.viewport.gatherViewsHere)
2015 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2021 else if (jarentry != null)
2023 // Some other file here.
2026 } while (jarentry != null);
2027 resolveFrefedSequences();
2028 } catch (java.io.FileNotFoundException ex)
2030 ex.printStackTrace();
2031 errorMessage = "Couldn't locate Jalview XML file : " + file;
2032 System.err.println("Exception whilst loading jalview XML file : "
2034 } catch (java.net.UnknownHostException ex)
2036 ex.printStackTrace();
2037 errorMessage = "Couldn't locate Jalview XML file : " + file;
2038 System.err.println("Exception whilst loading jalview XML file : "
2040 } catch (Exception ex)
2042 System.err.println("Parsing as Jalview Version 2 file failed.");
2043 ex.printStackTrace(System.err);
2044 if (attemptversion1parse)
2046 // Is Version 1 Jar file?
2049 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2050 } catch (Exception ex2)
2052 System.err.println("Exception whilst loading as jalviewXMLV1:");
2053 ex2.printStackTrace();
2057 if (Desktop.instance != null)
2059 Desktop.instance.stopLoading();
2063 System.out.println("Successfully loaded archive file");
2066 ex.printStackTrace();
2068 System.err.println("Exception whilst loading jalview XML file : "
2070 } catch (OutOfMemoryError e)
2072 // Don't use the OOM Window here
2073 errorMessage = "Out of memory loading jalview XML file";
2074 System.err.println("Out of memory whilst loading jalview XML file");
2075 e.printStackTrace();
2078 if (Desktop.instance != null)
2080 Desktop.instance.stopLoading();
2083 Enumeration en = gatherToThisFrame.elements();
2084 while (en.hasMoreElements())
2086 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2088 if (errorMessage != null)
2096 * check errorMessage for a valid error message and raise an error box in the
2097 * GUI or write the current errorMessage to stderr and then clear the error
2100 protected void reportErrors()
2102 reportErrors(false);
2105 protected void reportErrors(final boolean saving)
2107 if (errorMessage != null)
2109 final String finalErrorMessage = errorMessage;
2112 javax.swing.SwingUtilities.invokeLater(new Runnable()
2117 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2118 finalErrorMessage, "Error "
2119 + (saving ? "saving" : "loading")
2120 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2126 System.err.println("Problem loading Jalview file: " + errorMessage);
2129 errorMessage = null;
2132 Hashtable<String, String> alreadyLoadedPDB;
2135 * when set, local views will be updated from view stored in JalviewXML
2136 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2137 * sync if this is set to true.
2139 private final boolean updateLocalViews = false;
2141 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2143 if (alreadyLoadedPDB == null)
2145 alreadyLoadedPDB = new Hashtable();
2148 if (alreadyLoadedPDB.containsKey(pdbId))
2150 return alreadyLoadedPDB.get(pdbId).toString();
2155 JarInputStream jin = jprovider.getJarInputStream();
2157 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2158 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2159 * FileInputStream(jprovider)); }
2162 JarEntry entry = null;
2165 entry = jin.getNextJarEntry();
2166 } while (entry != null && !entry.getName().equals(pdbId));
2169 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2170 File outFile = File.createTempFile("jalview_pdb", ".txt");
2171 outFile.deleteOnExit();
2172 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2175 while ((data = in.readLine()) != null)
2182 } catch (Exception foo)
2187 String t = outFile.getAbsolutePath();
2188 alreadyLoadedPDB.put(pdbId, t);
2193 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2195 } catch (Exception ex)
2197 ex.printStackTrace();
2203 private class JvAnnotRow
2205 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2212 * persisted version of annotation row from which to take vis properties
2214 public jalview.datamodel.AlignmentAnnotation template;
2217 * original position of the annotation row in the alignment
2223 * Load alignment frame from jalview XML DOM object
2228 * filename source string
2229 * @param loadTreesAndStructures
2230 * when false only create Viewport
2232 * data source provider
2233 * @return alignment frame created from view stored in DOM
2235 AlignFrame LoadFromObject(JalviewModel object, String file,
2236 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2238 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2239 Sequence[] vamsasSeq = vamsasSet.getSequence();
2241 JalviewModelSequence jms = object.getJalviewModelSequence();
2243 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2246 // ////////////////////////////////
2249 Vector hiddenSeqs = null;
2250 jalview.datamodel.Sequence jseq;
2252 ArrayList tmpseqs = new ArrayList();
2254 boolean multipleView = false;
2256 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2257 int vi = 0; // counter in vamsasSeq array
2258 for (int i = 0; i < JSEQ.length; i++)
2260 String seqId = JSEQ[i].getId();
2262 if (seqRefIds.get(seqId) != null)
2264 tmpseqs.add(seqRefIds.get(seqId));
2265 multipleView = true;
2269 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2270 vamsasSeq[vi].getSequence());
2271 jseq.setDescription(vamsasSeq[vi].getDescription());
2272 jseq.setStart(JSEQ[i].getStart());
2273 jseq.setEnd(JSEQ[i].getEnd());
2274 jseq.setVamsasId(uniqueSetSuffix + seqId);
2275 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2280 if (JSEQ[i].getHidden())
2282 if (hiddenSeqs == null)
2284 hiddenSeqs = new Vector();
2287 hiddenSeqs.addElement(seqRefIds.get(seqId));
2293 // Create the alignment object from the sequence set
2294 // ///////////////////////////////
2295 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2298 tmpseqs.toArray(orderedSeqs);
2300 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2303 // / Add the alignment properties
2304 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2306 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2307 al.setProperty(ssp.getKey(), ssp.getValue());
2311 // SequenceFeatures are added to the DatasetSequence,
2312 // so we must create or recover the dataset before loading features
2313 // ///////////////////////////////
2314 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2316 // older jalview projects do not have a dataset id.
2317 al.setDataset(null);
2321 // recover dataset - passing on flag indicating if this a 'viewless'
2322 // sequence set (a.k.a. a stored dataset for the project)
2323 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2324 .getViewportCount() == 0);
2326 // ///////////////////////////////
2328 Hashtable pdbloaded = new Hashtable();
2331 // load sequence features, database references and any associated PDB
2332 // structures for the alignment
2333 for (int i = 0; i < vamsasSeq.length; i++)
2335 if (JSEQ[i].getFeaturesCount() > 0)
2337 Features[] features = JSEQ[i].getFeatures();
2338 for (int f = 0; f < features.length; f++)
2340 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2341 features[f].getType(), features[f].getDescription(),
2342 features[f].getStatus(), features[f].getBegin(),
2343 features[f].getEnd(), features[f].getFeatureGroup());
2345 sf.setScore(features[f].getScore());
2346 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2348 OtherData keyValue = features[f].getOtherData(od);
2349 if (keyValue.getKey().startsWith("LINK"))
2351 sf.addLink(keyValue.getValue());
2355 sf.setValue(keyValue.getKey(), keyValue.getValue());
2360 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2363 if (vamsasSeq[i].getDBRefCount() > 0)
2365 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2367 if (JSEQ[i].getPdbidsCount() > 0)
2369 Pdbids[] ids = JSEQ[i].getPdbids();
2370 for (int p = 0; p < ids.length; p++)
2372 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2373 entry.setId(ids[p].getId());
2374 entry.setType(ids[p].getType());
2375 if (ids[p].getFile() != null)
2377 if (!pdbloaded.containsKey(ids[p].getFile()))
2379 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2383 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2386 StructureSelectionManager.getStructureSelectionManager(
2388 .registerPDBEntry(entry);
2389 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2393 } // end !multipleview
2395 // ///////////////////////////////
2396 // LOAD SEQUENCE MAPPINGS
2398 if (vamsasSet.getAlcodonFrameCount() > 0)
2400 // TODO Potentially this should only be done once for all views of an
2402 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2403 for (int i = 0; i < alc.length; i++)
2405 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2406 alc[i].getAlcodonCount());
2407 if (alc[i].getAlcodonCount() > 0)
2409 Alcodon[] alcods = alc[i].getAlcodon();
2410 for (int p = 0; p < cf.codons.length; p++)
2412 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2413 && alcods[p].hasPos3())
2415 // translated codons require three valid positions
2416 cf.codons[p] = new int[3];
2417 cf.codons[p][0] = (int) alcods[p].getPos1();
2418 cf.codons[p][1] = (int) alcods[p].getPos2();
2419 cf.codons[p][2] = (int) alcods[p].getPos3();
2423 cf.codons[p] = null;
2427 if (alc[i].getAlcodMapCount() > 0)
2429 AlcodMap[] maps = alc[i].getAlcodMap();
2430 for (int m = 0; m < maps.length; m++)
2432 SequenceI dnaseq = (SequenceI) seqRefIds
2433 .get(maps[m].getDnasq());
2435 jalview.datamodel.Mapping mapping = null;
2436 // attach to dna sequence reference.
2437 if (maps[m].getMapping() != null)
2439 mapping = addMapping(maps[m].getMapping());
2443 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2448 frefedSequence.add(new Object[]
2449 { maps[m].getDnasq(), cf, mapping });
2453 al.addCodonFrame(cf);
2458 // ////////////////////////////////
2460 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2462 * store any annotations which forward reference a group's ID
2464 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2466 if (vamsasSet.getAnnotationCount() > 0)
2468 Annotation[] an = vamsasSet.getAnnotation();
2470 for (int i = 0; i < an.length; i++)
2473 * test if annotation is automatically calculated for this view only
2475 boolean autoForView = false;
2476 if (an[i].getLabel().equals("Quality")
2477 || an[i].getLabel().equals("Conservation")
2478 || an[i].getLabel().equals("Consensus"))
2480 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2482 if (!an[i].hasAutoCalculated())
2484 an[i].setAutoCalculated(true);
2488 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2490 // remove ID - we don't recover annotation from other views for
2491 // view-specific annotation
2495 // set visiblity for other annotation in this view
2496 if (an[i].getId() != null
2497 && annotationIds.containsKey(an[i].getId()))
2499 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2500 .get(an[i].getId());
2501 // in principle Visible should always be true for annotation displayed
2502 // in multiple views
2503 if (an[i].hasVisible())
2505 jda.visible = an[i].getVisible();
2508 al.addAnnotation(jda);
2512 // Construct new annotation from model.
2513 AnnotationElement[] ae = an[i].getAnnotationElement();
2514 jalview.datamodel.Annotation[] anot = null;
2515 java.awt.Color firstColour = null;
2517 if (!an[i].getScoreOnly())
2519 anot = new jalview.datamodel.Annotation[al.getWidth()];
2520 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2522 anpos = ae[aa].getPosition();
2524 if (anpos >= anot.length)
2529 anot[anpos] = new jalview.datamodel.Annotation(
2531 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2532 (ae[aa].getSecondaryStructure() == null || ae[aa]
2533 .getSecondaryStructure().length() == 0) ? ' '
2534 : ae[aa].getSecondaryStructure().charAt(0),
2538 // JBPNote: Consider verifying dataflow for IO of secondary
2539 // structure annotation read from Stockholm files
2540 // this was added to try to ensure that
2541 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2543 // anot[ae[aa].getPosition()].displayCharacter = "";
2545 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2546 if (firstColour == null)
2548 firstColour = anot[anpos].colour;
2552 jalview.datamodel.AlignmentAnnotation jaa = null;
2554 if (an[i].getGraph())
2556 float llim = 0, hlim = 0;
2557 // if (autoForView || an[i].isAutoCalculated()) {
2560 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2561 an[i].getDescription(), anot, llim, hlim,
2562 an[i].getGraphType());
2564 jaa.graphGroup = an[i].getGraphGroup();
2565 jaa._linecolour = firstColour;
2566 if (an[i].getThresholdLine() != null)
2568 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2569 .getThresholdLine().getValue(), an[i]
2570 .getThresholdLine().getLabel(), new java.awt.Color(
2571 an[i].getThresholdLine().getColour())));
2574 if (autoForView || an[i].isAutoCalculated())
2576 // Hardwire the symbol display line to ensure that labels for
2577 // histograms are displayed
2583 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2584 an[i].getDescription(), anot);
2585 jaa._linecolour = firstColour;
2587 // register new annotation
2588 if (an[i].getId() != null)
2590 annotationIds.put(an[i].getId(), jaa);
2591 jaa.annotationId = an[i].getId();
2593 // recover sequence association
2594 if (an[i].getSequenceRef() != null)
2596 if (al.findName(an[i].getSequenceRef()) != null)
2598 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2600 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2603 // and make a note of any group association
2604 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2606 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2607 .get(an[i].getGroupRef());
2610 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2611 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2616 if (an[i].hasScore())
2618 jaa.setScore(an[i].getScore());
2620 if (an[i].hasVisible())
2622 jaa.visible = an[i].getVisible();
2625 if (an[i].hasCentreColLabels())
2627 jaa.centreColLabels = an[i].getCentreColLabels();
2630 if (an[i].hasScaleColLabels())
2632 jaa.scaleColLabel = an[i].getScaleColLabels();
2634 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2636 // newer files have an 'autoCalculated' flag and store calculation
2637 // state in viewport properties
2638 jaa.autoCalculated = true; // means annotation will be marked for
2639 // update at end of load.
2641 if (an[i].hasGraphHeight())
2643 jaa.graphHeight = an[i].getGraphHeight();
2645 if (an[i].hasBelowAlignment())
2647 jaa.belowAlignment = an[i].isBelowAlignment();
2649 jaa.setCalcId(an[i].getCalcId());
2650 if (an[i].getPropertyCount() > 0)
2652 for (jalview.schemabinding.version2.Property prop : an[i]
2655 jaa.setProperty(prop.getName(), prop.getValue());
2658 if (jaa.autoCalculated)
2660 autoAlan.add(new JvAnnotRow(i, jaa));
2663 // if (!autoForView)
2665 // add autocalculated group annotation and any user created annotation
2667 al.addAnnotation(jaa);
2671 // ///////////////////////
2673 // Create alignment markup and styles for this view
2674 if (jms.getJGroupCount() > 0)
2676 JGroup[] groups = jms.getJGroup();
2677 boolean addAnnotSchemeGroup = false;
2678 for (int i = 0; i < groups.length; i++)
2680 ColourSchemeI cs = null;
2682 if (groups[i].getColour() != null)
2684 if (groups[i].getColour().startsWith("ucs"))
2686 cs = GetUserColourScheme(jms, groups[i].getColour());
2688 else if (groups[i].getColour().equals("AnnotationColourGradient")
2689 && groups[i].getAnnotationColours() != null)
2691 addAnnotSchemeGroup = true;
2696 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2701 cs.setThreshold(groups[i].getPidThreshold(), true);
2705 Vector seqs = new Vector();
2707 for (int s = 0; s < groups[i].getSeqCount(); s++)
2709 String seqId = groups[i].getSeq(s) + "";
2710 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2715 seqs.addElement(ts);
2719 if (seqs.size() < 1)
2724 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2725 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2726 groups[i].getDisplayText(), groups[i].getColourText(),
2727 groups[i].getStart(), groups[i].getEnd());
2729 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2731 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2732 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2733 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2734 .isShowUnconserved() : false);
2735 sg.thresholdTextColour = groups[i].getTextColThreshold();
2736 if (groups[i].hasShowConsensusHistogram())
2738 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2741 if (groups[i].hasShowSequenceLogo())
2743 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2745 if (groups[i].hasNormaliseSequenceLogo())
2747 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2749 if (groups[i].hasIgnoreGapsinConsensus())
2751 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2753 if (groups[i].getConsThreshold() != 0)
2755 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2756 "All", ResidueProperties.propHash, 3,
2757 sg.getSequences(null), 0, sg.getWidth() - 1);
2759 c.verdict(false, 25);
2760 sg.cs.setConservation(c);
2763 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2765 // re-instate unique group/annotation row reference
2766 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2767 .get(groups[i].getId());
2770 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2773 if (jaa.autoCalculated)
2775 // match up and try to set group autocalc alignment row for this
2777 if (jaa.label.startsWith("Consensus for "))
2779 sg.setConsensus(jaa);
2781 // match up and try to set group autocalc alignment row for this
2783 if (jaa.label.startsWith("Conservation for "))
2785 sg.setConservationRow(jaa);
2792 if (addAnnotSchemeGroup)
2794 // reconstruct the annotation colourscheme
2795 sg.cs = constructAnnotationColour(
2796 groups[i].getAnnotationColours(), null, al, jms, false);
2802 // only dataset in this model, so just return.
2805 // ///////////////////////////////
2808 // If we just load in the same jar file again, the sequenceSetId
2809 // will be the same, and we end up with multiple references
2810 // to the same sequenceSet. We must modify this id on load
2811 // so that each load of the file gives a unique id
2812 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2813 String viewId = (view.getId() == null ? null : view.getId()
2815 AlignFrame af = null;
2816 AlignViewport av = null;
2817 // now check to see if we really need to create a new viewport.
2818 if (multipleView && viewportsAdded.size() == 0)
2820 // We recovered an alignment for which a viewport already exists.
2821 // TODO: fix up any settings necessary for overlaying stored state onto
2822 // state recovered from another document. (may not be necessary).
2823 // we may need a binding from a viewport in memory to one recovered from
2825 // and then recover its containing af to allow the settings to be applied.
2826 // TODO: fix for vamsas demo
2828 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2830 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2831 if (seqsetobj != null)
2833 if (seqsetobj instanceof String)
2835 uniqueSeqSetId = (String) seqsetobj;
2837 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2843 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2849 * indicate that annotation colours are applied across all groups (pre
2850 * Jalview 2.8.1 behaviour)
2852 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2853 object.getVersion());
2855 AlignmentPanel ap = null;
2856 boolean isnewview = true;
2859 // Check to see if this alignment already has a view id == viewId
2860 jalview.gui.AlignmentPanel views[] = Desktop
2861 .getAlignmentPanels(uniqueSeqSetId);
2862 if (views != null && views.length > 0)
2864 for (int v = 0; v < views.length; v++)
2866 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2868 // recover the existing alignpanel, alignframe, viewport
2869 af = views[v].alignFrame;
2872 // TODO: could even skip resetting view settings if we don't want to
2873 // change the local settings from other jalview processes
2882 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2883 uniqueSeqSetId, viewId, autoAlan);
2888 // /////////////////////////////////////
2889 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2893 for (int t = 0; t < jms.getTreeCount(); t++)
2896 Tree tree = jms.getTree(t);
2898 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2901 tp = af.ShowNewickTree(
2902 new jalview.io.NewickFile(tree.getNewick()),
2903 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2904 tree.getXpos(), tree.getYpos());
2905 if (tree.getId() != null)
2907 // perhaps bind the tree id to something ?
2912 // update local tree attributes ?
2913 // TODO: should check if tp has been manipulated by user - if so its
2914 // settings shouldn't be modified
2915 tp.setTitle(tree.getTitle());
2916 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2917 .getWidth(), tree.getHeight()));
2918 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2921 tp.treeCanvas.av = av; // af.viewport;
2922 tp.treeCanvas.ap = ap; // af.alignPanel;
2927 warn("There was a problem recovering stored Newick tree: \n"
2928 + tree.getNewick());
2932 tp.fitToWindow.setState(tree.getFitToWindow());
2933 tp.fitToWindow_actionPerformed(null);
2935 if (tree.getFontName() != null)
2937 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2938 .getFontStyle(), tree.getFontSize()));
2942 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2943 .getFontStyle(), tree.getFontSize()));
2946 tp.showPlaceholders(tree.getMarkUnlinked());
2947 tp.showBootstrap(tree.getShowBootstrap());
2948 tp.showDistances(tree.getShowDistances());
2950 tp.treeCanvas.threshold = tree.getThreshold();
2952 if (tree.getCurrentTree())
2954 af.viewport.setCurrentTree(tp.getTree());
2958 } catch (Exception ex)
2960 ex.printStackTrace();
2964 // //LOAD STRUCTURES
2965 if (loadTreesAndStructures)
2967 // run through all PDB ids on the alignment, and collect mappings between
2968 // jmol view ids and all sequences referring to it
2969 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2971 for (int i = 0; i < JSEQ.length; i++)
2973 if (JSEQ[i].getPdbidsCount() > 0)
2975 Pdbids[] ids = JSEQ[i].getPdbids();
2976 for (int p = 0; p < ids.length; p++)
2978 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2980 // check to see if we haven't already created this structure view
2981 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2982 : ids[p].getStructureState(s).getViewId()
2984 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2985 // Originally : ids[p].getFile()
2986 // : TODO: verify external PDB file recovery still works in normal
2987 // jalview project load
2988 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2989 jpdb.setId(ids[p].getId());
2991 int x = ids[p].getStructureState(s).getXpos();
2992 int y = ids[p].getStructureState(s).getYpos();
2993 int width = ids[p].getStructureState(s).getWidth();
2994 int height = ids[p].getStructureState(s).getHeight();
2996 // Probably don't need to do this anymore...
2997 // Desktop.desktop.getComponentAt(x, y);
2998 // TODO: NOW: check that this recovers the PDB file correctly.
2999 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3000 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
3001 .get(JSEQ[i].getId() + "");
3002 if (sviewid == null)
3004 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3007 if (!jmolViewIds.containsKey(sviewid))
3009 jmolViewIds.put(sviewid, new Object[]
3011 { x, y, width, height }, "",
3012 new Hashtable<String, Object[]>(), new boolean[]
3013 { false, false, true } });
3014 // Legacy pre-2.7 conversion JAL-823 :
3015 // do not assume any view has to be linked for colour by
3019 // assemble String[] { pdb files }, String[] { id for each
3020 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3021 // seqs_file 2}, boolean[] {
3022 // linkAlignPanel,superposeWithAlignpanel}} from hash
3023 Object[] jmoldat = jmolViewIds.get(sviewid);
3024 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
3025 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
3026 s).getAlignwithAlignPanel() : false;
3027 // never colour by linked panel if not specified
3028 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
3029 .hasColourwithAlignPanel() ? ids[p]
3030 .getStructureState(s).getColourwithAlignPanel()
3032 // default for pre-2.7 projects is that Jmol colouring is enabled
3033 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
3034 .hasColourByJmol() ? ids[p].getStructureState(s)
3035 .getColourByJmol() : true;
3037 if (((String) jmoldat[1]).length() < ids[p]
3038 .getStructureState(s).getContent().length())
3041 jmoldat[1] = ids[p].getStructureState(s).getContent();
3044 if (ids[p].getFile() != null)
3046 File mapkey = new File(ids[p].getFile());
3047 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3049 if (seqstrmaps == null)
3051 ((Hashtable) jmoldat[2]).put(mapkey,
3052 seqstrmaps = new Object[]
3053 { pdbFile, ids[p].getId(), new Vector(),
3056 if (!((Vector) seqstrmaps[2]).contains(seq))
3058 ((Vector) seqstrmaps[2]).addElement(seq);
3059 // ((Vector)seqstrmaps[3]).addElement(n) :
3060 // in principle, chains
3061 // should be stored here : do we need to
3062 // TODO: store and recover seq/pdb_id :
3068 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");
3077 // Instantiate the associated Jmol views
3078 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3080 String sviewid = entry.getKey();
3081 Object[] svattrib = entry.getValue();
3082 int[] geom = (int[]) svattrib[0];
3083 String state = (String) svattrib[1];
3084 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3085 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3086 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3087 // collate the pdbfile -> sequence mappings from this view
3088 Vector<String> pdbfilenames = new Vector<String>();
3089 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3090 Vector<String> pdbids = new Vector<String>();
3092 // Search to see if we've already created this Jmol view
3093 AppJmol comp = null;
3094 JInternalFrame[] frames = null;
3099 frames = Desktop.desktop.getAllFrames();
3100 } catch (ArrayIndexOutOfBoundsException e)
3102 // occasional No such child exceptions are thrown here...
3107 } catch (Exception f)
3112 } while (frames == null);
3113 // search for any Jmol windows already open from other
3114 // alignment views that exactly match the stored structure state
3115 for (int f = 0; comp == null && f < frames.length; f++)
3117 if (frames[f] instanceof AppJmol)
3120 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3122 // post jalview 2.4 schema includes structure view id
3123 comp = (AppJmol) frames[f];
3125 else if (frames[f].getX() == x && frames[f].getY() == y
3126 && frames[f].getHeight() == height
3127 && frames[f].getWidth() == width)
3129 comp = (AppJmol) frames[f];
3136 // create a new Jmol window.
3137 // First parse the Jmol state to translate filenames loaded into the
3138 // view, and record the order in which files are shown in the Jmol
3139 // view, so we can add the sequence mappings in same order.
3140 StringBuffer newFileLoc = null;
3141 int cp = 0, ncp, ecp;
3142 while ((ncp = state.indexOf("load ", cp)) > -1)
3144 if (newFileLoc == null)
3146 newFileLoc = new StringBuffer();
3150 // look for next filename in load statement
3151 newFileLoc.append(state.substring(cp,
3152 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3153 String oldfilenam = state.substring(ncp,
3154 ecp = state.indexOf("\"", ncp));
3155 // recover the new mapping data for this old filename
3156 // have to normalize filename - since Jmol and jalview do
3158 // translation differently.
3159 Object[] filedat = oldFiles.get(new File(oldfilenam));
3160 newFileLoc.append(Platform
3161 .escapeString((String) filedat[0]));
3162 pdbfilenames.addElement((String) filedat[0]);
3163 pdbids.addElement((String) filedat[1]);
3164 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3165 .toArray(new SequenceI[0]));
3166 newFileLoc.append("\"");
3167 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3168 // look for next file statement.
3169 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3173 // just append rest of state
3174 newFileLoc.append(state.substring(cp));
3179 .print("Ignoring incomplete Jmol state for PDB ids: ");
3180 newFileLoc = new StringBuffer(state);
3181 newFileLoc.append("; load append ");
3182 for (File id : oldFiles.keySet())
3184 // add this and any other pdb files that should be present in
3186 Object[] filedat = oldFiles.get(id);
3188 newFileLoc.append(((String) filedat[0]));
3189 pdbfilenames.addElement((String) filedat[0]);
3190 pdbids.addElement((String) filedat[1]);
3191 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3192 .toArray(new SequenceI[0]));
3193 newFileLoc.append(" \"");
3194 newFileLoc.append((String) filedat[0]);
3195 newFileLoc.append("\"");
3198 newFileLoc.append(";");
3201 if (newFileLoc != null)
3203 int histbug = newFileLoc.indexOf("history = ");
3205 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3207 String val = (diff == -1) ? null : newFileLoc.substring(
3209 if (val != null && val.length() >= 4)
3211 if (val.contains("e"))
3213 if (val.trim().equals("true"))
3221 newFileLoc.replace(histbug, diff, val);
3224 // TODO: assemble String[] { pdb files }, String[] { id for each
3225 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3226 // seqs_file 2}} from hash
3227 final String[] pdbf = pdbfilenames
3228 .toArray(new String[pdbfilenames.size()]), id = pdbids
3229 .toArray(new String[pdbids.size()]);
3230 final SequenceI[][] sq = seqmaps
3231 .toArray(new SequenceI[seqmaps.size()][]);
3232 final String fileloc = newFileLoc.toString(), vid = sviewid;
3233 final AlignFrame alf = af;
3234 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3238 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3243 JalviewStructureDisplayI sview = null;
3246 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3247 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3248 useinJmolsuperpos, usetoColourbyseq,
3249 jmolColouring, fileloc, rect, vid);
3250 addNewStructureViewer(sview);
3251 } catch (OutOfMemoryError ex)
3253 new OOMWarning("restoring structure view for PDB id "
3254 + id, (OutOfMemoryError) ex.getCause());
3255 if (sview != null && sview.isVisible())
3257 sview.closeViewer();
3258 sview.setVisible(false);
3264 } catch (InvocationTargetException ex)
3266 warn("Unexpected error when opening Jmol view.", ex);
3268 } catch (InterruptedException e)
3270 // e.printStackTrace();
3276 // if (comp != null)
3278 // NOTE: if the jalview project is part of a shared session then
3279 // view synchronization should/could be done here.
3281 // add mapping for sequences in this view to an already open Jmol
3283 for (File id : oldFiles.keySet())
3285 // add this and any other pdb files that should be present in the
3287 Object[] filedat = oldFiles.get(id);
3288 String pdbFile = (String) filedat[0];
3289 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3290 .toArray(new SequenceI[0]);
3291 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3292 jalview.io.AppletFormatAdapter.FILE);
3293 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3295 // and add the AlignmentPanel's reference to the Jmol view
3296 comp.addAlignmentPanel(ap);
3297 if (useinJmolsuperpos)
3299 comp.useAlignmentPanelForSuperposition(ap);
3303 comp.excludeAlignmentPanelForSuperposition(ap);
3305 if (usetoColourbyseq)
3307 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3311 comp.excludeAlignmentPanelForColourbyseq(ap);
3317 // and finally return.
3324 * - minimum version we are comparing against
3326 * - version of data being processsed.
3327 * @return true if version is development/null or evaluates to the same or
3328 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3330 private boolean isVersionStringLaterThan(String supported, String version)
3332 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3333 || version.equalsIgnoreCase("Test")
3334 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3336 System.err.println("Assuming project file with "
3337 + (version == null ? "null" : version)
3338 + " is compatible with Jalview version " + supported);
3343 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3345 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3347 // convert b to decimal to catch bugfix releases within a series
3348 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3349 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3352 if (Float.valueOf(curT) > Float.valueOf(fileT))
3354 // current version is newer than the version that wrote the file
3357 } catch (NumberFormatException nfe)
3360 .println("** WARNING: Version comparison failed for tokens ("
3364 + ")\n** Current: '"
3365 + supported + "' and Version: '" + version + "'");
3368 if (currentV.hasMoreElements())
3370 // fileV has no minor version but identical series to current
3377 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3379 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3381 if (newStructureViewers != null)
3383 sview.getBinding().setFinishedLoadingFromArchive(false);
3384 newStructureViewers.add(sview);
3388 protected void setLoadingFinishedForNewStructureViewers()
3390 if (newStructureViewers != null)
3392 for (JalviewStructureDisplayI sview : newStructureViewers)
3394 sview.getBinding().setFinishedLoadingFromArchive(true);
3396 newStructureViewers.clear();
3397 newStructureViewers = null;
3401 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3402 Alignment al, JalviewModelSequence jms, Viewport view,
3403 String uniqueSeqSetId, String viewId,
3404 ArrayList<JvAnnotRow> autoAlan)
3406 AlignFrame af = null;
3407 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3408 uniqueSeqSetId, viewId);
3410 af.setFileName(file, "Jalview");
3412 for (int i = 0; i < JSEQ.length; i++)
3414 af.viewport.setSequenceColour(af.viewport.getAlignment()
3415 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3418 af.viewport.gatherViewsHere = view.getGatheredViews();
3420 if (view.getSequenceSetId() != null)
3422 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3423 .get(uniqueSeqSetId);
3425 af.viewport.setSequenceSetId(uniqueSeqSetId);
3428 // propagate shared settings to this new view
3429 af.viewport.historyList = av.historyList;
3430 af.viewport.redoList = av.redoList;
3434 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3436 // TODO: check if this method can be called repeatedly without
3437 // side-effects if alignpanel already registered.
3438 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3440 // apply Hidden regions to view.
3441 if (hiddenSeqs != null)
3443 for (int s = 0; s < JSEQ.length; s++)
3445 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3447 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3450 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3452 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3455 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3458 for (int s = 0; s < hiddenSeqs.size(); s++)
3460 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3463 af.viewport.hideSequence(hseqs);
3466 // recover view properties and display parameters
3467 if (view.getViewName() != null)
3469 af.viewport.viewName = view.getViewName();
3470 af.setInitialTabVisible();
3472 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3475 af.viewport.setShowAnnotation(view.getShowAnnotation());
3476 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3478 af.viewport.setColourText(view.getShowColourText());
3480 af.viewport.setConservationSelected(view.getConservationSelected());
3481 af.viewport.setShowJVSuffix(view.getShowFullId());
3482 af.viewport.setRightAlignIds(view.getRightAlignIds());
3483 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3484 .getFontStyle(), view.getFontSize()));
3485 af.alignPanel.fontChanged();
3486 af.viewport.setRenderGaps(view.getRenderGaps());
3487 af.viewport.setWrapAlignment(view.getWrapAlignment());
3488 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3489 af.viewport.setShowAnnotation(view.getShowAnnotation());
3490 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3492 af.viewport.setShowBoxes(view.getShowBoxes());
3494 af.viewport.setShowText(view.getShowText());
3496 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3497 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3498 af.viewport.thresholdTextColour = view.getTextColThreshold();
3499 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3500 .isShowUnconserved() : false);
3501 af.viewport.setStartRes(view.getStartRes());
3502 af.viewport.setStartSeq(view.getStartSeq());
3504 ColourSchemeI cs = null;
3505 // apply colourschemes
3506 if (view.getBgColour() != null)
3508 if (view.getBgColour().startsWith("ucs"))
3510 cs = GetUserColourScheme(jms, view.getBgColour());
3512 else if (view.getBgColour().startsWith("Annotation"))
3514 AnnotationColours viewAnnColour = view.getAnnotationColours();
3515 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3522 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3527 cs.setThreshold(view.getPidThreshold(), true);
3528 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3532 af.viewport.setGlobalColourScheme(cs);
3533 af.viewport.setColourAppliesToAllGroups(false);
3535 if (view.getConservationSelected() && cs != null)
3537 cs.setConservationInc(view.getConsThreshold());
3540 af.changeColour(cs);
3542 af.viewport.setColourAppliesToAllGroups(true);
3544 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
3546 if (view.hasCentreColumnLabels())
3548 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3550 if (view.hasIgnoreGapsinConsensus())
3552 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3555 if (view.hasFollowHighlight())
3557 af.viewport.followHighlight = view.getFollowHighlight();
3559 if (view.hasFollowSelection())
3561 af.viewport.followSelection = view.getFollowSelection();
3563 if (view.hasShowConsensusHistogram())
3565 af.viewport.setShowConsensusHistogram(view
3566 .getShowConsensusHistogram());
3570 af.viewport.setShowConsensusHistogram(true);
3572 if (view.hasShowSequenceLogo())
3574 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3578 af.viewport.setShowSequenceLogo(false);
3580 if (view.hasNormaliseSequenceLogo())
3582 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3584 if (view.hasShowDbRefTooltip())
3586 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3588 if (view.hasShowNPfeatureTooltip())
3590 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3592 if (view.hasShowGroupConsensus())
3594 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3598 af.viewport.setShowGroupConsensus(false);
3600 if (view.hasShowGroupConservation())
3602 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3606 af.viewport.setShowGroupConservation(false);
3609 // recover featre settings
3610 if (jms.getFeatureSettings() != null)
3612 FeaturesDisplayed fdi;
3613 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
3614 String[] renderOrder = new String[jms.getFeatureSettings()
3615 .getSettingCount()];
3616 Hashtable featureGroups = new Hashtable();
3617 Hashtable featureColours = new Hashtable();
3618 Hashtable featureOrder = new Hashtable();
3620 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3622 Setting setting = jms.getFeatureSettings().getSetting(fs);
3623 if (setting.hasMincolour())
3625 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3626 new java.awt.Color(setting.getMincolour()),
3627 new java.awt.Color(setting.getColour()),
3628 setting.getMin(), setting.getMax()) : new GraduatedColor(
3629 new java.awt.Color(setting.getMincolour()),
3630 new java.awt.Color(setting.getColour()), 0, 1);
3631 if (setting.hasThreshold())
3633 gc.setThresh(setting.getThreshold());
3634 gc.setThreshType(setting.getThreshstate());
3636 gc.setAutoScaled(true); // default
3637 if (setting.hasAutoScale())
3639 gc.setAutoScaled(setting.getAutoScale());
3641 if (setting.hasColourByLabel())
3643 gc.setColourByLabel(setting.getColourByLabel());
3645 // and put in the feature colour table.
3646 featureColours.put(setting.getType(), gc);
3650 featureColours.put(setting.getType(),
3651 new java.awt.Color(setting.getColour()));
3653 renderOrder[fs] = setting.getType();
3654 if (setting.hasOrder())
3656 featureOrder.put(setting.getType(), setting.getOrder());
3660 featureOrder.put(setting.getType(), new Float(fs
3661 / jms.getFeatureSettings().getSettingCount()));
3663 if (setting.getDisplay())
3665 fdi.setVisible(setting.getType());
3668 Hashtable fgtable = new Hashtable();
3669 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3671 Group grp = jms.getFeatureSettings().getGroup(gs);
3672 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3674 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
3675 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
3676 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
3677 FeatureRendererSettings frs = new FeatureRendererSettings(
3678 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
3679 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
3680 .transferSettings(frs);
3684 if (view.getHiddenColumnsCount() > 0)
3686 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3688 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3689 .getHiddenColumns(c).getEnd() // +1
3693 if (view.getCalcIdParam() != null)
3695 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3697 if (calcIdParam != null)
3699 if (recoverCalcIdParam(calcIdParam, af.viewport))
3704 warn("Couldn't recover parameters for "
3705 + calcIdParam.getCalcId());
3710 af.setMenusFromViewport(af.viewport);
3711 // TODO: we don't need to do this if the viewport is aready visible.
3712 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3714 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3715 reorderAutoannotation(af, al, autoAlan);
3716 af.alignPanel.alignmentChanged();
3720 private ColourSchemeI constructAnnotationColour(
3721 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3722 JalviewModelSequence jms, boolean checkGroupAnnColour)
3724 boolean propagateAnnColour = false;
3725 ColourSchemeI cs = null;
3726 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3727 if (checkGroupAnnColour && al.getGroups() != null
3728 && al.getGroups().size() > 0)
3730 // pre 2.8.1 behaviour
3731 // check to see if we should transfer annotation colours
3732 propagateAnnColour = true;
3733 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3735 if (sg.cs instanceof AnnotationColourGradient)
3737 propagateAnnColour = false;
3741 // int find annotation
3742 if (annAlignment.getAlignmentAnnotation() != null)
3744 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3746 if (annAlignment.getAlignmentAnnotation()[i].label
3747 .equals(viewAnnColour.getAnnotation()))
3749 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3751 annAlignment.getAlignmentAnnotation()[i]
3752 .setThreshold(new jalview.datamodel.GraphLine(
3753 viewAnnColour.getThreshold(), "Threshold",
3754 java.awt.Color.black)
3759 if (viewAnnColour.getColourScheme().equals("None"))
3761 cs = new AnnotationColourGradient(
3762 annAlignment.getAlignmentAnnotation()[i],
3763 new java.awt.Color(viewAnnColour.getMinColour()),
3764 new java.awt.Color(viewAnnColour.getMaxColour()),
3765 viewAnnColour.getAboveThreshold());
3767 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3769 cs = new AnnotationColourGradient(
3770 annAlignment.getAlignmentAnnotation()[i],
3771 GetUserColourScheme(jms,
3772 viewAnnColour.getColourScheme()),
3773 viewAnnColour.getAboveThreshold());
3777 cs = new AnnotationColourGradient(
3778 annAlignment.getAlignmentAnnotation()[i],
3779 ColourSchemeProperty.getColour(al,
3780 viewAnnColour.getColourScheme()),
3781 viewAnnColour.getAboveThreshold());
3783 if (viewAnnColour.hasPerSequence())
3785 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3788 if (viewAnnColour.hasPredefinedColours())
3790 ((AnnotationColourGradient) cs)
3791 .setPredefinedColours(viewAnnColour
3792 .isPredefinedColours());
3794 if (propagateAnnColour && al.getGroups() != null)
3796 // Also use these settings for all the groups
3797 for (int g = 0; g < al.getGroups().size(); g++)
3799 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3807 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3808 * new AnnotationColourGradient(
3809 * annAlignment.getAlignmentAnnotation()[i], new
3810 * java.awt.Color(viewAnnColour. getMinColour()), new
3811 * java.awt.Color(viewAnnColour. getMaxColour()),
3812 * viewAnnColour.getAboveThreshold()); } else
3815 sg.cs = new AnnotationColourGradient(
3816 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3817 viewAnnColour.getAboveThreshold());
3818 if (cs instanceof AnnotationColourGradient)
3820 if (viewAnnColour.hasPerSequence())
3822 ((AnnotationColourGradient) cs)
3823 .setSeqAssociated(viewAnnColour.isPerSequence());
3825 if (viewAnnColour.hasPredefinedColours())
3827 ((AnnotationColourGradient) cs)
3828 .setPredefinedColours(viewAnnColour
3829 .isPredefinedColours());
3845 private void reorderAutoannotation(AlignFrame af, Alignment al,
3846 ArrayList<JvAnnotRow> autoAlan)
3848 // copy over visualization settings for autocalculated annotation in the
3850 if (al.getAlignmentAnnotation() != null)
3853 * Kludge for magic autoannotation names (see JAL-811)
3855 String[] magicNames = new String[]
3856 { "Consensus", "Quality", "Conservation" };
3857 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3858 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3859 for (String nm : magicNames)
3861 visan.put(nm, nullAnnot);
3863 for (JvAnnotRow auan : autoAlan)
3865 visan.put(auan.template.label
3866 + (auan.template.getCalcId() == null ? "" : "\t"
3867 + auan.template.getCalcId()), auan);
3869 int hSize = al.getAlignmentAnnotation().length;
3870 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3871 // work through any autoCalculated annotation already on the view
3872 // removing it if it should be placed in a different location on the
3873 // annotation panel.
3874 List<String> remains = new ArrayList(visan.keySet());
3875 for (int h = 0; h < hSize; h++)
3877 jalview.datamodel.AlignmentAnnotation jalan = al
3878 .getAlignmentAnnotation()[h];
3879 if (jalan.autoCalculated)
3882 JvAnnotRow valan = visan.get(k = jalan.label);
3883 if (jalan.getCalcId() != null)
3885 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3890 // delete the auto calculated row from the alignment
3891 al.deleteAnnotation(jalan, false);
3895 if (valan != nullAnnot)
3897 if (jalan != valan.template)
3899 // newly created autoannotation row instance
3900 // so keep a reference to the visible annotation row
3901 // and copy over all relevant attributes
3902 if (valan.template.graphHeight >= 0)
3905 jalan.graphHeight = valan.template.graphHeight;
3907 jalan.visible = valan.template.visible;
3909 reorder.add(new JvAnnotRow(valan.order, jalan));
3914 // Add any (possibly stale) autocalculated rows that were not appended to
3915 // the view during construction
3916 for (String other : remains)
3918 JvAnnotRow othera = visan.get(other);
3919 if (othera != nullAnnot && othera.template.getCalcId() != null
3920 && othera.template.getCalcId().length() > 0)
3922 reorder.add(othera);
3925 // now put the automatic annotation in its correct place
3926 int s = 0, srt[] = new int[reorder.size()];
3927 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3928 for (JvAnnotRow jvar : reorder)
3931 srt[s++] = jvar.order;
3934 jalview.util.QuickSort.sort(srt, rws);
3935 // and re-insert the annotation at its correct position
3936 for (JvAnnotRow jvar : rws)
3938 al.addAnnotation(jvar.template, jvar.order);
3940 af.alignPanel.adjustAnnotationHeight();
3944 Hashtable skipList = null;
3947 * TODO remove this method
3950 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3951 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3952 * throw new Error("Implementation Error. No skipList defined for this
3953 * Jalview2XML instance."); } return (AlignFrame)
3954 * skipList.get(view.getSequenceSetId()); }
3958 * Check if the Jalview view contained in object should be skipped or not.
3961 * @return true if view's sequenceSetId is a key in skipList
3963 private boolean skipViewport(JalviewModel object)
3965 if (skipList == null)
3970 if (skipList.containsKey(id = object.getJalviewModelSequence()
3971 .getViewport()[0].getSequenceSetId()))
3973 if (Cache.log != null && Cache.log.isDebugEnabled())
3975 Cache.log.debug("Skipping seuqence set id " + id);
3982 public void AddToSkipList(AlignFrame af)
3984 if (skipList == null)
3986 skipList = new Hashtable();
3988 skipList.put(af.getViewport().getSequenceSetId(), af);
3991 public void clearSkipList()
3993 if (skipList != null)
4000 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4001 boolean ignoreUnrefed)
4003 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4004 Vector dseqs = null;
4007 // create a list of new dataset sequences
4008 dseqs = new Vector();
4010 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4012 Sequence vamsasSeq = vamsasSet.getSequence(i);
4013 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4015 // create a new dataset
4018 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4019 dseqs.copyInto(dsseqs);
4020 ds = new jalview.datamodel.Alignment(dsseqs);
4021 debug("Created new dataset " + vamsasSet.getDatasetId()
4022 + " for alignment " + System.identityHashCode(al));
4023 addDatasetRef(vamsasSet.getDatasetId(), ds);
4025 // set the dataset for the newly imported alignment.
4026 if (al.getDataset() == null && !ignoreUnrefed)
4035 * sequence definition to create/merge dataset sequence for
4039 * vector to add new dataset sequence to
4041 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4042 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4044 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4046 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4047 .get(vamsasSeq.getId());
4048 jalview.datamodel.SequenceI dsq = null;
4049 if (sq != null && sq.getDatasetSequence() != null)
4051 dsq = sq.getDatasetSequence();
4053 if (sq == null && ignoreUnrefed)
4057 String sqid = vamsasSeq.getDsseqid();
4060 // need to create or add a new dataset sequence reference to this sequence
4063 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4068 // make a new dataset sequence
4069 dsq = sq.createDatasetSequence();
4072 // make up a new dataset reference for this sequence
4073 sqid = seqHash(dsq);
4075 dsq.setVamsasId(uniqueSetSuffix + sqid);
4076 seqRefIds.put(sqid, dsq);
4081 dseqs.addElement(dsq);
4086 ds.addSequence(dsq);
4092 { // make this dataset sequence sq's dataset sequence
4093 sq.setDatasetSequence(dsq);
4094 // and update the current dataset alignment
4099 if (!dseqs.contains(dsq))
4106 if (ds.findIndex(dsq) < 0)
4108 ds.addSequence(dsq);
4115 // TODO: refactor this as a merge dataset sequence function
4116 // now check that sq (the dataset sequence) sequence really is the union of
4117 // all references to it
4118 // boolean pre = sq.getStart() < dsq.getStart();
4119 // boolean post = sq.getEnd() > dsq.getEnd();
4123 StringBuffer sb = new StringBuffer();
4124 String newres = jalview.analysis.AlignSeq.extractGaps(
4125 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4126 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4127 && newres.length() > dsq.getLength())
4129 // Update with the longer sequence.
4133 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4134 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4135 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4136 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4138 dsq.setSequence(newres);
4140 // TODO: merges will never happen if we 'know' we have the real dataset
4141 // sequence - this should be detected when id==dssid
4143 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4144 // + (pre ? "prepended" : "") + " "
4145 // + (post ? "appended" : ""));
4150 java.util.Hashtable datasetIds = null;
4152 java.util.IdentityHashMap dataset2Ids = null;
4154 private Alignment getDatasetFor(String datasetId)
4156 if (datasetIds == null)
4158 datasetIds = new Hashtable();
4161 if (datasetIds.containsKey(datasetId))
4163 return (Alignment) datasetIds.get(datasetId);
4168 private void addDatasetRef(String datasetId, Alignment dataset)
4170 if (datasetIds == null)
4172 datasetIds = new Hashtable();
4174 datasetIds.put(datasetId, dataset);
4178 * make a new dataset ID for this jalview dataset alignment
4183 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4185 if (dataset.getDataset() != null)
4187 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4189 String datasetId = makeHashCode(dataset, null);
4190 if (datasetId == null)
4192 // make a new datasetId and record it
4193 if (dataset2Ids == null)
4195 dataset2Ids = new IdentityHashMap();
4199 datasetId = (String) dataset2Ids.get(dataset);
4201 if (datasetId == null)
4203 datasetId = "ds" + dataset2Ids.size() + 1;
4204 dataset2Ids.put(dataset, datasetId);
4210 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4212 for (int d = 0; d < sequence.getDBRefCount(); d++)
4214 DBRef dr = sequence.getDBRef(d);
4215 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4216 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4217 .getVersion(), sequence.getDBRef(d).getAccessionId());
4218 if (dr.getMapping() != null)
4220 entry.setMap(addMapping(dr.getMapping()));
4222 datasetSequence.addDBRef(entry);
4226 private jalview.datamodel.Mapping addMapping(Mapping m)
4228 SequenceI dsto = null;
4229 // Mapping m = dr.getMapping();
4230 int fr[] = new int[m.getMapListFromCount() * 2];
4231 Enumeration f = m.enumerateMapListFrom();
4232 for (int _i = 0; f.hasMoreElements(); _i += 2)
4234 MapListFrom mf = (MapListFrom) f.nextElement();
4235 fr[_i] = mf.getStart();
4236 fr[_i + 1] = mf.getEnd();
4238 int fto[] = new int[m.getMapListToCount() * 2];
4239 f = m.enumerateMapListTo();
4240 for (int _i = 0; f.hasMoreElements(); _i += 2)
4242 MapListTo mf = (MapListTo) f.nextElement();
4243 fto[_i] = mf.getStart();
4244 fto[_i + 1] = mf.getEnd();
4246 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4247 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4248 if (m.getMappingChoice() != null)
4250 MappingChoice mc = m.getMappingChoice();
4251 if (mc.getDseqFor() != null)
4253 String dsfor = "" + mc.getDseqFor();
4254 if (seqRefIds.containsKey(dsfor))
4259 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4263 frefedSequence.add(new Object[]
4270 * local sequence definition
4272 Sequence ms = mc.getSequence();
4273 jalview.datamodel.Sequence djs = null;
4274 String sqid = ms.getDsseqid();
4275 if (sqid != null && sqid.length() > 0)
4278 * recover dataset sequence
4280 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4285 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4286 sqid = ((Object) ms).toString(); // make up a new hascode for
4287 // undefined dataset sequence hash
4288 // (unlikely to happen)
4294 * make a new dataset sequence and add it to refIds hash
4296 djs = new jalview.datamodel.Sequence(ms.getName(),
4298 djs.setStart(jmap.getMap().getToLowest());
4299 djs.setEnd(jmap.getMap().getToHighest());
4300 djs.setVamsasId(uniqueSetSuffix + sqid);
4302 seqRefIds.put(sqid, djs);
4305 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4314 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4315 boolean keepSeqRefs)
4318 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4324 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4328 uniqueSetSuffix = "";
4329 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4334 if (this.frefedSequence == null)
4336 frefedSequence = new Vector();
4339 viewportsAdded = new Hashtable();
4341 AlignFrame af = LoadFromObject(jm, null, false, null);
4342 af.alignPanels.clear();
4343 af.closeMenuItem_actionPerformed(true);
4346 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4347 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4348 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4349 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4350 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4353 return af.alignPanel;
4357 * flag indicating if hashtables should be cleared on finalization TODO this
4358 * flag may not be necessary
4360 private final boolean _cleartables = true;
4362 private Hashtable jvids2vobj;
4367 * @see java.lang.Object#finalize()
4370 protected void finalize() throws Throwable
4372 // really make sure we have no buried refs left.
4377 this.seqRefIds = null;
4378 this.seqsToIds = null;
4382 private void warn(String msg)
4387 private void warn(String msg, Exception e)
4389 if (Cache.log != null)
4393 Cache.log.warn(msg, e);
4397 Cache.log.warn(msg);
4402 System.err.println("Warning: " + msg);
4405 e.printStackTrace();
4410 private void debug(String string)
4412 debug(string, null);
4415 private void debug(String msg, Exception e)
4417 if (Cache.log != null)
4421 Cache.log.debug(msg, e);
4425 Cache.log.debug(msg);
4430 System.err.println("Warning: " + msg);
4433 e.printStackTrace();
4439 * set the object to ID mapping tables used to write/recover objects and XML
4440 * ID strings for the jalview project. If external tables are provided then
4441 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4442 * object goes out of scope. - also populates the datasetIds hashtable with
4443 * alignment objects containing dataset sequences
4446 * Map from ID strings to jalview datamodel
4448 * Map from jalview datamodel to ID strings
4452 public void setObjectMappingTables(Hashtable vobj2jv,
4453 IdentityHashMap jv2vobj)
4455 this.jv2vobj = jv2vobj;
4456 this.vobj2jv = vobj2jv;
4457 Iterator ds = jv2vobj.keySet().iterator();
4459 while (ds.hasNext())
4461 Object jvobj = ds.next();
4462 id = jv2vobj.get(jvobj).toString();
4463 if (jvobj instanceof jalview.datamodel.Alignment)
4465 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4467 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4470 else if (jvobj instanceof jalview.datamodel.Sequence)
4472 // register sequence object so the XML parser can recover it.
4473 if (seqRefIds == null)
4475 seqRefIds = new Hashtable();
4477 if (seqsToIds == null)
4479 seqsToIds = new IdentityHashMap();
4481 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4482 seqsToIds.put(jvobj, id);
4484 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4486 if (annotationIds == null)
4488 annotationIds = new Hashtable();
4491 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4492 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4493 if (jvann.annotationId == null)
4495 jvann.annotationId = anid;
4497 if (!jvann.annotationId.equals(anid))
4499 // TODO verify that this is the correct behaviour
4500 this.warn("Overriding Annotation ID for " + anid
4501 + " from different id : " + jvann.annotationId);
4502 jvann.annotationId = anid;
4505 else if (jvobj instanceof String)
4507 if (jvids2vobj == null)
4509 jvids2vobj = new Hashtable();
4510 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4515 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4521 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4522 * objects created from the project archive. If string is null (default for
4523 * construction) then suffix will be set automatically.
4527 public void setUniqueSetSuffix(String string)
4529 uniqueSetSuffix = string;
4534 * uses skipList2 as the skipList for skipping views on sequence sets
4535 * associated with keys in the skipList
4539 public void setSkipList(Hashtable skipList2)
4541 skipList = skipList2;