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 = MessageManager.formatMessage("label.dataset_for", new String[]{fileName,_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.rightAlignIds);
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.seqPanel.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.seqPanel.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.seqPanel.seqCanvas.getFeatureRenderer()
1183 .getColour(renderOrder[ro]).getRGB());
1186 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1188 float rorder = ap.seqPanel.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.seqPanel.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.seqPanel.seqCanvas.getFeatureRenderer()
1213 .getColour(key).getRGB());
1215 setting.setDisplay(false);
1216 float rorder = ap.seqPanel.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.seqPanel.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.seqPanel.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 != ' '
1465 && aa[i].annotations[a].secondaryStructure != '\0')
1467 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1471 if (aa[i].annotations[a].colour != null
1472 && aa[i].annotations[a].colour != java.awt.Color.black)
1474 ae.setColour(aa[i].annotations[a].colour.getRGB());
1477 an.addAnnotationElement(ae);
1478 if (aa[i].autoCalculated)
1480 // only write one non-null entry into the annotation row -
1481 // sufficient to get the visualization attributes necessary to
1489 an.setScoreOnly(true);
1491 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1493 // skip autocalculated annotation - these are only provided for
1495 vamsasSet.addAnnotation(an);
1501 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1503 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1504 if (settings != null)
1506 CalcIdParam vCalcIdParam = new CalcIdParam();
1507 vCalcIdParam.setCalcId(calcId);
1508 vCalcIdParam.addServiceURL(settings.getServiceURI());
1509 // generic URI allowing a third party to resolve another instance of the
1510 // service used for this calculation
1511 for (String urls : settings.getServiceURLs())
1513 vCalcIdParam.addServiceURL(urls);
1515 vCalcIdParam.setVersion("1.0");
1516 if (settings.getPreset() != null)
1518 WsParamSetI setting = settings.getPreset();
1519 vCalcIdParam.setName(setting.getName());
1520 vCalcIdParam.setDescription(setting.getDescription());
1524 vCalcIdParam.setName("");
1525 vCalcIdParam.setDescription("Last used parameters");
1527 // need to be able to recover 1) settings 2) user-defined presets or
1528 // recreate settings from preset 3) predefined settings provided by
1529 // service - or settings that can be transferred (or discarded)
1530 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1532 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1533 // todo - decide if updateImmediately is needed for any projects.
1535 return vCalcIdParam;
1540 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1543 if (calcIdParam.getVersion().equals("1.0"))
1545 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1546 .getPreferredServiceFor(calcIdParam.getServiceURL());
1547 if (service != null)
1549 WsParamSetI parmSet = null;
1552 parmSet = service.getParamStore().parseServiceParameterFile(
1553 calcIdParam.getName(), calcIdParam.getDescription(),
1554 calcIdParam.getServiceURL(),
1555 calcIdParam.getParameters().replace("|\\n|", "\n"));
1556 } catch (IOException x)
1558 warn("Couldn't parse parameter data for "
1559 + calcIdParam.getCalcId(), x);
1562 List<ArgumentI> argList = null;
1563 if (calcIdParam.getName().length() > 0)
1565 parmSet = service.getParamStore()
1566 .getPreset(calcIdParam.getName());
1567 if (parmSet != null)
1569 // TODO : check we have a good match with settings in AACon -
1570 // otherwise we'll need to create a new preset
1575 argList = parmSet.getArguments();
1578 AAConSettings settings = new AAConSettings(
1579 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1580 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1581 calcIdParam.isNeedsUpdate());
1586 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1590 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1594 * External mapping between jalview objects and objects yielding a valid and
1595 * unique object ID string. This is null for normal Jalview project IO, but
1596 * non-null when a jalview project is being read or written as part of a
1599 IdentityHashMap jv2vobj = null;
1602 * Construct a unique ID for jvobj using either existing bindings or if none
1603 * exist, the result of the hashcode call for the object.
1606 * jalview data object
1607 * @return unique ID for referring to jvobj
1609 private String makeHashCode(Object jvobj, String altCode)
1611 if (jv2vobj != null)
1613 Object id = jv2vobj.get(jvobj);
1616 return id.toString();
1618 // check string ID mappings
1619 if (jvids2vobj != null && jvobj instanceof String)
1621 id = jvids2vobj.get(jvobj);
1625 return id.toString();
1627 // give up and warn that something has gone wrong
1628 warn("Cannot find ID for object in external mapping : " + jvobj);
1634 * return local jalview object mapped to ID, if it exists
1638 * @return null or object bound to idcode
1640 private Object retrieveExistingObj(String idcode)
1642 if (idcode != null && vobj2jv != null)
1644 return vobj2jv.get(idcode);
1650 * binding from ID strings from external mapping table to jalview data model
1653 private Hashtable vobj2jv;
1655 private Sequence createVamsasSequence(String id, SequenceI jds)
1657 return createVamsasSequence(true, id, jds, null);
1660 private Sequence createVamsasSequence(boolean recurse, String id,
1661 SequenceI jds, SequenceI parentseq)
1663 Sequence vamsasSeq = new Sequence();
1664 vamsasSeq.setId(id);
1665 vamsasSeq.setName(jds.getName());
1666 vamsasSeq.setSequence(jds.getSequenceAsString());
1667 vamsasSeq.setDescription(jds.getDescription());
1668 jalview.datamodel.DBRefEntry[] dbrefs = null;
1669 if (jds.getDatasetSequence() != null)
1671 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1672 if (jds.getDatasetSequence().getDBRef() != null)
1674 dbrefs = jds.getDatasetSequence().getDBRef();
1679 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1680 // dataset sequences only
1681 dbrefs = jds.getDBRef();
1685 for (int d = 0; d < dbrefs.length; d++)
1687 DBRef dbref = new DBRef();
1688 dbref.setSource(dbrefs[d].getSource());
1689 dbref.setVersion(dbrefs[d].getVersion());
1690 dbref.setAccessionId(dbrefs[d].getAccessionId());
1691 if (dbrefs[d].hasMap())
1693 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1695 dbref.setMapping(mp);
1697 vamsasSeq.addDBRef(dbref);
1703 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1704 SequenceI parentseq, SequenceI jds, boolean recurse)
1707 if (jmp.getMap() != null)
1711 jalview.util.MapList mlst = jmp.getMap();
1712 int r[] = mlst.getFromRanges();
1713 for (int s = 0; s < r.length; s += 2)
1715 MapListFrom mfrom = new MapListFrom();
1716 mfrom.setStart(r[s]);
1717 mfrom.setEnd(r[s + 1]);
1718 mp.addMapListFrom(mfrom);
1720 r = mlst.getToRanges();
1721 for (int s = 0; s < r.length; s += 2)
1723 MapListTo mto = new MapListTo();
1725 mto.setEnd(r[s + 1]);
1726 mp.addMapListTo(mto);
1728 mp.setMapFromUnit(mlst.getFromRatio());
1729 mp.setMapToUnit(mlst.getToRatio());
1730 if (jmp.getTo() != null)
1732 MappingChoice mpc = new MappingChoice();
1734 && (parentseq != jmp.getTo() || parentseq
1735 .getDatasetSequence() != jmp.getTo()))
1737 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1743 SequenceI ps = null;
1744 if (parentseq != jmp.getTo()
1745 && parentseq.getDatasetSequence() != jmp.getTo())
1747 // chaining dbref rather than a handshaking one
1748 jmpid = seqHash(ps = jmp.getTo());
1752 jmpid = seqHash(ps = parentseq);
1754 mpc.setDseqFor(jmpid);
1755 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1757 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1758 seqRefIds.put(mpc.getDseqFor(), ps);
1762 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1765 mp.setMappingChoice(mpc);
1771 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1772 Vector userColours, JalviewModelSequence jms)
1775 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1776 boolean newucs = false;
1777 if (!userColours.contains(ucs))
1779 userColours.add(ucs);
1782 id = "ucs" + userColours.indexOf(ucs);
1785 // actually create the scheme's entry in the XML model
1786 java.awt.Color[] colours = ucs.getColours();
1787 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1788 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1790 for (int i = 0; i < colours.length; i++)
1792 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1793 col.setName(ResidueProperties.aa[i]);
1794 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1795 jbucs.addColour(col);
1797 if (ucs.getLowerCaseColours() != null)
1799 colours = ucs.getLowerCaseColours();
1800 for (int i = 0; i < colours.length; i++)
1802 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1803 col.setName(ResidueProperties.aa[i].toLowerCase());
1804 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1805 jbucs.addColour(col);
1810 uc.setUserColourScheme(jbucs);
1811 jms.addUserColours(uc);
1817 jalview.schemes.UserColourScheme GetUserColourScheme(
1818 JalviewModelSequence jms, String id)
1820 UserColours[] uc = jms.getUserColours();
1821 UserColours colours = null;
1823 for (int i = 0; i < uc.length; i++)
1825 if (uc[i].getId().equals(id))
1833 java.awt.Color[] newColours = new java.awt.Color[24];
1835 for (int i = 0; i < 24; i++)
1837 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1838 .getUserColourScheme().getColour(i).getRGB(), 16));
1841 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1844 if (colours.getUserColourScheme().getColourCount() > 24)
1846 newColours = new java.awt.Color[23];
1847 for (int i = 0; i < 23; i++)
1849 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1850 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1852 ucs.setLowerCaseColours(newColours);
1859 * contains last error message (if any) encountered by XML loader.
1861 String errorMessage = null;
1864 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1865 * exceptions are raised during project XML parsing
1867 public boolean attemptversion1parse = true;
1870 * Load a jalview project archive from a jar file
1873 * - HTTP URL or filename
1875 public AlignFrame LoadJalviewAlign(final String file)
1878 jalview.gui.AlignFrame af = null;
1882 // create list to store references for any new Jmol viewers created
1883 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1884 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1885 // Workaround is to make sure caller implements the JarInputStreamProvider
1887 // so we can re-open the jar input stream for each entry.
1889 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1890 af = LoadJalviewAlign(jprovider);
1892 } catch (MalformedURLException e)
1894 errorMessage = "Invalid URL format for '" + file + "'";
1900 SwingUtilities.invokeAndWait(new Runnable()
1904 setLoadingFinishedForNewStructureViewers();
1907 } catch (Exception x)
1915 private jarInputStreamProvider createjarInputStreamProvider(
1916 final String file) throws MalformedURLException
1919 errorMessage = null;
1920 uniqueSetSuffix = null;
1922 viewportsAdded = null;
1923 frefedSequence = null;
1925 if (file.startsWith("http://"))
1927 url = new URL(file);
1929 final URL _url = url;
1930 return new jarInputStreamProvider()
1934 public JarInputStream getJarInputStream() throws IOException
1938 return new JarInputStream(_url.openStream());
1942 return new JarInputStream(new FileInputStream(file));
1947 public String getFilename()
1955 * Recover jalview session from a jalview project archive. Caller may
1956 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1957 * themselves. Any null fields will be initialised with default values,
1958 * non-null fields are left alone.
1963 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1965 errorMessage = null;
1966 if (uniqueSetSuffix == null)
1968 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1970 if (seqRefIds == null)
1972 seqRefIds = new Hashtable();
1974 if (viewportsAdded == null)
1976 viewportsAdded = new Hashtable();
1978 if (frefedSequence == null)
1980 frefedSequence = new Vector();
1983 jalview.gui.AlignFrame af = null, _af = null;
1984 Hashtable gatherToThisFrame = new Hashtable();
1985 final String file = jprovider.getFilename();
1988 JarInputStream jin = null;
1989 JarEntry jarentry = null;
1994 jin = jprovider.getJarInputStream();
1995 for (int i = 0; i < entryCount; i++)
1997 jarentry = jin.getNextJarEntry();
2000 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2002 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2003 JalviewModel object = new JalviewModel();
2005 Unmarshaller unmar = new Unmarshaller(object);
2006 unmar.setValidation(false);
2007 object = (JalviewModel) unmar.unmarshal(in);
2008 if (true) // !skipViewport(object))
2010 _af = LoadFromObject(object, file, true, jprovider);
2011 if (object.getJalviewModelSequence().getViewportCount() > 0)
2014 if (af.viewport.gatherViewsHere)
2016 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2022 else if (jarentry != null)
2024 // Some other file here.
2027 } while (jarentry != null);
2028 resolveFrefedSequences();
2029 } catch (java.io.FileNotFoundException ex)
2031 ex.printStackTrace();
2032 errorMessage = "Couldn't locate Jalview XML file : " + file;
2033 System.err.println("Exception whilst loading jalview XML file : "
2035 } catch (java.net.UnknownHostException ex)
2037 ex.printStackTrace();
2038 errorMessage = "Couldn't locate Jalview XML file : " + file;
2039 System.err.println("Exception whilst loading jalview XML file : "
2041 } catch (Exception ex)
2043 System.err.println("Parsing as Jalview Version 2 file failed.");
2044 ex.printStackTrace(System.err);
2045 if (attemptversion1parse)
2047 // Is Version 1 Jar file?
2050 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2051 } catch (Exception ex2)
2053 System.err.println("Exception whilst loading as jalviewXMLV1:");
2054 ex2.printStackTrace();
2058 if (Desktop.instance != null)
2060 Desktop.instance.stopLoading();
2064 System.out.println("Successfully loaded archive file");
2067 ex.printStackTrace();
2069 System.err.println("Exception whilst loading jalview XML file : "
2071 } catch (OutOfMemoryError e)
2073 // Don't use the OOM Window here
2074 errorMessage = "Out of memory loading jalview XML file";
2075 System.err.println("Out of memory whilst loading jalview XML file");
2076 e.printStackTrace();
2079 if (Desktop.instance != null)
2081 Desktop.instance.stopLoading();
2084 Enumeration en = gatherToThisFrame.elements();
2085 while (en.hasMoreElements())
2087 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2089 if (errorMessage != null)
2097 * check errorMessage for a valid error message and raise an error box in the
2098 * GUI or write the current errorMessage to stderr and then clear the error
2101 protected void reportErrors()
2103 reportErrors(false);
2106 protected void reportErrors(final boolean saving)
2108 if (errorMessage != null)
2110 final String finalErrorMessage = errorMessage;
2113 javax.swing.SwingUtilities.invokeLater(new Runnable()
2118 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2119 finalErrorMessage, "Error "
2120 + (saving ? "saving" : "loading")
2121 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2127 System.err.println("Problem loading Jalview file: " + errorMessage);
2130 errorMessage = null;
2133 Hashtable<String, String> alreadyLoadedPDB;
2136 * when set, local views will be updated from view stored in JalviewXML
2137 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2138 * sync if this is set to true.
2140 private final boolean updateLocalViews = false;
2142 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2144 if (alreadyLoadedPDB == null)
2146 alreadyLoadedPDB = new Hashtable();
2149 if (alreadyLoadedPDB.containsKey(pdbId))
2151 return alreadyLoadedPDB.get(pdbId).toString();
2156 JarInputStream jin = jprovider.getJarInputStream();
2158 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2159 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2160 * FileInputStream(jprovider)); }
2163 JarEntry entry = null;
2166 entry = jin.getNextJarEntry();
2167 } while (entry != null && !entry.getName().equals(pdbId));
2170 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2171 File outFile = File.createTempFile("jalview_pdb", ".txt");
2172 outFile.deleteOnExit();
2173 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2176 while ((data = in.readLine()) != null)
2183 } catch (Exception foo)
2188 String t = outFile.getAbsolutePath();
2189 alreadyLoadedPDB.put(pdbId, t);
2194 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2196 } catch (Exception ex)
2198 ex.printStackTrace();
2204 private class JvAnnotRow
2206 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2213 * persisted version of annotation row from which to take vis properties
2215 public jalview.datamodel.AlignmentAnnotation template;
2218 * original position of the annotation row in the alignment
2224 * Load alignment frame from jalview XML DOM object
2229 * filename source string
2230 * @param loadTreesAndStructures
2231 * when false only create Viewport
2233 * data source provider
2234 * @return alignment frame created from view stored in DOM
2236 AlignFrame LoadFromObject(JalviewModel object, String file,
2237 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2239 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2240 Sequence[] vamsasSeq = vamsasSet.getSequence();
2242 JalviewModelSequence jms = object.getJalviewModelSequence();
2244 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2247 // ////////////////////////////////
2250 Vector hiddenSeqs = null;
2251 jalview.datamodel.Sequence jseq;
2253 ArrayList tmpseqs = new ArrayList();
2255 boolean multipleView = false;
2257 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2258 int vi = 0; // counter in vamsasSeq array
2259 for (int i = 0; i < JSEQ.length; i++)
2261 String seqId = JSEQ[i].getId();
2263 if (seqRefIds.get(seqId) != null)
2265 tmpseqs.add(seqRefIds.get(seqId));
2266 multipleView = true;
2270 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2271 vamsasSeq[vi].getSequence());
2272 jseq.setDescription(vamsasSeq[vi].getDescription());
2273 jseq.setStart(JSEQ[i].getStart());
2274 jseq.setEnd(JSEQ[i].getEnd());
2275 jseq.setVamsasId(uniqueSetSuffix + seqId);
2276 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2281 if (JSEQ[i].getHidden())
2283 if (hiddenSeqs == null)
2285 hiddenSeqs = new Vector();
2288 hiddenSeqs.addElement(seqRefIds.get(seqId));
2294 // Create the alignment object from the sequence set
2295 // ///////////////////////////////
2296 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2299 tmpseqs.toArray(orderedSeqs);
2301 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2304 // / Add the alignment properties
2305 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2307 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2308 al.setProperty(ssp.getKey(), ssp.getValue());
2312 // SequenceFeatures are added to the DatasetSequence,
2313 // so we must create or recover the dataset before loading features
2314 // ///////////////////////////////
2315 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2317 // older jalview projects do not have a dataset id.
2318 al.setDataset(null);
2322 recoverDatasetFor(vamsasSet, al);
2324 // ///////////////////////////////
2326 Hashtable pdbloaded = new Hashtable();
2329 // load sequence features, database references and any associated PDB
2330 // structures for the alignment
2331 for (int i = 0; i < vamsasSeq.length; i++)
2333 if (JSEQ[i].getFeaturesCount() > 0)
2335 Features[] features = JSEQ[i].getFeatures();
2336 for (int f = 0; f < features.length; f++)
2338 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2339 features[f].getType(), features[f].getDescription(),
2340 features[f].getStatus(), features[f].getBegin(),
2341 features[f].getEnd(), features[f].getFeatureGroup());
2343 sf.setScore(features[f].getScore());
2344 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2346 OtherData keyValue = features[f].getOtherData(od);
2347 if (keyValue.getKey().startsWith("LINK"))
2349 sf.addLink(keyValue.getValue());
2353 sf.setValue(keyValue.getKey(), keyValue.getValue());
2358 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2361 if (vamsasSeq[i].getDBRefCount() > 0)
2363 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2365 if (JSEQ[i].getPdbidsCount() > 0)
2367 Pdbids[] ids = JSEQ[i].getPdbids();
2368 for (int p = 0; p < ids.length; p++)
2370 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2371 entry.setId(ids[p].getId());
2372 entry.setType(ids[p].getType());
2373 if (ids[p].getFile() != null)
2375 if (!pdbloaded.containsKey(ids[p].getFile()))
2377 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2381 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2384 StructureSelectionManager.getStructureSelectionManager(
2386 .registerPDBEntry(entry);
2387 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2391 } // end !multipleview
2393 // ///////////////////////////////
2394 // LOAD SEQUENCE MAPPINGS
2396 if (vamsasSet.getAlcodonFrameCount() > 0)
2398 // TODO Potentially this should only be done once for all views of an
2400 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2401 for (int i = 0; i < alc.length; i++)
2403 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2404 alc[i].getAlcodonCount());
2405 if (alc[i].getAlcodonCount() > 0)
2407 Alcodon[] alcods = alc[i].getAlcodon();
2408 for (int p = 0; p < cf.codons.length; p++)
2410 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2411 && alcods[p].hasPos3())
2413 // translated codons require three valid positions
2414 cf.codons[p] = new int[3];
2415 cf.codons[p][0] = (int) alcods[p].getPos1();
2416 cf.codons[p][1] = (int) alcods[p].getPos2();
2417 cf.codons[p][2] = (int) alcods[p].getPos3();
2421 cf.codons[p] = null;
2425 if (alc[i].getAlcodMapCount() > 0)
2427 AlcodMap[] maps = alc[i].getAlcodMap();
2428 for (int m = 0; m < maps.length; m++)
2430 SequenceI dnaseq = (SequenceI) seqRefIds
2431 .get(maps[m].getDnasq());
2433 jalview.datamodel.Mapping mapping = null;
2434 // attach to dna sequence reference.
2435 if (maps[m].getMapping() != null)
2437 mapping = addMapping(maps[m].getMapping());
2441 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2446 frefedSequence.add(new Object[]
2447 { maps[m].getDnasq(), cf, mapping });
2451 al.addCodonFrame(cf);
2456 // ////////////////////////////////
2458 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2460 * store any annotations which forward reference a group's ID
2462 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2464 if (vamsasSet.getAnnotationCount() > 0)
2466 Annotation[] an = vamsasSet.getAnnotation();
2468 for (int i = 0; i < an.length; i++)
2471 * test if annotation is automatically calculated for this view only
2473 boolean autoForView = false;
2474 if (an[i].getLabel().equals("Quality")
2475 || an[i].getLabel().equals("Conservation")
2476 || an[i].getLabel().equals("Consensus"))
2478 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2480 if (!an[i].hasAutoCalculated())
2482 an[i].setAutoCalculated(true);
2486 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2488 // remove ID - we don't recover annotation from other views for
2489 // view-specific annotation
2493 // set visiblity for other annotation in this view
2494 if (an[i].getId() != null
2495 && annotationIds.containsKey(an[i].getId()))
2497 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2498 .get(an[i].getId());
2499 // in principle Visible should always be true for annotation displayed
2500 // in multiple views
2501 if (an[i].hasVisible())
2503 jda.visible = an[i].getVisible();
2506 al.addAnnotation(jda);
2510 // Construct new annotation from model.
2511 AnnotationElement[] ae = an[i].getAnnotationElement();
2512 jalview.datamodel.Annotation[] anot = null;
2513 java.awt.Color firstColour = null;
2515 if (!an[i].getScoreOnly())
2517 anot = new jalview.datamodel.Annotation[al.getWidth()];
2518 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2520 anpos = ae[aa].getPosition();
2522 if (anpos >= anot.length)
2527 anot[anpos] = new jalview.datamodel.Annotation(
2529 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2530 (ae[aa].getSecondaryStructure() == null || ae[aa]
2531 .getSecondaryStructure().length() == 0) ? ' '
2532 : ae[aa].getSecondaryStructure().charAt(0),
2536 // JBPNote: Consider verifying dataflow for IO of secondary
2537 // structure annotation read from Stockholm files
2538 // this was added to try to ensure that
2539 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2541 // anot[ae[aa].getPosition()].displayCharacter = "";
2543 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2544 if (firstColour == null)
2546 firstColour = anot[anpos].colour;
2550 jalview.datamodel.AlignmentAnnotation jaa = null;
2552 if (an[i].getGraph())
2554 float llim = 0, hlim = 0;
2555 // if (autoForView || an[i].isAutoCalculated()) {
2558 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2559 an[i].getDescription(), anot, llim, hlim,
2560 an[i].getGraphType());
2562 jaa.graphGroup = an[i].getGraphGroup();
2563 jaa._linecolour = firstColour;
2564 if (an[i].getThresholdLine() != null)
2566 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2567 .getThresholdLine().getValue(), an[i]
2568 .getThresholdLine().getLabel(), new java.awt.Color(
2569 an[i].getThresholdLine().getColour())));
2572 if (autoForView || an[i].isAutoCalculated())
2574 // Hardwire the symbol display line to ensure that labels for
2575 // histograms are displayed
2581 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2582 an[i].getDescription(), anot);
2583 jaa._linecolour = firstColour;
2585 // register new annotation
2586 if (an[i].getId() != null)
2588 annotationIds.put(an[i].getId(), jaa);
2589 jaa.annotationId = an[i].getId();
2591 // recover sequence association
2592 if (an[i].getSequenceRef() != null)
2594 if (al.findName(an[i].getSequenceRef()) != null)
2596 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2598 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2601 // and make a note of any group association
2602 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2604 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2605 .get(an[i].getGroupRef());
2608 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2609 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2614 if (an[i].hasScore())
2616 jaa.setScore(an[i].getScore());
2618 if (an[i].hasVisible())
2620 jaa.visible = an[i].getVisible();
2623 if (an[i].hasCentreColLabels())
2625 jaa.centreColLabels = an[i].getCentreColLabels();
2628 if (an[i].hasScaleColLabels())
2630 jaa.scaleColLabel = an[i].getScaleColLabels();
2632 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2634 // newer files have an 'autoCalculated' flag and store calculation
2635 // state in viewport properties
2636 jaa.autoCalculated = true; // means annotation will be marked for
2637 // update at end of load.
2639 if (an[i].hasGraphHeight())
2641 jaa.graphHeight = an[i].getGraphHeight();
2643 if (an[i].hasBelowAlignment())
2645 jaa.belowAlignment = an[i].isBelowAlignment();
2647 jaa.setCalcId(an[i].getCalcId());
2648 if (an[i].getPropertyCount() > 0)
2650 for (jalview.schemabinding.version2.Property prop : an[i]
2653 jaa.setProperty(prop.getName(), prop.getValue());
2656 if (jaa.autoCalculated)
2658 autoAlan.add(new JvAnnotRow(i, jaa));
2661 // if (!autoForView)
2663 // add autocalculated group annotation and any user created annotation
2665 al.addAnnotation(jaa);
2669 // ///////////////////////
2671 // Create alignment markup and styles for this view
2672 if (jms.getJGroupCount() > 0)
2674 JGroup[] groups = jms.getJGroup();
2675 boolean addAnnotSchemeGroup = false;
2676 for (int i = 0; i < groups.length; i++)
2678 ColourSchemeI cs = null;
2680 if (groups[i].getColour() != null)
2682 if (groups[i].getColour().startsWith("ucs"))
2684 cs = GetUserColourScheme(jms, groups[i].getColour());
2686 else if (groups[i].getColour().equals("AnnotationColourGradient")
2687 && groups[i].getAnnotationColours() != null)
2689 addAnnotSchemeGroup = true;
2694 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2699 cs.setThreshold(groups[i].getPidThreshold(), true);
2703 Vector seqs = new Vector();
2705 for (int s = 0; s < groups[i].getSeqCount(); s++)
2707 String seqId = groups[i].getSeq(s) + "";
2708 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2713 seqs.addElement(ts);
2717 if (seqs.size() < 1)
2722 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2723 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2724 groups[i].getDisplayText(), groups[i].getColourText(),
2725 groups[i].getStart(), groups[i].getEnd());
2727 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2729 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2730 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2731 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2732 .isShowUnconserved() : false);
2733 sg.thresholdTextColour = groups[i].getTextColThreshold();
2734 if (groups[i].hasShowConsensusHistogram())
2736 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2739 if (groups[i].hasShowSequenceLogo())
2741 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2743 if (groups[i].hasNormaliseSequenceLogo())
2745 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2747 if (groups[i].hasIgnoreGapsinConsensus())
2749 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2751 if (groups[i].getConsThreshold() != 0)
2753 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2754 "All", ResidueProperties.propHash, 3,
2755 sg.getSequences(null), 0, sg.getWidth() - 1);
2757 c.verdict(false, 25);
2758 sg.cs.setConservation(c);
2761 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2763 // re-instate unique group/annotation row reference
2764 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2765 .get(groups[i].getId());
2768 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2771 if (jaa.autoCalculated)
2773 // match up and try to set group autocalc alignment row for this
2775 if (jaa.label.startsWith("Consensus for "))
2777 sg.setConsensus(jaa);
2779 // match up and try to set group autocalc alignment row for this
2781 if (jaa.label.startsWith("Conservation for "))
2783 sg.setConservationRow(jaa);
2790 if (addAnnotSchemeGroup)
2792 // reconstruct the annotation colourscheme
2793 sg.cs = constructAnnotationColour(
2794 groups[i].getAnnotationColours(), null, al, jms, false);
2800 // only dataset in this model, so just return.
2803 // ///////////////////////////////
2806 // If we just load in the same jar file again, the sequenceSetId
2807 // will be the same, and we end up with multiple references
2808 // to the same sequenceSet. We must modify this id on load
2809 // so that each load of the file gives a unique id
2810 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2811 String viewId = (view.getId() == null ? null : view.getId()
2813 AlignFrame af = null;
2814 AlignViewport av = null;
2815 // now check to see if we really need to create a new viewport.
2816 if (multipleView && viewportsAdded.size() == 0)
2818 // We recovered an alignment for which a viewport already exists.
2819 // TODO: fix up any settings necessary for overlaying stored state onto
2820 // state recovered from another document. (may not be necessary).
2821 // we may need a binding from a viewport in memory to one recovered from
2823 // and then recover its containing af to allow the settings to be applied.
2824 // TODO: fix for vamsas demo
2826 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2828 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2829 if (seqsetobj != null)
2831 if (seqsetobj instanceof String)
2833 uniqueSeqSetId = (String) seqsetobj;
2835 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2841 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2847 * indicate that annotation colours are applied across all groups (pre
2848 * Jalview 2.8.1 behaviour)
2850 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2851 object.getVersion());
2853 AlignmentPanel ap = null;
2854 boolean isnewview = true;
2857 // Check to see if this alignment already has a view id == viewId
2858 jalview.gui.AlignmentPanel views[] = Desktop
2859 .getAlignmentPanels(uniqueSeqSetId);
2860 if (views != null && views.length > 0)
2862 for (int v = 0; v < views.length; v++)
2864 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2866 // recover the existing alignpanel, alignframe, viewport
2867 af = views[v].alignFrame;
2870 // TODO: could even skip resetting view settings if we don't want to
2871 // change the local settings from other jalview processes
2880 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2881 uniqueSeqSetId, viewId, autoAlan);
2886 // /////////////////////////////////////
2887 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2891 for (int t = 0; t < jms.getTreeCount(); t++)
2894 Tree tree = jms.getTree(t);
2896 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2899 tp = af.ShowNewickTree(
2900 new jalview.io.NewickFile(tree.getNewick()),
2901 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2902 tree.getXpos(), tree.getYpos());
2903 if (tree.getId() != null)
2905 // perhaps bind the tree id to something ?
2910 // update local tree attributes ?
2911 // TODO: should check if tp has been manipulated by user - if so its
2912 // settings shouldn't be modified
2913 tp.setTitle(tree.getTitle());
2914 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2915 .getWidth(), tree.getHeight()));
2916 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2919 tp.treeCanvas.av = av; // af.viewport;
2920 tp.treeCanvas.ap = ap; // af.alignPanel;
2925 warn("There was a problem recovering stored Newick tree: \n"
2926 + tree.getNewick());
2930 tp.fitToWindow.setState(tree.getFitToWindow());
2931 tp.fitToWindow_actionPerformed(null);
2933 if (tree.getFontName() != null)
2935 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2936 .getFontStyle(), tree.getFontSize()));
2940 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2941 .getFontStyle(), tree.getFontSize()));
2944 tp.showPlaceholders(tree.getMarkUnlinked());
2945 tp.showBootstrap(tree.getShowBootstrap());
2946 tp.showDistances(tree.getShowDistances());
2948 tp.treeCanvas.threshold = tree.getThreshold();
2950 if (tree.getCurrentTree())
2952 af.viewport.setCurrentTree(tp.getTree());
2956 } catch (Exception ex)
2958 ex.printStackTrace();
2962 // //LOAD STRUCTURES
2963 if (loadTreesAndStructures)
2965 // run through all PDB ids on the alignment, and collect mappings between
2966 // jmol view ids and all sequences referring to it
2967 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2969 for (int i = 0; i < JSEQ.length; i++)
2971 if (JSEQ[i].getPdbidsCount() > 0)
2973 Pdbids[] ids = JSEQ[i].getPdbids();
2974 for (int p = 0; p < ids.length; p++)
2976 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2978 // check to see if we haven't already created this structure view
2979 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2980 : ids[p].getStructureState(s).getViewId()
2982 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2983 // Originally : ids[p].getFile()
2984 // : TODO: verify external PDB file recovery still works in normal
2985 // jalview project load
2986 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2987 jpdb.setId(ids[p].getId());
2989 int x = ids[p].getStructureState(s).getXpos();
2990 int y = ids[p].getStructureState(s).getYpos();
2991 int width = ids[p].getStructureState(s).getWidth();
2992 int height = ids[p].getStructureState(s).getHeight();
2994 // Probably don't need to do this anymore...
2995 // Desktop.desktop.getComponentAt(x, y);
2996 // TODO: NOW: check that this recovers the PDB file correctly.
2997 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2998 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2999 .get(JSEQ[i].getId() + "");
3000 if (sviewid == null)
3002 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3005 if (!jmolViewIds.containsKey(sviewid))
3007 jmolViewIds.put(sviewid, new Object[]
3009 { x, y, width, height }, "",
3010 new Hashtable<String, Object[]>(), new boolean[]
3011 { false, false, true } });
3012 // Legacy pre-2.7 conversion JAL-823 :
3013 // do not assume any view has to be linked for colour by
3017 // assemble String[] { pdb files }, String[] { id for each
3018 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3019 // seqs_file 2}, boolean[] {
3020 // linkAlignPanel,superposeWithAlignpanel}} from hash
3021 Object[] jmoldat = jmolViewIds.get(sviewid);
3022 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
3023 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
3024 s).getAlignwithAlignPanel() : false;
3025 // never colour by linked panel if not specified
3026 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
3027 .hasColourwithAlignPanel() ? ids[p]
3028 .getStructureState(s).getColourwithAlignPanel()
3030 // default for pre-2.7 projects is that Jmol colouring is enabled
3031 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
3032 .hasColourByJmol() ? ids[p].getStructureState(s)
3033 .getColourByJmol() : true;
3035 if (((String) jmoldat[1]).length() < ids[p]
3036 .getStructureState(s).getContent().length())
3039 jmoldat[1] = ids[p].getStructureState(s).getContent();
3042 if (ids[p].getFile() != null)
3044 File mapkey = new File(ids[p].getFile());
3045 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3047 if (seqstrmaps == null)
3049 ((Hashtable) jmoldat[2]).put(mapkey,
3050 seqstrmaps = new Object[]
3051 { pdbFile, ids[p].getId(), new Vector(),
3054 if (!((Vector) seqstrmaps[2]).contains(seq))
3056 ((Vector) seqstrmaps[2]).addElement(seq);
3057 // ((Vector)seqstrmaps[3]).addElement(n) :
3058 // in principle, chains
3059 // should be stored here : do we need to
3060 // TODO: store and recover seq/pdb_id :
3066 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");
3075 // Instantiate the associated Jmol views
3076 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3078 String sviewid = entry.getKey();
3079 Object[] svattrib = entry.getValue();
3080 int[] geom = (int[]) svattrib[0];
3081 String state = (String) svattrib[1];
3082 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3083 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3084 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3085 // collate the pdbfile -> sequence mappings from this view
3086 Vector<String> pdbfilenames = new Vector<String>();
3087 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3088 Vector<String> pdbids = new Vector<String>();
3090 // Search to see if we've already created this Jmol view
3091 AppJmol comp = null;
3092 JInternalFrame[] frames = null;
3097 frames = Desktop.desktop.getAllFrames();
3098 } catch (ArrayIndexOutOfBoundsException e)
3100 // occasional No such child exceptions are thrown here...
3105 } catch (Exception f)
3110 } while (frames == null);
3111 // search for any Jmol windows already open from other
3112 // alignment views that exactly match the stored structure state
3113 for (int f = 0; comp == null && f < frames.length; f++)
3115 if (frames[f] instanceof AppJmol)
3118 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3120 // post jalview 2.4 schema includes structure view id
3121 comp = (AppJmol) frames[f];
3123 else if (frames[f].getX() == x && frames[f].getY() == y
3124 && frames[f].getHeight() == height
3125 && frames[f].getWidth() == width)
3127 comp = (AppJmol) frames[f];
3134 // create a new Jmol window.
3135 // First parse the Jmol state to translate filenames loaded into the
3136 // view, and record the order in which files are shown in the Jmol
3137 // view, so we can add the sequence mappings in same order.
3138 StringBuffer newFileLoc = null;
3139 int cp = 0, ncp, ecp;
3140 while ((ncp = state.indexOf("load ", cp)) > -1)
3142 if (newFileLoc == null)
3144 newFileLoc = new StringBuffer();
3148 // look for next filename in load statement
3149 newFileLoc.append(state.substring(cp,
3150 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3151 String oldfilenam = state.substring(ncp,
3152 ecp = state.indexOf("\"", ncp));
3153 // recover the new mapping data for this old filename
3154 // have to normalize filename - since Jmol and jalview do
3156 // translation differently.
3157 Object[] filedat = oldFiles.get(new File(oldfilenam));
3158 newFileLoc.append(Platform
3159 .escapeString((String) filedat[0]));
3160 pdbfilenames.addElement((String) filedat[0]);
3161 pdbids.addElement((String) filedat[1]);
3162 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3163 .toArray(new SequenceI[0]));
3164 newFileLoc.append("\"");
3165 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3166 // look for next file statement.
3167 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3171 // just append rest of state
3172 newFileLoc.append(state.substring(cp));
3177 .print("Ignoring incomplete Jmol state for PDB ids: ");
3178 newFileLoc = new StringBuffer(state);
3179 newFileLoc.append("; load append ");
3180 for (File id : oldFiles.keySet())
3182 // add this and any other pdb files that should be present in
3184 Object[] filedat = oldFiles.get(id);
3186 newFileLoc.append(((String) filedat[0]));
3187 pdbfilenames.addElement((String) filedat[0]);
3188 pdbids.addElement((String) filedat[1]);
3189 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3190 .toArray(new SequenceI[0]));
3191 newFileLoc.append(" \"");
3192 newFileLoc.append((String) filedat[0]);
3193 newFileLoc.append("\"");
3196 newFileLoc.append(";");
3199 if (newFileLoc != null)
3201 int histbug = newFileLoc.indexOf("history = ");
3203 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3205 String val = (diff == -1) ? null : newFileLoc.substring(
3207 if (val != null && val.length() >= 4)
3209 if (val.contains("e"))
3211 if (val.trim().equals("true"))
3219 newFileLoc.replace(histbug, diff, val);
3222 // TODO: assemble String[] { pdb files }, String[] { id for each
3223 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3224 // seqs_file 2}} from hash
3225 final String[] pdbf = pdbfilenames
3226 .toArray(new String[pdbfilenames.size()]), id = pdbids
3227 .toArray(new String[pdbids.size()]);
3228 final SequenceI[][] sq = seqmaps
3229 .toArray(new SequenceI[seqmaps.size()][]);
3230 final String fileloc = newFileLoc.toString(), vid = sviewid;
3231 final AlignFrame alf = af;
3232 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3236 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3241 JalviewStructureDisplayI sview = null;
3244 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3245 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3246 useinJmolsuperpos, usetoColourbyseq,
3247 jmolColouring, fileloc, rect, vid);
3248 addNewStructureViewer(sview);
3249 } catch (OutOfMemoryError ex)
3251 new OOMWarning("restoring structure view for PDB id "
3252 + id, (OutOfMemoryError) ex.getCause());
3253 if (sview != null && sview.isVisible())
3255 sview.closeViewer();
3256 sview.setVisible(false);
3262 } catch (InvocationTargetException ex)
3264 warn("Unexpected error when opening Jmol view.", ex);
3266 } catch (InterruptedException e)
3268 // e.printStackTrace();
3274 // if (comp != null)
3276 // NOTE: if the jalview project is part of a shared session then
3277 // view synchronization should/could be done here.
3279 // add mapping for sequences in this view to an already open Jmol
3281 for (File id : oldFiles.keySet())
3283 // add this and any other pdb files that should be present in the
3285 Object[] filedat = oldFiles.get(id);
3286 String pdbFile = (String) filedat[0];
3287 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3288 .toArray(new SequenceI[0]);
3289 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3290 jalview.io.AppletFormatAdapter.FILE);
3291 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3293 // and add the AlignmentPanel's reference to the Jmol view
3294 comp.addAlignmentPanel(ap);
3295 if (useinJmolsuperpos)
3297 comp.useAlignmentPanelForSuperposition(ap);
3301 comp.excludeAlignmentPanelForSuperposition(ap);
3303 if (usetoColourbyseq)
3305 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3309 comp.excludeAlignmentPanelForColourbyseq(ap);
3315 // and finally return.
3322 * - minimum version we are comparing against
3324 * - version of data being processsed.
3325 * @return true if version is development/null or evaluates to the same or
3326 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3328 private boolean isVersionStringLaterThan(String supported, String version)
3330 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3331 || version.equalsIgnoreCase("Test")
3332 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3334 System.err.println("Assuming project file with "
3335 + (version == null ? "null" : version)
3336 + " is compatible with Jalview version " + supported);
3341 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3343 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3345 // convert b to decimal to catch bugfix releases within a series
3346 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3347 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3350 if (Float.valueOf(curT) > Float.valueOf(fileT))
3352 // current version is newer than the version that wrote the file
3355 } catch (NumberFormatException nfe)
3358 .println("** WARNING: Version comparison failed for tokens ("
3362 + ")\n** Current: '"
3363 + supported + "' and Version: '" + version + "'");
3366 if (currentV.hasMoreElements())
3368 // fileV has no minor version but identical series to current
3375 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3377 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3379 if (newStructureViewers != null)
3381 sview.getBinding().setFinishedLoadingFromArchive(false);
3382 newStructureViewers.add(sview);
3386 protected void setLoadingFinishedForNewStructureViewers()
3388 if (newStructureViewers != null)
3390 for (JalviewStructureDisplayI sview : newStructureViewers)
3392 sview.getBinding().setFinishedLoadingFromArchive(true);
3394 newStructureViewers.clear();
3395 newStructureViewers = null;
3399 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3400 Alignment al, JalviewModelSequence jms, Viewport view,
3401 String uniqueSeqSetId, String viewId,
3402 ArrayList<JvAnnotRow> autoAlan)
3404 AlignFrame af = null;
3405 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3406 uniqueSeqSetId, viewId);
3408 af.setFileName(file, "Jalview");
3410 for (int i = 0; i < JSEQ.length; i++)
3412 af.viewport.setSequenceColour(af.viewport.getAlignment()
3413 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3416 af.viewport.gatherViewsHere = view.getGatheredViews();
3418 if (view.getSequenceSetId() != null)
3420 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3421 .get(uniqueSeqSetId);
3423 af.viewport.setSequenceSetId(uniqueSeqSetId);
3426 // propagate shared settings to this new view
3427 af.viewport.historyList = av.historyList;
3428 af.viewport.redoList = av.redoList;
3432 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3434 // TODO: check if this method can be called repeatedly without
3435 // side-effects if alignpanel already registered.
3436 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3438 // apply Hidden regions to view.
3439 if (hiddenSeqs != null)
3441 for (int s = 0; s < JSEQ.length; s++)
3443 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3445 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3448 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3450 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3453 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3456 for (int s = 0; s < hiddenSeqs.size(); s++)
3458 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3461 af.viewport.hideSequence(hseqs);
3464 // recover view properties and display parameters
3465 if (view.getViewName() != null)
3467 af.viewport.viewName = view.getViewName();
3468 af.setInitialTabVisible();
3470 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3473 af.viewport.setShowAnnotation(view.getShowAnnotation());
3474 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3476 af.viewport.setColourText(view.getShowColourText());
3478 af.viewport.setConservationSelected(view.getConservationSelected());
3479 af.viewport.setShowJVSuffix(view.getShowFullId());
3480 af.viewport.rightAlignIds = view.getRightAlignIds();
3481 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3482 .getFontStyle(), view.getFontSize()));
3483 af.alignPanel.fontChanged();
3484 af.viewport.setRenderGaps(view.getRenderGaps());
3485 af.viewport.setWrapAlignment(view.getWrapAlignment());
3486 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3487 af.viewport.setShowAnnotation(view.getShowAnnotation());
3488 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3490 af.viewport.setShowBoxes(view.getShowBoxes());
3492 af.viewport.setShowText(view.getShowText());
3494 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3495 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3496 af.viewport.thresholdTextColour = view.getTextColThreshold();
3497 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3498 .isShowUnconserved() : false);
3499 af.viewport.setStartRes(view.getStartRes());
3500 af.viewport.setStartSeq(view.getStartSeq());
3502 ColourSchemeI cs = null;
3503 // apply colourschemes
3504 if (view.getBgColour() != null)
3506 if (view.getBgColour().startsWith("ucs"))
3508 cs = GetUserColourScheme(jms, view.getBgColour());
3510 else if (view.getBgColour().startsWith("Annotation"))
3512 AnnotationColours viewAnnColour = view.getAnnotationColours();
3513 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3520 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3525 cs.setThreshold(view.getPidThreshold(), true);
3526 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3530 af.viewport.setGlobalColourScheme(cs);
3531 af.viewport.setColourAppliesToAllGroups(false);
3533 if (view.getConservationSelected() && cs != null)
3535 cs.setConservationInc(view.getConsThreshold());
3538 af.changeColour(cs);
3540 af.viewport.setColourAppliesToAllGroups(true);
3542 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
3544 if (view.hasCentreColumnLabels())
3546 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3548 if (view.hasIgnoreGapsinConsensus())
3550 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3553 if (view.hasFollowHighlight())
3555 af.viewport.followHighlight = view.getFollowHighlight();
3557 if (view.hasFollowSelection())
3559 af.viewport.followSelection = view.getFollowSelection();
3561 if (view.hasShowConsensusHistogram())
3563 af.viewport.setShowConsensusHistogram(view
3564 .getShowConsensusHistogram());
3568 af.viewport.setShowConsensusHistogram(true);
3570 if (view.hasShowSequenceLogo())
3572 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3576 af.viewport.setShowSequenceLogo(false);
3578 if (view.hasNormaliseSequenceLogo())
3580 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3582 if (view.hasShowDbRefTooltip())
3584 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3586 if (view.hasShowNPfeatureTooltip())
3588 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3590 if (view.hasShowGroupConsensus())
3592 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3596 af.viewport.setShowGroupConsensus(false);
3598 if (view.hasShowGroupConservation())
3600 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3604 af.viewport.setShowGroupConservation(false);
3607 // recover featre settings
3608 if (jms.getFeatureSettings() != null)
3610 FeaturesDisplayed fdi;
3611 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
3612 String[] renderOrder = new String[jms.getFeatureSettings()
3613 .getSettingCount()];
3614 Hashtable featureGroups = new Hashtable();
3615 Hashtable featureColours = new Hashtable();
3616 Hashtable featureOrder = new Hashtable();
3618 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3620 Setting setting = jms.getFeatureSettings().getSetting(fs);
3621 if (setting.hasMincolour())
3623 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3624 new java.awt.Color(setting.getMincolour()),
3625 new java.awt.Color(setting.getColour()),
3626 setting.getMin(), setting.getMax()) : new GraduatedColor(
3627 new java.awt.Color(setting.getMincolour()),
3628 new java.awt.Color(setting.getColour()), 0, 1);
3629 if (setting.hasThreshold())
3631 gc.setThresh(setting.getThreshold());
3632 gc.setThreshType(setting.getThreshstate());
3634 gc.setAutoScaled(true); // default
3635 if (setting.hasAutoScale())
3637 gc.setAutoScaled(setting.getAutoScale());
3639 if (setting.hasColourByLabel())
3641 gc.setColourByLabel(setting.getColourByLabel());
3643 // and put in the feature colour table.
3644 featureColours.put(setting.getType(), gc);
3648 featureColours.put(setting.getType(),
3649 new java.awt.Color(setting.getColour()));
3651 renderOrder[fs] = setting.getType();
3652 if (setting.hasOrder())
3654 featureOrder.put(setting.getType(), setting.getOrder());
3658 featureOrder.put(setting.getType(), new Float(fs
3659 / jms.getFeatureSettings().getSettingCount()));
3661 if (setting.getDisplay())
3663 fdi.setVisible(setting.getType());
3666 Hashtable fgtable = new Hashtable();
3667 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3669 Group grp = jms.getFeatureSettings().getGroup(gs);
3670 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3672 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
3673 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
3674 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
3675 FeatureRendererSettings frs = new FeatureRendererSettings(
3676 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
3677 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer()
3678 .transferSettings(frs);
3682 if (view.getHiddenColumnsCount() > 0)
3684 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3686 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3687 .getHiddenColumns(c).getEnd() // +1
3691 if (view.getCalcIdParam() != null)
3693 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3695 if (calcIdParam != null)
3697 if (recoverCalcIdParam(calcIdParam, af.viewport))
3702 warn("Couldn't recover parameters for "
3703 + calcIdParam.getCalcId());
3708 af.setMenusFromViewport(af.viewport);
3709 // TODO: we don't need to do this if the viewport is aready visible.
3710 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3712 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3713 reorderAutoannotation(af, al, autoAlan);
3714 af.alignPanel.alignmentChanged();
3718 private ColourSchemeI constructAnnotationColour(
3719 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3720 JalviewModelSequence jms, boolean checkGroupAnnColour)
3722 boolean propagateAnnColour = false;
3723 ColourSchemeI cs = null;
3724 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3725 if (checkGroupAnnColour && al.getGroups() != null
3726 && al.getGroups().size() > 0)
3728 // pre 2.8.1 behaviour
3729 // check to see if we should transfer annotation colours
3730 propagateAnnColour = true;
3731 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3733 if (sg.cs instanceof AnnotationColourGradient)
3735 propagateAnnColour = false;
3739 // int find annotation
3740 if (annAlignment.getAlignmentAnnotation() != null)
3742 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3744 if (annAlignment.getAlignmentAnnotation()[i].label
3745 .equals(viewAnnColour.getAnnotation()))
3747 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3749 annAlignment.getAlignmentAnnotation()[i]
3750 .setThreshold(new jalview.datamodel.GraphLine(
3751 viewAnnColour.getThreshold(), "Threshold",
3752 java.awt.Color.black)
3757 if (viewAnnColour.getColourScheme().equals("None"))
3759 cs = new AnnotationColourGradient(
3760 annAlignment.getAlignmentAnnotation()[i],
3761 new java.awt.Color(viewAnnColour.getMinColour()),
3762 new java.awt.Color(viewAnnColour.getMaxColour()),
3763 viewAnnColour.getAboveThreshold());
3765 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3767 cs = new AnnotationColourGradient(
3768 annAlignment.getAlignmentAnnotation()[i],
3769 GetUserColourScheme(jms,
3770 viewAnnColour.getColourScheme()),
3771 viewAnnColour.getAboveThreshold());
3775 cs = new AnnotationColourGradient(
3776 annAlignment.getAlignmentAnnotation()[i],
3777 ColourSchemeProperty.getColour(al,
3778 viewAnnColour.getColourScheme()),
3779 viewAnnColour.getAboveThreshold());
3781 if (viewAnnColour.hasPerSequence())
3783 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3786 if (viewAnnColour.hasPredefinedColours())
3788 ((AnnotationColourGradient) cs)
3789 .setPredefinedColours(viewAnnColour
3790 .isPredefinedColours());
3792 if (propagateAnnColour && al.getGroups() != null)
3794 // Also use these settings for all the groups
3795 for (int g = 0; g < al.getGroups().size(); g++)
3797 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3805 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3806 * new AnnotationColourGradient(
3807 * annAlignment.getAlignmentAnnotation()[i], new
3808 * java.awt.Color(viewAnnColour. getMinColour()), new
3809 * java.awt.Color(viewAnnColour. getMaxColour()),
3810 * viewAnnColour.getAboveThreshold()); } else
3813 sg.cs = new AnnotationColourGradient(
3814 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3815 viewAnnColour.getAboveThreshold());
3816 if (cs instanceof AnnotationColourGradient)
3818 if (viewAnnColour.hasPerSequence())
3820 ((AnnotationColourGradient) cs)
3821 .setSeqAssociated(viewAnnColour.isPerSequence());
3823 if (viewAnnColour.hasPredefinedColours())
3825 ((AnnotationColourGradient) cs)
3826 .setPredefinedColours(viewAnnColour
3827 .isPredefinedColours());
3843 private void reorderAutoannotation(AlignFrame af, Alignment al,
3844 ArrayList<JvAnnotRow> autoAlan)
3846 // copy over visualization settings for autocalculated annotation in the
3848 if (al.getAlignmentAnnotation() != null)
3851 * Kludge for magic autoannotation names (see JAL-811)
3853 String[] magicNames = new String[]
3854 { "Consensus", "Quality", "Conservation" };
3855 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3856 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3857 for (String nm : magicNames)
3859 visan.put(nm, nullAnnot);
3861 for (JvAnnotRow auan : autoAlan)
3863 visan.put(auan.template.label
3864 + (auan.template.getCalcId() == null ? "" : "\t"
3865 + auan.template.getCalcId()), auan);
3867 int hSize = al.getAlignmentAnnotation().length;
3868 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3869 // work through any autoCalculated annotation already on the view
3870 // removing it if it should be placed in a different location on the
3871 // annotation panel.
3872 List<String> remains = new ArrayList(visan.keySet());
3873 for (int h = 0; h < hSize; h++)
3875 jalview.datamodel.AlignmentAnnotation jalan = al
3876 .getAlignmentAnnotation()[h];
3877 if (jalan.autoCalculated)
3880 JvAnnotRow valan = visan.get(k = jalan.label);
3881 if (jalan.getCalcId() != null)
3883 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3888 // delete the auto calculated row from the alignment
3889 al.deleteAnnotation(jalan, false);
3893 if (valan != nullAnnot)
3895 if (jalan != valan.template)
3897 // newly created autoannotation row instance
3898 // so keep a reference to the visible annotation row
3899 // and copy over all relevant attributes
3900 if (valan.template.graphHeight >= 0)
3903 jalan.graphHeight = valan.template.graphHeight;
3905 jalan.visible = valan.template.visible;
3907 reorder.add(new JvAnnotRow(valan.order, jalan));
3912 // Add any (possibly stale) autocalculated rows that were not appended to
3913 // the view during construction
3914 for (String other : remains)
3916 JvAnnotRow othera = visan.get(other);
3917 if (othera != nullAnnot && othera.template.getCalcId() != null
3918 && othera.template.getCalcId().length() > 0)
3920 reorder.add(othera);
3923 // now put the automatic annotation in its correct place
3924 int s = 0, srt[] = new int[reorder.size()];
3925 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3926 for (JvAnnotRow jvar : reorder)
3929 srt[s++] = jvar.order;
3932 jalview.util.QuickSort.sort(srt, rws);
3933 // and re-insert the annotation at its correct position
3934 for (JvAnnotRow jvar : rws)
3936 al.addAnnotation(jvar.template, jvar.order);
3938 af.alignPanel.adjustAnnotationHeight();
3942 Hashtable skipList = null;
3945 * TODO remove this method
3948 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3949 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3950 * throw new Error("Implementation Error. No skipList defined for this
3951 * Jalview2XML instance."); } return (AlignFrame)
3952 * skipList.get(view.getSequenceSetId()); }
3956 * Check if the Jalview view contained in object should be skipped or not.
3959 * @return true if view's sequenceSetId is a key in skipList
3961 private boolean skipViewport(JalviewModel object)
3963 if (skipList == null)
3968 if (skipList.containsKey(id = object.getJalviewModelSequence()
3969 .getViewport()[0].getSequenceSetId()))
3971 if (Cache.log != null && Cache.log.isDebugEnabled())
3973 Cache.log.debug("Skipping seuqence set id " + id);
3980 public void AddToSkipList(AlignFrame af)
3982 if (skipList == null)
3984 skipList = new Hashtable();
3986 skipList.put(af.getViewport().getSequenceSetId(), af);
3989 public void clearSkipList()
3991 if (skipList != null)
3998 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
4000 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4001 Vector dseqs = null;
4004 // create a list of new dataset sequences
4005 dseqs = new Vector();
4007 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4009 Sequence vamsasSeq = vamsasSet.getSequence(i);
4010 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
4012 // create a new dataset
4015 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4016 dseqs.copyInto(dsseqs);
4017 ds = new jalview.datamodel.Alignment(dsseqs);
4018 debug("Created new dataset " + vamsasSet.getDatasetId()
4019 + " for alignment " + System.identityHashCode(al));
4020 addDatasetRef(vamsasSet.getDatasetId(), ds);
4022 // set the dataset for the newly imported alignment.
4023 if (al.getDataset() == null)
4032 * sequence definition to create/merge dataset sequence for
4036 * vector to add new dataset sequence to
4038 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4039 AlignmentI ds, Vector dseqs)
4041 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4043 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4044 .get(vamsasSeq.getId());
4045 jalview.datamodel.SequenceI dsq = null;
4046 if (sq != null && sq.getDatasetSequence() != null)
4048 dsq = sq.getDatasetSequence();
4051 String sqid = vamsasSeq.getDsseqid();
4054 // need to create or add a new dataset sequence reference to this sequence
4057 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4062 // make a new dataset sequence
4063 dsq = sq.createDatasetSequence();
4066 // make up a new dataset reference for this sequence
4067 sqid = seqHash(dsq);
4069 dsq.setVamsasId(uniqueSetSuffix + sqid);
4070 seqRefIds.put(sqid, dsq);
4075 dseqs.addElement(dsq);
4080 ds.addSequence(dsq);
4086 { // make this dataset sequence sq's dataset sequence
4087 sq.setDatasetSequence(dsq);
4088 // and update the current dataset alignment
4093 if (!dseqs.contains(dsq))
4100 if (ds.findIndex(dsq) < 0)
4102 ds.addSequence(dsq);
4109 // TODO: refactor this as a merge dataset sequence function
4110 // now check that sq (the dataset sequence) sequence really is the union of
4111 // all references to it
4112 // boolean pre = sq.getStart() < dsq.getStart();
4113 // boolean post = sq.getEnd() > dsq.getEnd();
4117 StringBuffer sb = new StringBuffer();
4118 String newres = jalview.analysis.AlignSeq.extractGaps(
4119 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4120 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4121 && newres.length() > dsq.getLength())
4123 // Update with the longer sequence.
4127 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4128 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4129 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4130 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4132 dsq.setSequence(newres);
4134 // TODO: merges will never happen if we 'know' we have the real dataset
4135 // sequence - this should be detected when id==dssid
4137 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4138 // + (pre ? "prepended" : "") + " "
4139 // + (post ? "appended" : ""));
4144 java.util.Hashtable datasetIds = null;
4146 java.util.IdentityHashMap dataset2Ids = null;
4148 private Alignment getDatasetFor(String datasetId)
4150 if (datasetIds == null)
4152 datasetIds = new Hashtable();
4155 if (datasetIds.containsKey(datasetId))
4157 return (Alignment) datasetIds.get(datasetId);
4162 private void addDatasetRef(String datasetId, Alignment dataset)
4164 if (datasetIds == null)
4166 datasetIds = new Hashtable();
4168 datasetIds.put(datasetId, dataset);
4172 * make a new dataset ID for this jalview dataset alignment
4177 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4179 if (dataset.getDataset() != null)
4181 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4183 String datasetId = makeHashCode(dataset, null);
4184 if (datasetId == null)
4186 // make a new datasetId and record it
4187 if (dataset2Ids == null)
4189 dataset2Ids = new IdentityHashMap();
4193 datasetId = (String) dataset2Ids.get(dataset);
4195 if (datasetId == null)
4197 datasetId = "ds" + dataset2Ids.size() + 1;
4198 dataset2Ids.put(dataset, datasetId);
4204 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4206 for (int d = 0; d < sequence.getDBRefCount(); d++)
4208 DBRef dr = sequence.getDBRef(d);
4209 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4210 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4211 .getVersion(), sequence.getDBRef(d).getAccessionId());
4212 if (dr.getMapping() != null)
4214 entry.setMap(addMapping(dr.getMapping()));
4216 datasetSequence.addDBRef(entry);
4220 private jalview.datamodel.Mapping addMapping(Mapping m)
4222 SequenceI dsto = null;
4223 // Mapping m = dr.getMapping();
4224 int fr[] = new int[m.getMapListFromCount() * 2];
4225 Enumeration f = m.enumerateMapListFrom();
4226 for (int _i = 0; f.hasMoreElements(); _i += 2)
4228 MapListFrom mf = (MapListFrom) f.nextElement();
4229 fr[_i] = mf.getStart();
4230 fr[_i + 1] = mf.getEnd();
4232 int fto[] = new int[m.getMapListToCount() * 2];
4233 f = m.enumerateMapListTo();
4234 for (int _i = 0; f.hasMoreElements(); _i += 2)
4236 MapListTo mf = (MapListTo) f.nextElement();
4237 fto[_i] = mf.getStart();
4238 fto[_i + 1] = mf.getEnd();
4240 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4241 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4242 if (m.getMappingChoice() != null)
4244 MappingChoice mc = m.getMappingChoice();
4245 if (mc.getDseqFor() != null)
4247 String dsfor = "" + mc.getDseqFor();
4248 if (seqRefIds.containsKey(dsfor))
4253 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4257 frefedSequence.add(new Object[]
4264 * local sequence definition
4266 Sequence ms = mc.getSequence();
4267 jalview.datamodel.Sequence djs = null;
4268 String sqid = ms.getDsseqid();
4269 if (sqid != null && sqid.length() > 0)
4272 * recover dataset sequence
4274 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4279 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4280 sqid = ((Object) ms).toString(); // make up a new hascode for
4281 // undefined dataset sequence hash
4282 // (unlikely to happen)
4288 * make a new dataset sequence and add it to refIds hash
4290 djs = new jalview.datamodel.Sequence(ms.getName(),
4292 djs.setStart(jmap.getMap().getToLowest());
4293 djs.setEnd(jmap.getMap().getToHighest());
4294 djs.setVamsasId(uniqueSetSuffix + sqid);
4296 seqRefIds.put(sqid, djs);
4299 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4308 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4309 boolean keepSeqRefs)
4312 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4318 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4322 uniqueSetSuffix = "";
4323 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4328 if (this.frefedSequence == null)
4330 frefedSequence = new Vector();
4333 viewportsAdded = new Hashtable();
4335 AlignFrame af = LoadFromObject(jm, null, false, null);
4336 af.alignPanels.clear();
4337 af.closeMenuItem_actionPerformed(true);
4340 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4341 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4342 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4343 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4344 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4347 return af.alignPanel;
4351 * flag indicating if hashtables should be cleared on finalization TODO this
4352 * flag may not be necessary
4354 private final boolean _cleartables = true;
4356 private Hashtable jvids2vobj;
4361 * @see java.lang.Object#finalize()
4364 protected void finalize() throws Throwable
4366 // really make sure we have no buried refs left.
4371 this.seqRefIds = null;
4372 this.seqsToIds = null;
4376 private void warn(String msg)
4381 private void warn(String msg, Exception e)
4383 if (Cache.log != null)
4387 Cache.log.warn(msg, e);
4391 Cache.log.warn(msg);
4396 System.err.println("Warning: " + msg);
4399 e.printStackTrace();
4404 private void debug(String string)
4406 debug(string, null);
4409 private void debug(String msg, Exception e)
4411 if (Cache.log != null)
4415 Cache.log.debug(msg, e);
4419 Cache.log.debug(msg);
4424 System.err.println("Warning: " + msg);
4427 e.printStackTrace();
4433 * set the object to ID mapping tables used to write/recover objects and XML
4434 * ID strings for the jalview project. If external tables are provided then
4435 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4436 * object goes out of scope. - also populates the datasetIds hashtable with
4437 * alignment objects containing dataset sequences
4440 * Map from ID strings to jalview datamodel
4442 * Map from jalview datamodel to ID strings
4446 public void setObjectMappingTables(Hashtable vobj2jv,
4447 IdentityHashMap jv2vobj)
4449 this.jv2vobj = jv2vobj;
4450 this.vobj2jv = vobj2jv;
4451 Iterator ds = jv2vobj.keySet().iterator();
4453 while (ds.hasNext())
4455 Object jvobj = ds.next();
4456 id = jv2vobj.get(jvobj).toString();
4457 if (jvobj instanceof jalview.datamodel.Alignment)
4459 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4461 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4464 else if (jvobj instanceof jalview.datamodel.Sequence)
4466 // register sequence object so the XML parser can recover it.
4467 if (seqRefIds == null)
4469 seqRefIds = new Hashtable();
4471 if (seqsToIds == null)
4473 seqsToIds = new IdentityHashMap();
4475 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4476 seqsToIds.put(jvobj, id);
4478 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4480 if (annotationIds == null)
4482 annotationIds = new Hashtable();
4485 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4486 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4487 if (jvann.annotationId == null)
4489 jvann.annotationId = anid;
4491 if (!jvann.annotationId.equals(anid))
4493 // TODO verify that this is the correct behaviour
4494 this.warn("Overriding Annotation ID for " + anid
4495 + " from different id : " + jvann.annotationId);
4496 jvann.annotationId = anid;
4499 else if (jvobj instanceof String)
4501 if (jvids2vobj == null)
4503 jvids2vobj = new Hashtable();
4504 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4509 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4515 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4516 * objects created from the project archive. If string is null (default for
4517 * construction) then suffix will be set automatically.
4521 public void setUniqueSetSuffix(String string)
4523 uniqueSetSuffix = string;
4528 * uses skipList2 as the skipList for skipping views on sequence sets
4529 * associated with keys in the skipList
4533 public void setSkipList(Hashtable skipList2)
4535 skipList = skipList2;