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.PDBEntry;
29 import jalview.datamodel.SequenceI;
30 import jalview.jbgui.GStructureViewer;
31 import jalview.schemabinding.version2.AlcodMap;
32 import jalview.schemabinding.version2.Alcodon;
33 import jalview.schemabinding.version2.AlcodonFrame;
34 import jalview.schemabinding.version2.Annotation;
35 import jalview.schemabinding.version2.AnnotationColours;
36 import jalview.schemabinding.version2.AnnotationElement;
37 import jalview.schemabinding.version2.CalcIdParam;
38 import jalview.schemabinding.version2.DBRef;
39 import jalview.schemabinding.version2.Features;
40 import jalview.schemabinding.version2.Group;
41 import jalview.schemabinding.version2.HiddenColumns;
42 import jalview.schemabinding.version2.JGroup;
43 import jalview.schemabinding.version2.JSeq;
44 import jalview.schemabinding.version2.JalviewModel;
45 import jalview.schemabinding.version2.JalviewModelSequence;
46 import jalview.schemabinding.version2.MapListFrom;
47 import jalview.schemabinding.version2.MapListTo;
48 import jalview.schemabinding.version2.Mapping;
49 import jalview.schemabinding.version2.MappingChoice;
50 import jalview.schemabinding.version2.OtherData;
51 import jalview.schemabinding.version2.PdbentryItem;
52 import jalview.schemabinding.version2.Pdbids;
53 import jalview.schemabinding.version2.Property;
54 import jalview.schemabinding.version2.Sequence;
55 import jalview.schemabinding.version2.SequenceSet;
56 import jalview.schemabinding.version2.SequenceSetProperties;
57 import jalview.schemabinding.version2.Setting;
58 import jalview.schemabinding.version2.StructureState;
59 import jalview.schemabinding.version2.ThresholdLine;
60 import jalview.schemabinding.version2.Tree;
61 import jalview.schemabinding.version2.UserColours;
62 import jalview.schemabinding.version2.Viewport;
63 import jalview.schemes.AnnotationColourGradient;
64 import jalview.schemes.ColourSchemeI;
65 import jalview.schemes.ColourSchemeProperty;
66 import jalview.schemes.GraduatedColor;
67 import jalview.schemes.ResidueColourScheme;
68 import jalview.schemes.ResidueProperties;
69 import jalview.schemes.UserColourScheme;
70 import jalview.structure.StructureSelectionManager;
71 import jalview.structures.models.AAStructureBindingModel;
72 import jalview.util.MessageManager;
73 import jalview.util.Platform;
74 import jalview.util.jarInputStreamProvider;
75 import jalview.viewmodel.AlignmentViewport;
76 import jalview.ws.jws2.Jws2Discoverer;
77 import jalview.ws.jws2.dm.AAConSettings;
78 import jalview.ws.jws2.jabaws2.Jws2Instance;
79 import jalview.ws.params.ArgumentI;
80 import jalview.ws.params.AutoCalcSetting;
81 import jalview.ws.params.WsParamSetI;
83 import java.awt.Rectangle;
84 import java.io.BufferedReader;
85 import java.io.DataInputStream;
86 import java.io.DataOutputStream;
88 import java.io.FileInputStream;
89 import java.io.FileOutputStream;
90 import java.io.IOException;
91 import java.io.InputStreamReader;
92 import java.io.OutputStreamWriter;
93 import java.io.PrintWriter;
94 import java.lang.reflect.InvocationTargetException;
95 import java.net.MalformedURLException;
97 import java.util.ArrayList;
98 import java.util.Enumeration;
99 import java.util.HashSet;
100 import java.util.Hashtable;
101 import java.util.IdentityHashMap;
102 import java.util.Iterator;
103 import java.util.List;
104 import java.util.Map.Entry;
105 import java.util.Set;
106 import java.util.StringTokenizer;
107 import java.util.Vector;
108 import java.util.jar.JarEntry;
109 import java.util.jar.JarInputStream;
110 import java.util.jar.JarOutputStream;
112 import javax.swing.JInternalFrame;
113 import javax.swing.JOptionPane;
114 import javax.swing.SwingUtilities;
116 import org.exolab.castor.xml.Unmarshaller;
119 * Write out the current jalview desktop state as a Jalview XML stream.
121 * Note: the vamsas objects referred to here are primitive versions of the
122 * VAMSAS project schema elements - they are not the same and most likely never
126 * @version $Revision: 1.134 $
128 public class Jalview2XML
131 * create/return unique hash string for sq
134 * @return new or existing unique string for sq
136 String seqHash(SequenceI sq)
138 if (seqsToIds == null)
142 if (seqsToIds.containsKey(sq))
144 return (String) seqsToIds.get(sq);
148 // create sequential key
149 String key = "sq" + (seqsToIds.size() + 1);
150 key = makeHashCode(sq, key); // check we don't have an external reference
152 seqsToIds.put(sq, key);
161 if (seqRefIds != null)
165 if (seqsToIds != null)
175 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
176 // seqRefIds = new Hashtable();
177 // seqsToIds = new IdentityHashMap();
183 if (seqsToIds == null)
185 seqsToIds = new IdentityHashMap();
187 if (seqRefIds == null)
189 seqRefIds = new Hashtable();
194 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
195 * of sequence objects are created.
197 java.util.IdentityHashMap seqsToIds = null;
200 * jalview XML Sequence ID to jalview sequence object reference (both dataset
201 * and alignment sequences. Populated as XML reps of sequence objects are
204 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
206 Vector frefedSequence = null;
208 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
214 public Jalview2XML(boolean raiseGUI)
216 this.raiseGUI = raiseGUI;
219 public void resolveFrefedSequences()
221 if (frefedSequence.size() > 0)
223 int r = 0, rSize = frefedSequence.size();
226 Object[] ref = (Object[]) frefedSequence.elementAt(r);
229 String sref = (String) ref[0];
230 if (seqRefIds.containsKey(sref))
232 if (ref[1] instanceof jalview.datamodel.Mapping)
234 SequenceI seq = (SequenceI) seqRefIds.get(sref);
235 while (seq.getDatasetSequence() != null)
237 seq = seq.getDatasetSequence();
239 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
243 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
245 SequenceI seq = (SequenceI) seqRefIds.get(sref);
246 while (seq.getDatasetSequence() != null)
248 seq = seq.getDatasetSequence();
251 && ref[2] instanceof jalview.datamodel.Mapping)
253 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
254 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
255 seq, mp.getTo(), mp.getMap());
260 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
261 + ref[2].getClass() + " type objects.");
267 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
268 + ref[1].getClass() + " type objects.");
271 frefedSequence.remove(r);
277 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
279 + " with objecttype "
280 + ref[1].getClass());
287 frefedSequence.remove(r);
295 * This maintains a list of viewports, the key being the seqSetId. Important
296 * to set historyItem and redoList for multiple views
298 Hashtable viewportsAdded;
300 Hashtable annotationIds = new Hashtable();
302 String uniqueSetSuffix = "";
305 * List of pdbfiles added to Jar
307 Vector pdbfiles = null;
309 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
310 public void SaveState(File statefile)
314 FileOutputStream fos = new FileOutputStream(statefile);
315 JarOutputStream jout = new JarOutputStream(fos);
318 } catch (Exception e)
320 // TODO: inform user of the problem - they need to know if their data was
322 if (errorMessage == null)
324 errorMessage = "Couldn't write Jalview Archive to output file '"
325 + statefile + "' - See console error log for details";
329 errorMessage += "(output file was '" + statefile + "')";
337 * Writes a jalview project archive to the given Jar output stream.
341 public void SaveState(JarOutputStream jout)
343 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
350 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
355 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
356 // //////////////////////////////////////////////////
357 // NOTE ALSO new PrintWriter must be used for each new JarEntry
358 PrintWriter out = null;
360 Vector shortNames = new Vector();
363 for (int i = frames.length - 1; i > -1; i--)
365 if (frames[i] instanceof AlignFrame)
367 AlignFrame af = (AlignFrame) frames[i];
370 && skipList.containsKey(af.getViewport()
371 .getSequenceSetId()))
376 String shortName = af.getTitle();
378 if (shortName.indexOf(File.separatorChar) > -1)
380 shortName = shortName.substring(shortName
381 .lastIndexOf(File.separatorChar) + 1);
386 while (shortNames.contains(shortName))
388 if (shortName.endsWith("_" + (count - 1)))
390 shortName = shortName
391 .substring(0, shortName.lastIndexOf("_"));
394 shortName = shortName.concat("_" + count);
398 shortNames.addElement(shortName);
400 if (!shortName.endsWith(".xml"))
402 shortName = shortName + ".xml";
405 int ap, apSize = af.alignPanels.size();
407 for (ap = 0; ap < apSize; ap++)
409 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
411 String fileName = apSize == 1 ? shortName : ap + shortName;
412 if (!fileName.endsWith(".xml"))
414 fileName = fileName + ".xml";
417 SaveState(apanel, fileName, jout);
419 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
421 if (!dsses.containsKey(dssid))
423 dsses.put(dssid, af);
430 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
436 } catch (Exception foo)
441 } catch (Exception ex)
443 // TODO: inform user of the problem - they need to know if their data was
445 if (errorMessage == null)
447 errorMessage = "Couldn't write Jalview Archive - see error output for details";
449 ex.printStackTrace();
453 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
454 public boolean SaveAlignment(AlignFrame af, String jarFile,
459 int ap, apSize = af.alignPanels.size();
460 FileOutputStream fos = new FileOutputStream(jarFile);
461 JarOutputStream jout = new JarOutputStream(fos);
462 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
463 for (ap = 0; ap < apSize; ap++)
465 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
467 String jfileName = apSize == 1 ? fileName : fileName + ap;
468 if (!jfileName.endsWith(".xml"))
470 jfileName = jfileName + ".xml";
472 SaveState(apanel, jfileName, jout);
473 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
475 if (!dsses.containsKey(dssid))
477 dsses.put(dssid, af);
480 writeDatasetFor(dsses, fileName, jout);
484 } catch (Exception foo)
490 } catch (Exception ex)
492 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
493 ex.printStackTrace();
498 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
499 String fileName, JarOutputStream jout)
502 for (String dssids : dsses.keySet())
504 AlignFrame _af = dsses.get(dssids);
505 String jfileName = fileName + " Dataset for " + _af.getTitle();
506 if (!jfileName.endsWith(".xml"))
508 jfileName = jfileName + ".xml";
510 SaveState(_af.alignPanel, jfileName, true, jout);
515 * create a JalviewModel from an algnment view and marshall it to a
519 * panel to create jalview model for
521 * name of alignment panel written to output stream
527 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
528 JarOutputStream jout)
530 return SaveState(ap, fileName, false, jout);
534 * create a JalviewModel from an alignment view and marshall it to a
538 * panel to create jalview model for
540 * name of alignment panel written to output stream
542 * when true, only write the dataset for the alignment, not the data
543 * associated with the view.
549 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
550 boolean storeDS, JarOutputStream jout)
553 List<String> chimeraViewIds = new ArrayList<String>();
554 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
556 AlignViewport av = ap.av;
558 JalviewModel object = new JalviewModel();
559 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
561 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
562 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
563 "Development Build"));
565 jalview.datamodel.AlignmentI jal = av.getAlignment();
567 if (av.hasHiddenRows())
569 jal = jal.getHiddenSequences().getFullAlignment();
572 SequenceSet vamsasSet = new SequenceSet();
574 JalviewModelSequence jms = new JalviewModelSequence();
576 vamsasSet.setGapChar(jal.getGapCharacter() + "");
578 if (jal.getDataset() != null)
580 // dataset id is the dataset's hashcode
581 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
584 // switch jal and the dataset
585 jal = jal.getDataset();
588 if (jal.getProperties() != null)
590 Enumeration en = jal.getProperties().keys();
591 while (en.hasMoreElements())
593 String key = en.nextElement().toString();
594 SequenceSetProperties ssp = new SequenceSetProperties();
596 ssp.setValue(jal.getProperties().get(key).toString());
597 vamsasSet.addSequenceSetProperties(ssp);
602 Set<String> calcIdSet = new HashSet<String>();
606 jalview.datamodel.SequenceI jds, jdatasq;
607 for (int i = 0; i < jal.getHeight(); i++)
609 jds = jal.getSequenceAt(i);
610 jdatasq = jds.getDatasetSequence() == null ? jds : jds
611 .getDatasetSequence();
614 if (seqRefIds.get(id) != null)
616 // This happens for two reasons: 1. multiple views are being serialised.
617 // 2. the hashCode has collided with another sequence's code. This DOES
618 // HAPPEN! (PF00072.15.stk does this)
619 // JBPNote: Uncomment to debug writing out of files that do not read
620 // back in due to ArrayOutOfBoundExceptions.
621 // System.err.println("vamsasSeq backref: "+id+"");
622 // System.err.println(jds.getName()+"
623 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
624 // System.err.println("Hashcode: "+seqHash(jds));
625 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
626 // System.err.println(rsq.getName()+"
627 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
628 // System.err.println("Hashcode: "+seqHash(rsq));
632 vamsasSeq = createVamsasSequence(id, jds);
633 vamsasSet.addSequence(vamsasSeq);
634 seqRefIds.put(id, jds);
638 jseq.setStart(jds.getStart());
639 jseq.setEnd(jds.getEnd());
640 jseq.setColour(av.getSequenceColour(jds).getRGB());
642 jseq.setId(id); // jseq id should be a string not a number
645 // Store any sequences this sequence represents
646 if (av.hasHiddenRows())
648 jseq.setHidden(av.getAlignment().getHiddenSequences()
651 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
653 jalview.datamodel.SequenceI[] reps = av
654 .getRepresentedSequences(jal.getSequenceAt(i))
655 .getSequencesInOrder(jal);
657 for (int h = 0; h < reps.length; h++)
659 if (reps[h] != jal.getSequenceAt(i))
661 jseq.addHiddenSequences(jal.findIndex(reps[h]));
668 if (jdatasq.getSequenceFeatures() != null)
670 jalview.datamodel.SequenceFeature[] sf = jdatasq
671 .getSequenceFeatures();
673 while (index < sf.length)
675 Features features = new Features();
677 features.setBegin(sf[index].getBegin());
678 features.setEnd(sf[index].getEnd());
679 features.setDescription(sf[index].getDescription());
680 features.setType(sf[index].getType());
681 features.setFeatureGroup(sf[index].getFeatureGroup());
682 features.setScore(sf[index].getScore());
683 if (sf[index].links != null)
685 for (int l = 0; l < sf[index].links.size(); l++)
687 OtherData keyValue = new OtherData();
688 keyValue.setKey("LINK_" + l);
689 keyValue.setValue(sf[index].links.elementAt(l).toString());
690 features.addOtherData(keyValue);
693 if (sf[index].otherDetails != null)
696 Enumeration keys = sf[index].otherDetails.keys();
697 while (keys.hasMoreElements())
699 key = keys.nextElement().toString();
700 OtherData keyValue = new OtherData();
701 keyValue.setKey(key);
702 keyValue.setValue(sf[index].otherDetails.get(key).toString());
703 features.addOtherData(keyValue);
707 jseq.addFeatures(features);
712 if (jdatasq.getPDBId() != null)
714 Enumeration en = jdatasq.getPDBId().elements();
715 while (en.hasMoreElements())
717 Pdbids pdb = new Pdbids();
718 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
721 pdb.setId(entry.getId());
722 pdb.setType(entry.getType());
724 // store any JMol views associated with this sequence
725 // this section copes with duplicate entries in the project, so a
726 // dataset only view *should* be coped with sensibly
727 List<String> jmolViewIds = new ArrayList<String>();
728 // This must have been loaded, is it still visible?
729 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
730 String matchedFile = null;
731 for (int f = frames.length - 1; f > -1; f--)
733 if (frames[f] instanceof GStructureViewer)
735 GStructureViewer viewFrame = (GStructureViewer) frames[f];
736 matchedFile = saveStructureState(ap, jds, pdb, entry,
737 jmolViewIds, matchedFile, viewFrame);
741 if (matchedFile != null || entry.getFile() != null)
743 if (entry.getFile() != null)
746 matchedFile = entry.getFile();
748 pdb.setFile(matchedFile); // entry.getFile());
749 if (pdbfiles == null)
751 pdbfiles = new Vector();
754 if (!pdbfiles.contains(entry.getId()))
756 pdbfiles.addElement(entry.getId());
759 File file = new File(matchedFile);
760 if (file.exists() && jout != null)
762 byte[] data = new byte[(int) file.length()];
763 jout.putNextEntry(new JarEntry(entry.getId()));
764 DataInputStream dis = new DataInputStream(
765 new FileInputStream(file));
768 DataOutputStream dout = new DataOutputStream(jout);
769 dout.write(data, 0, data.length);
773 } catch (Exception ex)
775 ex.printStackTrace();
781 if (entry.getProperty() != null)
783 PdbentryItem item = new PdbentryItem();
784 Hashtable properties = entry.getProperty();
785 Enumeration en2 = properties.keys();
786 while (en2.hasMoreElements())
788 Property prop = new Property();
789 String key = en2.nextElement().toString();
791 prop.setValue(properties.get(key).toString());
792 item.addProperty(prop);
794 pdb.addPdbentryItem(item);
804 if (!storeDS && av.hasHiddenRows())
806 jal = av.getAlignment();
809 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
811 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
812 for (int i = 0; i < jac.length; i++)
814 AlcodonFrame alc = new AlcodonFrame();
815 vamsasSet.addAlcodonFrame(alc);
816 for (int p = 0; p < jac[i].aaWidth; p++)
818 Alcodon cmap = new Alcodon();
819 if (jac[i].codons[p] != null)
821 // Null codons indicate a gapped column in the translated peptide
823 cmap.setPos1(jac[i].codons[p][0]);
824 cmap.setPos2(jac[i].codons[p][1]);
825 cmap.setPos3(jac[i].codons[p][2]);
827 alc.addAlcodon(cmap);
829 if (jac[i].getProtMappings() != null
830 && jac[i].getProtMappings().length > 0)
832 SequenceI[] dnas = jac[i].getdnaSeqs();
833 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
834 for (int m = 0; m < pmaps.length; m++)
836 AlcodMap alcmap = new AlcodMap();
837 alcmap.setDnasq(seqHash(dnas[m]));
838 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
840 alc.addAlcodMap(alcmap);
847 // /////////////////////////////////
848 if (!storeDS && av.currentTree != null)
850 // FIND ANY ASSOCIATED TREES
851 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
852 if (Desktop.desktop != null)
854 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
856 for (int t = 0; t < frames.length; t++)
858 if (frames[t] instanceof TreePanel)
860 TreePanel tp = (TreePanel) frames[t];
862 if (tp.treeCanvas.av.getAlignment() == jal)
864 Tree tree = new Tree();
865 tree.setTitle(tp.getTitle());
866 tree.setCurrentTree((av.currentTree == tp.getTree()));
867 tree.setNewick(tp.getTree().toString());
868 tree.setThreshold(tp.treeCanvas.threshold);
870 tree.setFitToWindow(tp.fitToWindow.getState());
871 tree.setFontName(tp.getTreeFont().getName());
872 tree.setFontSize(tp.getTreeFont().getSize());
873 tree.setFontStyle(tp.getTreeFont().getStyle());
874 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
876 tree.setShowBootstrap(tp.bootstrapMenu.getState());
877 tree.setShowDistances(tp.distanceMenu.getState());
879 tree.setHeight(tp.getHeight());
880 tree.setWidth(tp.getWidth());
881 tree.setXpos(tp.getX());
882 tree.setYpos(tp.getY());
883 tree.setId(makeHashCode(tp, null));
892 * store forward refs from an annotationRow to any groups
894 IdentityHashMap groupRefs = new IdentityHashMap();
897 for (SequenceI sq : jal.getSequences())
899 // Store annotation on dataset sequences only
900 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
901 if (aa != null && aa.length > 0)
903 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
910 if (jal.getAlignmentAnnotation() != null)
912 // Store the annotation shown on the alignment.
913 jalview.datamodel.AlignmentAnnotation[] aa = jal
914 .getAlignmentAnnotation();
915 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
920 if (jal.getGroups() != null)
922 JGroup[] groups = new JGroup[jal.getGroups().size()];
924 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
926 groups[++i] = new JGroup();
928 groups[i].setStart(sg.getStartRes());
929 groups[i].setEnd(sg.getEndRes());
930 groups[i].setName(sg.getName());
931 if (groupRefs.containsKey(sg))
933 // group has references so set it's ID field
934 groups[i].setId(groupRefs.get(sg).toString());
938 if (sg.cs.conservationApplied())
940 groups[i].setConsThreshold(sg.cs.getConservationInc());
942 if (sg.cs instanceof jalview.schemes.UserColourScheme)
944 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
950 .setColour(ColourSchemeProperty.getColourName(sg.cs));
953 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
955 groups[i].setColour("AnnotationColourGradient");
956 groups[i].setAnnotationColours(constructAnnotationColours(
957 (jalview.schemes.AnnotationColourGradient) sg.cs,
960 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
963 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
967 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
970 groups[i].setPidThreshold(sg.cs.getThreshold());
973 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
974 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
975 groups[i].setDisplayText(sg.getDisplayText());
976 groups[i].setColourText(sg.getColourText());
977 groups[i].setTextCol1(sg.textColour.getRGB());
978 groups[i].setTextCol2(sg.textColour2.getRGB());
979 groups[i].setTextColThreshold(sg.thresholdTextColour);
980 groups[i].setShowUnconserved(sg.getShowNonconserved());
981 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
982 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
983 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
984 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
985 for (int s = 0; s < sg.getSize(); s++)
987 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
989 groups[i].addSeq(seqHash(seq));
993 jms.setJGroup(groups);
997 // /////////SAVE VIEWPORT
998 Viewport view = new Viewport();
999 view.setTitle(ap.alignFrame.getTitle());
1000 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1001 av.getSequenceSetId()));
1002 view.setId(av.getViewId());
1003 view.setViewName(av.viewName);
1004 view.setGatheredViews(av.gatherViewsHere);
1006 if (ap.av.explodedPosition != null)
1008 view.setXpos(av.explodedPosition.x);
1009 view.setYpos(av.explodedPosition.y);
1010 view.setWidth(av.explodedPosition.width);
1011 view.setHeight(av.explodedPosition.height);
1015 view.setXpos(ap.alignFrame.getBounds().x);
1016 view.setYpos(ap.alignFrame.getBounds().y);
1017 view.setWidth(ap.alignFrame.getBounds().width);
1018 view.setHeight(ap.alignFrame.getBounds().height);
1021 view.setStartRes(av.startRes);
1022 view.setStartSeq(av.startSeq);
1024 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1026 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1029 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1031 AnnotationColours ac = constructAnnotationColours(
1032 (jalview.schemes.AnnotationColourGradient) av
1033 .getGlobalColourScheme(),
1036 view.setAnnotationColours(ac);
1037 view.setBgColour("AnnotationColourGradient");
1041 view.setBgColour(ColourSchemeProperty.getColourName(av
1042 .getGlobalColourScheme()));
1045 ColourSchemeI cs = av.getGlobalColourScheme();
1049 if (cs.conservationApplied())
1051 view.setConsThreshold(cs.getConservationInc());
1052 if (cs instanceof jalview.schemes.UserColourScheme)
1054 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1058 if (cs instanceof ResidueColourScheme)
1060 view.setPidThreshold(cs.getThreshold());
1064 view.setConservationSelected(av.getConservationSelected());
1065 view.setPidSelected(av.getAbovePIDThreshold());
1066 view.setFontName(av.font.getName());
1067 view.setFontSize(av.font.getSize());
1068 view.setFontStyle(av.font.getStyle());
1069 view.setRenderGaps(av.renderGaps);
1070 view.setShowAnnotation(av.getShowAnnotation());
1071 view.setShowBoxes(av.getShowBoxes());
1072 view.setShowColourText(av.getColourText());
1073 view.setShowFullId(av.getShowJVSuffix());
1074 view.setRightAlignIds(av.isRightAlignIds());
1075 view.setShowSequenceFeatures(av.showSequenceFeatures);
1076 view.setShowText(av.getShowText());
1077 view.setShowUnconserved(av.getShowUnconserved());
1078 view.setWrapAlignment(av.getWrapAlignment());
1079 view.setTextCol1(av.textColour.getRGB());
1080 view.setTextCol2(av.textColour2.getRGB());
1081 view.setTextColThreshold(av.thresholdTextColour);
1082 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1083 view.setShowSequenceLogo(av.isShowSequenceLogo());
1084 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1085 view.setShowGroupConsensus(av.isShowGroupConsensus());
1086 view.setShowGroupConservation(av.isShowGroupConservation());
1087 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1088 view.setShowDbRefTooltip(av.isShowDbRefs());
1089 view.setFollowHighlight(av.followHighlight);
1090 view.setFollowSelection(av.followSelection);
1091 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1092 if (av.getFeaturesDisplayed() != null)
1094 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1096 String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder;
1098 Vector settingsAdded = new Vector();
1099 Object gstyle = null;
1100 GraduatedColor gcol = null;
1101 if (renderOrder != null)
1103 for (int ro = 0; ro < renderOrder.length; ro++)
1105 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1106 .getFeatureStyle(renderOrder[ro]);
1107 Setting setting = new Setting();
1108 setting.setType(renderOrder[ro]);
1109 if (gstyle instanceof GraduatedColor)
1111 gcol = (GraduatedColor) gstyle;
1112 setting.setColour(gcol.getMaxColor().getRGB());
1113 setting.setMincolour(gcol.getMinColor().getRGB());
1114 setting.setMin(gcol.getMin());
1115 setting.setMax(gcol.getMax());
1116 setting.setColourByLabel(gcol.isColourByLabel());
1117 setting.setAutoScale(gcol.isAutoScale());
1118 setting.setThreshold(gcol.getThresh());
1119 setting.setThreshstate(gcol.getThreshType());
1123 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1124 .getColour(renderOrder[ro]).getRGB());
1127 setting.setDisplay(av.getFeaturesDisplayed()
1128 .containsKey(renderOrder[ro]));
1129 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1130 .getOrder(renderOrder[ro]);
1133 setting.setOrder(rorder);
1135 fs.addSetting(setting);
1136 settingsAdded.addElement(renderOrder[ro]);
1140 // Make sure we save none displayed feature settings
1141 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureColours
1142 .keySet().iterator();
1143 while (en.hasNext())
1145 String key = en.next().toString();
1146 if (settingsAdded.contains(key))
1151 Setting setting = new Setting();
1152 setting.setType(key);
1153 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1154 .getColour(key).getRGB());
1156 setting.setDisplay(false);
1157 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1161 setting.setOrder(rorder);
1163 fs.addSetting(setting);
1164 settingsAdded.addElement(key);
1166 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups
1167 .keySet().iterator();
1168 Vector groupsAdded = new Vector();
1169 while (en.hasNext())
1171 String grp = en.next().toString();
1172 if (groupsAdded.contains(grp))
1176 Group g = new Group();
1178 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1179 .getFeatureRenderer().featureGroups.get(grp))
1182 groupsAdded.addElement(grp);
1184 jms.setFeatureSettings(fs);
1188 if (av.hasHiddenColumns())
1190 if (av.getColumnSelection() == null
1191 || av.getColumnSelection().getHiddenColumns() == null)
1193 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1197 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1200 int[] region = (int[]) av.getColumnSelection()
1201 .getHiddenColumns().elementAt(c);
1202 HiddenColumns hc = new HiddenColumns();
1203 hc.setStart(region[0]);
1204 hc.setEnd(region[1]);
1205 view.addHiddenColumns(hc);
1209 if (calcIdSet.size() > 0)
1211 for (String calcId : calcIdSet)
1213 if (calcId.trim().length() > 0)
1215 CalcIdParam cidp = createCalcIdParam(calcId, av);
1216 // Some calcIds have no parameters.
1219 view.addCalcIdParam(cidp);
1225 jms.addViewport(view);
1227 object.setJalviewModelSequence(jms);
1228 object.getVamsasModel().addSequenceSet(vamsasSet);
1230 if (jout != null && fileName != null)
1232 // We may not want to write the object to disk,
1233 // eg we can copy the alignViewport to a new view object
1234 // using save and then load
1237 JarEntry entry = new JarEntry(fileName);
1238 jout.putNextEntry(entry);
1239 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1241 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1243 marshaller.marshal(object);
1246 } catch (Exception ex)
1248 // TODO: raise error in GUI if marshalling failed.
1249 ex.printStackTrace();
1260 * @param jmolViewIds
1261 * @param matchedFile
1265 protected String saveStructureState(AlignmentPanel ap,
1266 jalview.datamodel.SequenceI jds, Pdbids pdb,
1267 jalview.datamodel.PDBEntry entry, List<String> jmolViewIds,
1268 String matchedFile, GStructureViewer viewFrame)
1270 final AAStructureBindingModel bindingModel = viewFrame
1272 for (int peid = 0; peid < bindingModel
1273 .getPdbCount(); peid++)
1275 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1276 final String pdbId = pdbentry.getId();
1277 if (!pdbId.equals(entry.getId())
1278 && !(entry.getId().length() > 4 && entry.getId()
1280 .startsWith(pdbId.toLowerCase())))
1284 if (matchedFile == null)
1286 matchedFile = pdbentry.getFile();
1288 else if (!matchedFile.equals(pdbentry
1292 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1293 + pdbentry.getFile());
1297 // can get at it if the ID
1298 // match is ambiguous (e.g.
1300 String statestring = viewFrame.getStateInfo();
1302 for (int smap = 0; smap < viewFrame.getBinding()
1303 .getSequence()[peid].length; smap++)
1305 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1306 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1308 StructureState state = new StructureState();
1309 state.setVisible(true);
1310 state.setXpos(viewFrame.getX());
1311 state.setYpos(viewFrame.getY());
1312 state.setWidth(viewFrame.getWidth());
1313 state.setHeight(viewFrame.getHeight());
1314 state.setViewId(viewFrame.getViewId());
1315 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1316 state.setColourwithAlignPanel(viewFrame
1317 .isUsedforcolourby(ap));
1318 state.setColourByJmol(viewFrame.isColouredByViewer());
1319 if (!jmolViewIds.contains(state.getViewId()))
1321 // Make sure we only store a Jmol state once in each XML
1323 jmolViewIds.add(state.getViewId());
1324 state.setContent(statestring.replaceAll("\n", ""));
1328 state.setContent("# duplicate state");
1330 pdb.addStructureState(state);
1338 private AnnotationColours constructAnnotationColours(
1339 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1340 JalviewModelSequence jms)
1342 AnnotationColours ac = new AnnotationColours();
1343 ac.setAboveThreshold(acg.getAboveThreshold());
1344 ac.setThreshold(acg.getAnnotationThreshold());
1345 ac.setAnnotation(acg.getAnnotation());
1346 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1348 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1353 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1357 ac.setMaxColour(acg.getMaxColour().getRGB());
1358 ac.setMinColour(acg.getMinColour().getRGB());
1359 ac.setPerSequence(acg.isSeqAssociated());
1360 ac.setPredefinedColours(acg.isPredefinedColours());
1364 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1365 IdentityHashMap groupRefs, AlignmentViewport av,
1366 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1369 for (int i = 0; i < aa.length; i++)
1371 Annotation an = new Annotation();
1373 if (aa[i].annotationId != null)
1375 annotationIds.put(aa[i].annotationId, aa[i]);
1378 an.setId(aa[i].annotationId);
1380 an.setVisible(aa[i].visible);
1382 an.setDescription(aa[i].description);
1384 if (aa[i].sequenceRef != null)
1386 // TODO later annotation sequenceRef should be the XML ID of the
1387 // sequence rather than its display name
1388 an.setSequenceRef(aa[i].sequenceRef.getName());
1390 if (aa[i].groupRef != null)
1392 Object groupIdr = groupRefs.get(aa[i].groupRef);
1393 if (groupIdr == null)
1395 // make a locally unique String
1396 groupRefs.put(aa[i].groupRef,
1397 groupIdr = ("" + System.currentTimeMillis()
1398 + aa[i].groupRef.getName() + groupRefs.size()));
1400 an.setGroupRef(groupIdr.toString());
1403 // store all visualization attributes for annotation
1404 an.setGraphHeight(aa[i].graphHeight);
1405 an.setCentreColLabels(aa[i].centreColLabels);
1406 an.setScaleColLabels(aa[i].scaleColLabel);
1407 an.setShowAllColLabels(aa[i].showAllColLabels);
1408 an.setBelowAlignment(aa[i].belowAlignment);
1410 if (aa[i].graph > 0)
1413 an.setGraphType(aa[i].graph);
1414 an.setGraphGroup(aa[i].graphGroup);
1415 if (aa[i].getThreshold() != null)
1417 ThresholdLine line = new ThresholdLine();
1418 line.setLabel(aa[i].getThreshold().label);
1419 line.setValue(aa[i].getThreshold().value);
1420 line.setColour(aa[i].getThreshold().colour.getRGB());
1421 an.setThresholdLine(line);
1429 an.setLabel(aa[i].label);
1431 if (aa[i] == av.getAlignmentQualityAnnot()
1432 || aa[i] == av.getAlignmentConservationAnnotation()
1433 || aa[i] == av.getAlignmentConsensusAnnotation()
1434 || aa[i].autoCalculated)
1436 // new way of indicating autocalculated annotation -
1437 an.setAutoCalculated(aa[i].autoCalculated);
1439 if (aa[i].hasScore())
1441 an.setScore(aa[i].getScore());
1444 if (aa[i].getCalcId() != null)
1446 calcIdSet.add(aa[i].getCalcId());
1447 an.setCalcId(aa[i].getCalcId());
1449 if (aa[i].hasProperties())
1451 for (String pr : aa[i].getProperties())
1453 Property prop = new Property();
1455 prop.setValue(aa[i].getProperty(pr));
1456 an.addProperty(prop);
1459 AnnotationElement ae;
1460 if (aa[i].annotations != null)
1462 an.setScoreOnly(false);
1463 for (int a = 0; a < aa[i].annotations.length; a++)
1465 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1470 ae = new AnnotationElement();
1471 if (aa[i].annotations[a].description != null)
1473 ae.setDescription(aa[i].annotations[a].description);
1475 if (aa[i].annotations[a].displayCharacter != null)
1477 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1480 if (!Float.isNaN(aa[i].annotations[a].value))
1482 ae.setValue(aa[i].annotations[a].value);
1486 if (aa[i].annotations[a].secondaryStructure > ' ')
1488 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1492 if (aa[i].annotations[a].colour != null
1493 && aa[i].annotations[a].colour != java.awt.Color.black)
1495 ae.setColour(aa[i].annotations[a].colour.getRGB());
1498 an.addAnnotationElement(ae);
1499 if (aa[i].autoCalculated)
1501 // only write one non-null entry into the annotation row -
1502 // sufficient to get the visualization attributes necessary to
1510 an.setScoreOnly(true);
1512 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1514 // skip autocalculated annotation - these are only provided for
1516 vamsasSet.addAnnotation(an);
1522 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1524 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1525 if (settings != null)
1527 CalcIdParam vCalcIdParam = new CalcIdParam();
1528 vCalcIdParam.setCalcId(calcId);
1529 vCalcIdParam.addServiceURL(settings.getServiceURI());
1530 // generic URI allowing a third party to resolve another instance of the
1531 // service used for this calculation
1532 for (String urls : settings.getServiceURLs())
1534 vCalcIdParam.addServiceURL(urls);
1536 vCalcIdParam.setVersion("1.0");
1537 if (settings.getPreset() != null)
1539 WsParamSetI setting = settings.getPreset();
1540 vCalcIdParam.setName(setting.getName());
1541 vCalcIdParam.setDescription(setting.getDescription());
1545 vCalcIdParam.setName("");
1546 vCalcIdParam.setDescription("Last used parameters");
1548 // need to be able to recover 1) settings 2) user-defined presets or
1549 // recreate settings from preset 3) predefined settings provided by
1550 // service - or settings that can be transferred (or discarded)
1551 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1553 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1554 // todo - decide if updateImmediately is needed for any projects.
1556 return vCalcIdParam;
1561 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1564 if (calcIdParam.getVersion().equals("1.0"))
1566 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1567 .getPreferredServiceFor(calcIdParam.getServiceURL());
1568 if (service != null)
1570 WsParamSetI parmSet = null;
1573 parmSet = service.getParamStore().parseServiceParameterFile(
1574 calcIdParam.getName(), calcIdParam.getDescription(),
1575 calcIdParam.getServiceURL(),
1576 calcIdParam.getParameters().replace("|\\n|", "\n"));
1577 } catch (IOException x)
1579 warn("Couldn't parse parameter data for "
1580 + calcIdParam.getCalcId(), x);
1583 List<ArgumentI> argList = null;
1584 if (calcIdParam.getName().length() > 0)
1586 parmSet = service.getParamStore()
1587 .getPreset(calcIdParam.getName());
1588 if (parmSet != null)
1590 // TODO : check we have a good match with settings in AACon -
1591 // otherwise we'll need to create a new preset
1596 argList = parmSet.getArguments();
1599 AAConSettings settings = new AAConSettings(
1600 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1601 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1602 calcIdParam.isNeedsUpdate());
1607 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1611 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1615 * External mapping between jalview objects and objects yielding a valid and
1616 * unique object ID string. This is null for normal Jalview project IO, but
1617 * non-null when a jalview project is being read or written as part of a
1620 IdentityHashMap jv2vobj = null;
1623 * Construct a unique ID for jvobj using either existing bindings or if none
1624 * exist, the result of the hashcode call for the object.
1627 * jalview data object
1628 * @return unique ID for referring to jvobj
1630 private String makeHashCode(Object jvobj, String altCode)
1632 if (jv2vobj != null)
1634 Object id = jv2vobj.get(jvobj);
1637 return id.toString();
1639 // check string ID mappings
1640 if (jvids2vobj != null && jvobj instanceof String)
1642 id = jvids2vobj.get(jvobj);
1646 return id.toString();
1648 // give up and warn that something has gone wrong
1649 warn("Cannot find ID for object in external mapping : " + jvobj);
1655 * return local jalview object mapped to ID, if it exists
1659 * @return null or object bound to idcode
1661 private Object retrieveExistingObj(String idcode)
1663 if (idcode != null && vobj2jv != null)
1665 return vobj2jv.get(idcode);
1671 * binding from ID strings from external mapping table to jalview data model
1674 private Hashtable vobj2jv;
1676 private Sequence createVamsasSequence(String id, SequenceI jds)
1678 return createVamsasSequence(true, id, jds, null);
1681 private Sequence createVamsasSequence(boolean recurse, String id,
1682 SequenceI jds, SequenceI parentseq)
1684 Sequence vamsasSeq = new Sequence();
1685 vamsasSeq.setId(id);
1686 vamsasSeq.setName(jds.getName());
1687 vamsasSeq.setSequence(jds.getSequenceAsString());
1688 vamsasSeq.setDescription(jds.getDescription());
1689 jalview.datamodel.DBRefEntry[] dbrefs = null;
1690 if (jds.getDatasetSequence() != null)
1692 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1693 if (jds.getDatasetSequence().getDBRef() != null)
1695 dbrefs = jds.getDatasetSequence().getDBRef();
1700 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1701 // dataset sequences only
1702 dbrefs = jds.getDBRef();
1706 for (int d = 0; d < dbrefs.length; d++)
1708 DBRef dbref = new DBRef();
1709 dbref.setSource(dbrefs[d].getSource());
1710 dbref.setVersion(dbrefs[d].getVersion());
1711 dbref.setAccessionId(dbrefs[d].getAccessionId());
1712 if (dbrefs[d].hasMap())
1714 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1716 dbref.setMapping(mp);
1718 vamsasSeq.addDBRef(dbref);
1724 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1725 SequenceI parentseq, SequenceI jds, boolean recurse)
1728 if (jmp.getMap() != null)
1732 jalview.util.MapList mlst = jmp.getMap();
1733 int r[] = mlst.getFromRanges();
1734 for (int s = 0; s < r.length; s += 2)
1736 MapListFrom mfrom = new MapListFrom();
1737 mfrom.setStart(r[s]);
1738 mfrom.setEnd(r[s + 1]);
1739 mp.addMapListFrom(mfrom);
1741 r = mlst.getToRanges();
1742 for (int s = 0; s < r.length; s += 2)
1744 MapListTo mto = new MapListTo();
1746 mto.setEnd(r[s + 1]);
1747 mp.addMapListTo(mto);
1749 mp.setMapFromUnit(mlst.getFromRatio());
1750 mp.setMapToUnit(mlst.getToRatio());
1751 if (jmp.getTo() != null)
1753 MappingChoice mpc = new MappingChoice();
1755 && (parentseq != jmp.getTo() || parentseq
1756 .getDatasetSequence() != jmp.getTo()))
1758 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1764 SequenceI ps = null;
1765 if (parentseq != jmp.getTo()
1766 && parentseq.getDatasetSequence() != jmp.getTo())
1768 // chaining dbref rather than a handshaking one
1769 jmpid = seqHash(ps = jmp.getTo());
1773 jmpid = seqHash(ps = parentseq);
1775 mpc.setDseqFor(jmpid);
1776 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1778 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1779 seqRefIds.put(mpc.getDseqFor(), ps);
1783 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1786 mp.setMappingChoice(mpc);
1792 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1793 List<UserColourScheme> userColours, JalviewModelSequence jms)
1796 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1797 boolean newucs = false;
1798 if (!userColours.contains(ucs))
1800 userColours.add(ucs);
1803 id = "ucs" + userColours.indexOf(ucs);
1806 // actually create the scheme's entry in the XML model
1807 java.awt.Color[] colours = ucs.getColours();
1808 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1809 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1811 for (int i = 0; i < colours.length; i++)
1813 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1814 col.setName(ResidueProperties.aa[i]);
1815 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1816 jbucs.addColour(col);
1818 if (ucs.getLowerCaseColours() != null)
1820 colours = ucs.getLowerCaseColours();
1821 for (int i = 0; i < colours.length; i++)
1823 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1824 col.setName(ResidueProperties.aa[i].toLowerCase());
1825 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1826 jbucs.addColour(col);
1831 uc.setUserColourScheme(jbucs);
1832 jms.addUserColours(uc);
1838 jalview.schemes.UserColourScheme GetUserColourScheme(
1839 JalviewModelSequence jms, String id)
1841 UserColours[] uc = jms.getUserColours();
1842 UserColours colours = null;
1844 for (int i = 0; i < uc.length; i++)
1846 if (uc[i].getId().equals(id))
1854 java.awt.Color[] newColours = new java.awt.Color[24];
1856 for (int i = 0; i < 24; i++)
1858 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1859 .getUserColourScheme().getColour(i).getRGB(), 16));
1862 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1865 if (colours.getUserColourScheme().getColourCount() > 24)
1867 newColours = new java.awt.Color[23];
1868 for (int i = 0; i < 23; i++)
1870 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1871 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1873 ucs.setLowerCaseColours(newColours);
1880 * contains last error message (if any) encountered by XML loader.
1882 String errorMessage = null;
1885 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1886 * exceptions are raised during project XML parsing
1888 public boolean attemptversion1parse = true;
1891 * Load a jalview project archive from a jar file
1894 * - HTTP URL or filename
1896 public AlignFrame LoadJalviewAlign(final String file)
1899 jalview.gui.AlignFrame af = null;
1903 // create list to store references for any new Jmol viewers created
1904 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1905 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1906 // Workaround is to make sure caller implements the JarInputStreamProvider
1908 // so we can re-open the jar input stream for each entry.
1910 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1911 af = LoadJalviewAlign(jprovider);
1913 } catch (MalformedURLException e)
1915 errorMessage = "Invalid URL format for '" + file + "'";
1921 SwingUtilities.invokeAndWait(new Runnable()
1925 setLoadingFinishedForNewStructureViewers();
1928 } catch (Exception x)
1936 private jarInputStreamProvider createjarInputStreamProvider(
1937 final String file) throws MalformedURLException
1940 errorMessage = null;
1941 uniqueSetSuffix = null;
1943 viewportsAdded = null;
1944 frefedSequence = null;
1946 if (file.startsWith("http://"))
1948 url = new URL(file);
1950 final URL _url = url;
1951 return new jarInputStreamProvider()
1955 public JarInputStream getJarInputStream() throws IOException
1959 return new JarInputStream(_url.openStream());
1963 return new JarInputStream(new FileInputStream(file));
1968 public String getFilename()
1976 * Recover jalview session from a jalview project archive. Caller may
1977 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1978 * themselves. Any null fields will be initialised with default values,
1979 * non-null fields are left alone.
1984 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1986 errorMessage = null;
1987 if (uniqueSetSuffix == null)
1989 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1991 if (seqRefIds == null)
1993 seqRefIds = new Hashtable();
1995 if (viewportsAdded == null)
1997 viewportsAdded = new Hashtable();
1999 if (frefedSequence == null)
2001 frefedSequence = new Vector();
2004 jalview.gui.AlignFrame af = null, _af = null;
2005 Hashtable gatherToThisFrame = new Hashtable();
2006 final String file = jprovider.getFilename();
2009 JarInputStream jin = null;
2010 JarEntry jarentry = null;
2015 jin = jprovider.getJarInputStream();
2016 for (int i = 0; i < entryCount; i++)
2018 jarentry = jin.getNextJarEntry();
2021 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2023 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2024 JalviewModel object = new JalviewModel();
2026 Unmarshaller unmar = new Unmarshaller(object);
2027 unmar.setValidation(false);
2028 object = (JalviewModel) unmar.unmarshal(in);
2029 if (true) // !skipViewport(object))
2031 _af = LoadFromObject(object, file, true, jprovider);
2032 if (object.getJalviewModelSequence().getViewportCount() > 0)
2035 if (af.viewport.gatherViewsHere)
2037 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2043 else if (jarentry != null)
2045 // Some other file here.
2048 } while (jarentry != null);
2049 resolveFrefedSequences();
2050 } catch (java.io.FileNotFoundException ex)
2052 ex.printStackTrace();
2053 errorMessage = "Couldn't locate Jalview XML file : " + file;
2054 System.err.println("Exception whilst loading jalview XML file : "
2056 } catch (java.net.UnknownHostException ex)
2058 ex.printStackTrace();
2059 errorMessage = "Couldn't locate Jalview XML file : " + file;
2060 System.err.println("Exception whilst loading jalview XML file : "
2062 } catch (Exception ex)
2064 System.err.println("Parsing as Jalview Version 2 file failed.");
2065 ex.printStackTrace(System.err);
2066 if (attemptversion1parse)
2068 // Is Version 1 Jar file?
2071 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2072 } catch (Exception ex2)
2074 System.err.println("Exception whilst loading as jalviewXMLV1:");
2075 ex2.printStackTrace();
2079 if (Desktop.instance != null)
2081 Desktop.instance.stopLoading();
2085 System.out.println("Successfully loaded archive file");
2088 ex.printStackTrace();
2090 System.err.println("Exception whilst loading jalview XML file : "
2092 } catch (OutOfMemoryError e)
2094 // Don't use the OOM Window here
2095 errorMessage = "Out of memory loading jalview XML file";
2096 System.err.println("Out of memory whilst loading jalview XML file");
2097 e.printStackTrace();
2100 if (Desktop.instance != null)
2102 Desktop.instance.stopLoading();
2105 Enumeration en = gatherToThisFrame.elements();
2106 while (en.hasMoreElements())
2108 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2110 if (errorMessage != null)
2118 * check errorMessage for a valid error message and raise an error box in the
2119 * GUI or write the current errorMessage to stderr and then clear the error
2122 protected void reportErrors()
2124 reportErrors(false);
2127 protected void reportErrors(final boolean saving)
2129 if (errorMessage != null)
2131 final String finalErrorMessage = errorMessage;
2134 javax.swing.SwingUtilities.invokeLater(new Runnable()
2139 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2140 finalErrorMessage, "Error "
2141 + (saving ? "saving" : "loading")
2142 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2148 System.err.println("Problem loading Jalview file: " + errorMessage);
2151 errorMessage = null;
2154 Hashtable<String, String> alreadyLoadedPDB;
2157 * when set, local views will be updated from view stored in JalviewXML
2158 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2159 * sync if this is set to true.
2161 private final boolean updateLocalViews = false;
2163 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2165 if (alreadyLoadedPDB == null)
2167 alreadyLoadedPDB = new Hashtable();
2170 if (alreadyLoadedPDB.containsKey(pdbId))
2172 return alreadyLoadedPDB.get(pdbId).toString();
2177 JarInputStream jin = jprovider.getJarInputStream();
2179 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2180 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2181 * FileInputStream(jprovider)); }
2184 JarEntry entry = null;
2187 entry = jin.getNextJarEntry();
2188 } while (entry != null && !entry.getName().equals(pdbId));
2191 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2192 File outFile = File.createTempFile("jalview_pdb", ".txt");
2193 outFile.deleteOnExit();
2194 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2197 while ((data = in.readLine()) != null)
2204 } catch (Exception foo)
2209 String t = outFile.getAbsolutePath();
2210 alreadyLoadedPDB.put(pdbId, t);
2215 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2217 } catch (Exception ex)
2219 ex.printStackTrace();
2225 private class JvAnnotRow
2227 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2234 * persisted version of annotation row from which to take vis properties
2236 public jalview.datamodel.AlignmentAnnotation template;
2239 * original position of the annotation row in the alignment
2245 * Load alignment frame from jalview XML DOM object
2250 * filename source string
2251 * @param loadTreesAndStructures
2252 * when false only create Viewport
2254 * data source provider
2255 * @return alignment frame created from view stored in DOM
2257 AlignFrame LoadFromObject(JalviewModel object, String file,
2258 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2260 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2261 Sequence[] vamsasSeq = vamsasSet.getSequence();
2263 JalviewModelSequence jms = object.getJalviewModelSequence();
2265 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2268 // ////////////////////////////////
2271 Vector hiddenSeqs = null;
2272 jalview.datamodel.Sequence jseq;
2274 ArrayList tmpseqs = new ArrayList();
2276 boolean multipleView = false;
2278 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2279 int vi = 0; // counter in vamsasSeq array
2280 for (int i = 0; i < JSEQ.length; i++)
2282 String seqId = JSEQ[i].getId();
2284 if (seqRefIds.get(seqId) != null)
2286 tmpseqs.add(seqRefIds.get(seqId));
2287 multipleView = true;
2291 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2292 vamsasSeq[vi].getSequence());
2293 jseq.setDescription(vamsasSeq[vi].getDescription());
2294 jseq.setStart(JSEQ[i].getStart());
2295 jseq.setEnd(JSEQ[i].getEnd());
2296 jseq.setVamsasId(uniqueSetSuffix + seqId);
2297 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2302 if (JSEQ[i].getHidden())
2304 if (hiddenSeqs == null)
2306 hiddenSeqs = new Vector();
2309 hiddenSeqs.addElement(seqRefIds.get(seqId));
2315 // Create the alignment object from the sequence set
2316 // ///////////////////////////////
2317 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2320 tmpseqs.toArray(orderedSeqs);
2322 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2325 // / Add the alignment properties
2326 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2328 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2329 al.setProperty(ssp.getKey(), ssp.getValue());
2333 // SequenceFeatures are added to the DatasetSequence,
2334 // so we must create or recover the dataset before loading features
2335 // ///////////////////////////////
2336 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2338 // older jalview projects do not have a dataset id.
2339 al.setDataset(null);
2343 // recover dataset - passing on flag indicating if this a 'viewless'
2344 // sequence set (a.k.a. a stored dataset for the project)
2345 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2346 .getViewportCount() == 0);
2348 // ///////////////////////////////
2350 Hashtable pdbloaded = new Hashtable();
2353 // load sequence features, database references and any associated PDB
2354 // structures for the alignment
2355 for (int i = 0; i < vamsasSeq.length; i++)
2357 if (JSEQ[i].getFeaturesCount() > 0)
2359 Features[] features = JSEQ[i].getFeatures();
2360 for (int f = 0; f < features.length; f++)
2362 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2363 features[f].getType(), features[f].getDescription(),
2364 features[f].getStatus(), features[f].getBegin(),
2365 features[f].getEnd(), features[f].getFeatureGroup());
2367 sf.setScore(features[f].getScore());
2368 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2370 OtherData keyValue = features[f].getOtherData(od);
2371 if (keyValue.getKey().startsWith("LINK"))
2373 sf.addLink(keyValue.getValue());
2377 sf.setValue(keyValue.getKey(), keyValue.getValue());
2382 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2385 if (vamsasSeq[i].getDBRefCount() > 0)
2387 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2389 if (JSEQ[i].getPdbidsCount() > 0)
2391 Pdbids[] ids = JSEQ[i].getPdbids();
2392 for (int p = 0; p < ids.length; p++)
2394 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2395 entry.setId(ids[p].getId());
2396 entry.setType(ids[p].getType());
2397 if (ids[p].getFile() != null)
2399 if (!pdbloaded.containsKey(ids[p].getFile()))
2401 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2405 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2408 StructureSelectionManager.getStructureSelectionManager(
2410 .registerPDBEntry(entry);
2411 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2415 } // end !multipleview
2417 // ///////////////////////////////
2418 // LOAD SEQUENCE MAPPINGS
2420 if (vamsasSet.getAlcodonFrameCount() > 0)
2422 // TODO Potentially this should only be done once for all views of an
2424 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2425 for (int i = 0; i < alc.length; i++)
2427 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2428 alc[i].getAlcodonCount());
2429 if (alc[i].getAlcodonCount() > 0)
2431 Alcodon[] alcods = alc[i].getAlcodon();
2432 for (int p = 0; p < cf.codons.length; p++)
2434 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2435 && alcods[p].hasPos3())
2437 // translated codons require three valid positions
2438 cf.codons[p] = new int[3];
2439 cf.codons[p][0] = (int) alcods[p].getPos1();
2440 cf.codons[p][1] = (int) alcods[p].getPos2();
2441 cf.codons[p][2] = (int) alcods[p].getPos3();
2445 cf.codons[p] = null;
2449 if (alc[i].getAlcodMapCount() > 0)
2451 AlcodMap[] maps = alc[i].getAlcodMap();
2452 for (int m = 0; m < maps.length; m++)
2454 SequenceI dnaseq = (SequenceI) seqRefIds
2455 .get(maps[m].getDnasq());
2457 jalview.datamodel.Mapping mapping = null;
2458 // attach to dna sequence reference.
2459 if (maps[m].getMapping() != null)
2461 mapping = addMapping(maps[m].getMapping());
2465 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2470 frefedSequence.add(new Object[]
2471 { maps[m].getDnasq(), cf, mapping });
2475 al.addCodonFrame(cf);
2480 // ////////////////////////////////
2482 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2484 * store any annotations which forward reference a group's ID
2486 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2488 if (vamsasSet.getAnnotationCount() > 0)
2490 Annotation[] an = vamsasSet.getAnnotation();
2492 for (int i = 0; i < an.length; i++)
2495 * test if annotation is automatically calculated for this view only
2497 boolean autoForView = false;
2498 if (an[i].getLabel().equals("Quality")
2499 || an[i].getLabel().equals("Conservation")
2500 || an[i].getLabel().equals("Consensus"))
2502 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2504 if (!an[i].hasAutoCalculated())
2506 an[i].setAutoCalculated(true);
2510 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2512 // remove ID - we don't recover annotation from other views for
2513 // view-specific annotation
2517 // set visiblity for other annotation in this view
2518 if (an[i].getId() != null
2519 && annotationIds.containsKey(an[i].getId()))
2521 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2522 .get(an[i].getId());
2523 // in principle Visible should always be true for annotation displayed
2524 // in multiple views
2525 if (an[i].hasVisible())
2527 jda.visible = an[i].getVisible();
2530 al.addAnnotation(jda);
2534 // Construct new annotation from model.
2535 AnnotationElement[] ae = an[i].getAnnotationElement();
2536 jalview.datamodel.Annotation[] anot = null;
2537 java.awt.Color firstColour = null;
2539 if (!an[i].getScoreOnly())
2541 anot = new jalview.datamodel.Annotation[al.getWidth()];
2542 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2544 anpos = ae[aa].getPosition();
2546 if (anpos >= anot.length)
2551 anot[anpos] = new jalview.datamodel.Annotation(
2553 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2554 (ae[aa].getSecondaryStructure() == null || ae[aa]
2555 .getSecondaryStructure().length() == 0) ? ' '
2556 : ae[aa].getSecondaryStructure().charAt(0),
2560 // JBPNote: Consider verifying dataflow for IO of secondary
2561 // structure annotation read from Stockholm files
2562 // this was added to try to ensure that
2563 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2565 // anot[ae[aa].getPosition()].displayCharacter = "";
2567 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2568 if (firstColour == null)
2570 firstColour = anot[anpos].colour;
2574 jalview.datamodel.AlignmentAnnotation jaa = null;
2576 if (an[i].getGraph())
2578 float llim = 0, hlim = 0;
2579 // if (autoForView || an[i].isAutoCalculated()) {
2582 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2583 an[i].getDescription(), anot, llim, hlim,
2584 an[i].getGraphType());
2586 jaa.graphGroup = an[i].getGraphGroup();
2587 jaa._linecolour = firstColour;
2588 if (an[i].getThresholdLine() != null)
2590 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2591 .getThresholdLine().getValue(), an[i]
2592 .getThresholdLine().getLabel(), new java.awt.Color(
2593 an[i].getThresholdLine().getColour())));
2596 if (autoForView || an[i].isAutoCalculated())
2598 // Hardwire the symbol display line to ensure that labels for
2599 // histograms are displayed
2605 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2606 an[i].getDescription(), anot);
2607 jaa._linecolour = firstColour;
2609 // register new annotation
2610 if (an[i].getId() != null)
2612 annotationIds.put(an[i].getId(), jaa);
2613 jaa.annotationId = an[i].getId();
2615 // recover sequence association
2616 if (an[i].getSequenceRef() != null)
2618 if (al.findName(an[i].getSequenceRef()) != null)
2620 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2622 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2625 // and make a note of any group association
2626 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2628 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2629 .get(an[i].getGroupRef());
2632 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2633 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2638 if (an[i].hasScore())
2640 jaa.setScore(an[i].getScore());
2642 if (an[i].hasVisible())
2644 jaa.visible = an[i].getVisible();
2647 if (an[i].hasCentreColLabels())
2649 jaa.centreColLabels = an[i].getCentreColLabels();
2652 if (an[i].hasScaleColLabels())
2654 jaa.scaleColLabel = an[i].getScaleColLabels();
2656 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2658 // newer files have an 'autoCalculated' flag and store calculation
2659 // state in viewport properties
2660 jaa.autoCalculated = true; // means annotation will be marked for
2661 // update at end of load.
2663 if (an[i].hasGraphHeight())
2665 jaa.graphHeight = an[i].getGraphHeight();
2667 if (an[i].hasBelowAlignment())
2669 jaa.belowAlignment = an[i].isBelowAlignment();
2671 jaa.setCalcId(an[i].getCalcId());
2672 if (an[i].getPropertyCount() > 0)
2674 for (jalview.schemabinding.version2.Property prop : an[i]
2677 jaa.setProperty(prop.getName(), prop.getValue());
2680 if (jaa.autoCalculated)
2682 autoAlan.add(new JvAnnotRow(i, jaa));
2685 // if (!autoForView)
2687 // add autocalculated group annotation and any user created annotation
2689 al.addAnnotation(jaa);
2693 // ///////////////////////
2695 // Create alignment markup and styles for this view
2696 if (jms.getJGroupCount() > 0)
2698 JGroup[] groups = jms.getJGroup();
2699 boolean addAnnotSchemeGroup = false;
2700 for (int i = 0; i < groups.length; i++)
2702 ColourSchemeI cs = null;
2704 if (groups[i].getColour() != null)
2706 if (groups[i].getColour().startsWith("ucs"))
2708 cs = GetUserColourScheme(jms, groups[i].getColour());
2710 else if (groups[i].getColour().equals("AnnotationColourGradient")
2711 && groups[i].getAnnotationColours() != null)
2713 addAnnotSchemeGroup = true;
2718 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2723 cs.setThreshold(groups[i].getPidThreshold(), true);
2727 Vector seqs = new Vector();
2729 for (int s = 0; s < groups[i].getSeqCount(); s++)
2731 String seqId = groups[i].getSeq(s) + "";
2732 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2737 seqs.addElement(ts);
2741 if (seqs.size() < 1)
2746 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2747 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2748 groups[i].getDisplayText(), groups[i].getColourText(),
2749 groups[i].getStart(), groups[i].getEnd());
2751 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2753 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2754 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2755 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2756 .isShowUnconserved() : false);
2757 sg.thresholdTextColour = groups[i].getTextColThreshold();
2758 if (groups[i].hasShowConsensusHistogram())
2760 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2763 if (groups[i].hasShowSequenceLogo())
2765 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2767 if (groups[i].hasNormaliseSequenceLogo())
2769 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2771 if (groups[i].hasIgnoreGapsinConsensus())
2773 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2775 if (groups[i].getConsThreshold() != 0)
2777 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2778 "All", ResidueProperties.propHash, 3,
2779 sg.getSequences(null), 0, sg.getWidth() - 1);
2781 c.verdict(false, 25);
2782 sg.cs.setConservation(c);
2785 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2787 // re-instate unique group/annotation row reference
2788 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2789 .get(groups[i].getId());
2792 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2795 if (jaa.autoCalculated)
2797 // match up and try to set group autocalc alignment row for this
2799 if (jaa.label.startsWith("Consensus for "))
2801 sg.setConsensus(jaa);
2803 // match up and try to set group autocalc alignment row for this
2805 if (jaa.label.startsWith("Conservation for "))
2807 sg.setConservationRow(jaa);
2814 if (addAnnotSchemeGroup)
2816 // reconstruct the annotation colourscheme
2817 sg.cs = constructAnnotationColour(
2818 groups[i].getAnnotationColours(), null, al, jms, false);
2824 // only dataset in this model, so just return.
2827 // ///////////////////////////////
2830 // If we just load in the same jar file again, the sequenceSetId
2831 // will be the same, and we end up with multiple references
2832 // to the same sequenceSet. We must modify this id on load
2833 // so that each load of the file gives a unique id
2834 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2835 String viewId = (view.getId() == null ? null : view.getId()
2837 AlignFrame af = null;
2838 AlignViewport av = null;
2839 // now check to see if we really need to create a new viewport.
2840 if (multipleView && viewportsAdded.size() == 0)
2842 // We recovered an alignment for which a viewport already exists.
2843 // TODO: fix up any settings necessary for overlaying stored state onto
2844 // state recovered from another document. (may not be necessary).
2845 // we may need a binding from a viewport in memory to one recovered from
2847 // and then recover its containing af to allow the settings to be applied.
2848 // TODO: fix for vamsas demo
2850 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2852 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2853 if (seqsetobj != null)
2855 if (seqsetobj instanceof String)
2857 uniqueSeqSetId = (String) seqsetobj;
2859 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2865 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2871 * indicate that annotation colours are applied across all groups (pre
2872 * Jalview 2.8.1 behaviour)
2874 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2875 object.getVersion());
2877 AlignmentPanel ap = null;
2878 boolean isnewview = true;
2881 // Check to see if this alignment already has a view id == viewId
2882 jalview.gui.AlignmentPanel views[] = Desktop
2883 .getAlignmentPanels(uniqueSeqSetId);
2884 if (views != null && views.length > 0)
2886 for (int v = 0; v < views.length; v++)
2888 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2890 // recover the existing alignpanel, alignframe, viewport
2891 af = views[v].alignFrame;
2894 // TODO: could even skip resetting view settings if we don't want to
2895 // change the local settings from other jalview processes
2904 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2905 uniqueSeqSetId, viewId, autoAlan);
2910 // /////////////////////////////////////
2911 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2915 for (int t = 0; t < jms.getTreeCount(); t++)
2918 Tree tree = jms.getTree(t);
2920 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2923 tp = af.ShowNewickTree(
2924 new jalview.io.NewickFile(tree.getNewick()),
2925 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2926 tree.getXpos(), tree.getYpos());
2927 if (tree.getId() != null)
2929 // perhaps bind the tree id to something ?
2934 // update local tree attributes ?
2935 // TODO: should check if tp has been manipulated by user - if so its
2936 // settings shouldn't be modified
2937 tp.setTitle(tree.getTitle());
2938 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2939 .getWidth(), tree.getHeight()));
2940 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2943 tp.treeCanvas.av = av; // af.viewport;
2944 tp.treeCanvas.ap = ap; // af.alignPanel;
2949 warn("There was a problem recovering stored Newick tree: \n"
2950 + tree.getNewick());
2954 tp.fitToWindow.setState(tree.getFitToWindow());
2955 tp.fitToWindow_actionPerformed(null);
2957 if (tree.getFontName() != null)
2959 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2960 .getFontStyle(), tree.getFontSize()));
2964 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2965 .getFontStyle(), tree.getFontSize()));
2968 tp.showPlaceholders(tree.getMarkUnlinked());
2969 tp.showBootstrap(tree.getShowBootstrap());
2970 tp.showDistances(tree.getShowDistances());
2972 tp.treeCanvas.threshold = tree.getThreshold();
2974 if (tree.getCurrentTree())
2976 af.viewport.setCurrentTree(tp.getTree());
2980 } catch (Exception ex)
2982 ex.printStackTrace();
2986 // //LOAD STRUCTURES
2987 if (loadTreesAndStructures)
2989 // run through all PDB ids on the alignment, and collect mappings between
2990 // jmol view ids and all sequences referring to it
2991 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2993 for (int i = 0; i < JSEQ.length; i++)
2995 if (JSEQ[i].getPdbidsCount() > 0)
2997 Pdbids[] ids = JSEQ[i].getPdbids();
2998 for (int p = 0; p < ids.length; p++)
3000 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
3002 // check to see if we haven't already created this structure view
3003 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
3004 : ids[p].getStructureState(s).getViewId()
3006 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3007 // Originally : ids[p].getFile()
3008 // : TODO: verify external PDB file recovery still works in normal
3009 // jalview project load
3010 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3011 jpdb.setId(ids[p].getId());
3013 int x = ids[p].getStructureState(s).getXpos();
3014 int y = ids[p].getStructureState(s).getYpos();
3015 int width = ids[p].getStructureState(s).getWidth();
3016 int height = ids[p].getStructureState(s).getHeight();
3018 // Probably don't need to do this anymore...
3019 // Desktop.desktop.getComponentAt(x, y);
3020 // TODO: NOW: check that this recovers the PDB file correctly.
3021 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3022 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
3023 .get(JSEQ[i].getId() + "");
3024 if (sviewid == null)
3026 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3029 if (!jmolViewIds.containsKey(sviewid))
3031 jmolViewIds.put(sviewid, new Object[]
3033 { x, y, width, height }, "",
3034 new Hashtable<String, Object[]>(), new boolean[]
3035 { false, false, true } });
3036 // Legacy pre-2.7 conversion JAL-823 :
3037 // do not assume any view has to be linked for colour by
3041 // assemble String[] { pdb files }, String[] { id for each
3042 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3043 // seqs_file 2}, boolean[] {
3044 // linkAlignPanel,superposeWithAlignpanel}} from hash
3045 Object[] jmoldat = jmolViewIds.get(sviewid);
3046 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
3047 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
3048 s).getAlignwithAlignPanel() : false;
3049 // never colour by linked panel if not specified
3050 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
3051 .hasColourwithAlignPanel() ? ids[p]
3052 .getStructureState(s).getColourwithAlignPanel()
3054 // default for pre-2.7 projects is that Jmol colouring is enabled
3055 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
3056 .hasColourByJmol() ? ids[p].getStructureState(s)
3057 .getColourByJmol() : true;
3059 if (((String) jmoldat[1]).length() < ids[p]
3060 .getStructureState(s).getContent().length())
3063 jmoldat[1] = ids[p].getStructureState(s).getContent();
3066 if (ids[p].getFile() != null)
3068 File mapkey = new File(ids[p].getFile());
3069 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3071 if (seqstrmaps == null)
3073 ((Hashtable) jmoldat[2]).put(mapkey,
3074 seqstrmaps = new Object[]
3075 { pdbFile, ids[p].getId(), new Vector(),
3078 if (!((Vector) seqstrmaps[2]).contains(seq))
3080 ((Vector) seqstrmaps[2]).addElement(seq);
3081 // ((Vector)seqstrmaps[3]).addElement(n) :
3082 // in principle, chains
3083 // should be stored here : do we need to
3084 // TODO: store and recover seq/pdb_id :
3090 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");
3099 // Instantiate the associated Jmol views
3100 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3102 String sviewid = entry.getKey();
3103 Object[] svattrib = entry.getValue();
3104 int[] geom = (int[]) svattrib[0];
3105 String state = (String) svattrib[1];
3106 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3107 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3108 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3109 // collate the pdbfile -> sequence mappings from this view
3110 Vector<String> pdbfilenames = new Vector<String>();
3111 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3112 Vector<String> pdbids = new Vector<String>();
3114 // Search to see if we've already created this Jmol view
3115 AppJmol comp = null;
3116 JInternalFrame[] frames = null;
3121 frames = Desktop.desktop.getAllFrames();
3122 } catch (ArrayIndexOutOfBoundsException e)
3124 // occasional No such child exceptions are thrown here...
3129 } catch (Exception f)
3134 } while (frames == null);
3135 // search for any Jmol windows already open from other
3136 // alignment views that exactly match the stored structure state
3137 for (int f = 0; comp == null && f < frames.length; f++)
3139 if (frames[f] instanceof AppJmol)
3142 && ((GStructureViewer) frames[f]).getViewId().equals(sviewid))
3144 // post jalview 2.4 schema includes structure view id
3145 comp = (AppJmol) frames[f];
3147 else if (frames[f].getX() == x && frames[f].getY() == y
3148 && frames[f].getHeight() == height
3149 && frames[f].getWidth() == width)
3151 comp = (AppJmol) frames[f];
3158 // create a new Jmol window.
3159 // First parse the Jmol state to translate filenames loaded into the
3160 // view, and record the order in which files are shown in the Jmol
3161 // view, so we can add the sequence mappings in same order.
3162 StringBuffer newFileLoc = null;
3163 int cp = 0, ncp, ecp;
3164 while ((ncp = state.indexOf("load ", cp)) > -1)
3166 if (newFileLoc == null)
3168 newFileLoc = new StringBuffer();
3172 // look for next filename in load statement
3173 newFileLoc.append(state.substring(cp,
3174 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3175 String oldfilenam = state.substring(ncp,
3176 ecp = state.indexOf("\"", ncp));
3177 // recover the new mapping data for this old filename
3178 // have to normalize filename - since Jmol and jalview do
3180 // translation differently.
3181 Object[] filedat = oldFiles.get(new File(oldfilenam));
3182 newFileLoc.append(Platform
3183 .escapeString((String) filedat[0]));
3184 pdbfilenames.addElement((String) filedat[0]);
3185 pdbids.addElement((String) filedat[1]);
3186 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3187 .toArray(new SequenceI[0]));
3188 newFileLoc.append("\"");
3189 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3190 // look for next file statement.
3191 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3195 // just append rest of state
3196 newFileLoc.append(state.substring(cp));
3201 .print("Ignoring incomplete Jmol state for PDB ids: ");
3202 newFileLoc = new StringBuffer(state);
3203 newFileLoc.append("; load append ");
3204 for (File id : oldFiles.keySet())
3206 // add this and any other pdb files that should be present in
3208 Object[] filedat = oldFiles.get(id);
3210 newFileLoc.append(((String) filedat[0]));
3211 pdbfilenames.addElement((String) filedat[0]);
3212 pdbids.addElement((String) filedat[1]);
3213 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3214 .toArray(new SequenceI[0]));
3215 newFileLoc.append(" \"");
3216 newFileLoc.append((String) filedat[0]);
3217 newFileLoc.append("\"");
3220 newFileLoc.append(";");
3223 if (newFileLoc != null)
3225 int histbug = newFileLoc.indexOf("history = ");
3227 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3229 String val = (diff == -1) ? null : newFileLoc.substring(
3231 if (val != null && val.length() >= 4)
3233 if (val.contains("e"))
3235 if (val.trim().equals("true"))
3243 newFileLoc.replace(histbug, diff, val);
3246 // TODO: assemble String[] { pdb files }, String[] { id for each
3247 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3248 // seqs_file 2}} from hash
3249 final String[] pdbf = pdbfilenames
3250 .toArray(new String[pdbfilenames.size()]), id = pdbids
3251 .toArray(new String[pdbids.size()]);
3252 final SequenceI[][] sq = seqmaps
3253 .toArray(new SequenceI[seqmaps.size()][]);
3254 final String fileloc = newFileLoc.toString(), vid = sviewid;
3255 final AlignFrame alf = af;
3256 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3260 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3265 JalviewStructureDisplayI sview = null;
3268 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3269 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3270 useinJmolsuperpos, usetoColourbyseq,
3271 jmolColouring, fileloc, rect, vid);
3272 addNewStructureViewer(sview);
3273 } catch (OutOfMemoryError ex)
3275 new OOMWarning("restoring structure view for PDB id "
3276 + id, (OutOfMemoryError) ex.getCause());
3277 if (sview != null && sview.isVisible())
3279 sview.closeViewer();
3280 sview.setVisible(false);
3286 } catch (InvocationTargetException ex)
3288 warn("Unexpected error when opening Jmol view.", ex);
3290 } catch (InterruptedException e)
3292 // e.printStackTrace();
3298 // if (comp != null)
3300 // NOTE: if the jalview project is part of a shared session then
3301 // view synchronization should/could be done here.
3303 // add mapping for sequences in this view to an already open Jmol
3305 for (File id : oldFiles.keySet())
3307 // add this and any other pdb files that should be present in the
3309 Object[] filedat = oldFiles.get(id);
3310 String pdbFile = (String) filedat[0];
3311 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3312 .toArray(new SequenceI[0]);
3313 comp.jmb.getSsm().setMapping(seq, null, pdbFile,
3314 jalview.io.AppletFormatAdapter.FILE);
3315 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3317 // and add the AlignmentPanel's reference to the Jmol view
3318 comp.addAlignmentPanel(ap);
3319 if (useinJmolsuperpos)
3321 comp.useAlignmentPanelForSuperposition(ap);
3325 comp.excludeAlignmentPanelForSuperposition(ap);
3327 if (usetoColourbyseq)
3329 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3333 comp.excludeAlignmentPanelForColourbyseq(ap);
3339 // and finally return.
3346 * - minimum version we are comparing against
3348 * - version of data being processsed.
3349 * @return true if version is development/null or evaluates to the same or
3350 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3352 private boolean isVersionStringLaterThan(String supported, String version)
3354 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3355 || version.equalsIgnoreCase("Test")
3356 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3358 System.err.println("Assuming project file with "
3359 + (version == null ? "null" : version)
3360 + " is compatible with Jalview version " + supported);
3365 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3367 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3369 // convert b to decimal to catch bugfix releases within a series
3370 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3371 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3374 if (Float.valueOf(curT) > Float.valueOf(fileT))
3376 // current version is newer than the version that wrote the file
3379 } catch (NumberFormatException nfe)
3382 .println("** WARNING: Version comparison failed for tokens ("
3386 + ")\n** Current: '"
3387 + supported + "' and Version: '" + version + "'");
3390 if (currentV.hasMoreElements())
3392 // fileV has no minor version but identical series to current
3399 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3401 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3403 if (newStructureViewers != null)
3405 sview.getBinding().setFinishedLoadingFromArchive(false);
3406 newStructureViewers.add(sview);
3410 protected void setLoadingFinishedForNewStructureViewers()
3412 if (newStructureViewers != null)
3414 for (JalviewStructureDisplayI sview : newStructureViewers)
3416 sview.getBinding().setFinishedLoadingFromArchive(true);
3418 newStructureViewers.clear();
3419 newStructureViewers = null;
3423 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3424 Alignment al, JalviewModelSequence jms, Viewport view,
3425 String uniqueSeqSetId, String viewId,
3426 ArrayList<JvAnnotRow> autoAlan)
3428 AlignFrame af = null;
3429 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3430 uniqueSeqSetId, viewId);
3432 af.setFileName(file, "Jalview");
3434 for (int i = 0; i < JSEQ.length; i++)
3436 af.viewport.setSequenceColour(af.viewport.getAlignment()
3437 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3440 af.viewport.gatherViewsHere = view.getGatheredViews();
3442 if (view.getSequenceSetId() != null)
3444 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3445 .get(uniqueSeqSetId);
3447 af.viewport.setSequenceSetId(uniqueSeqSetId);
3450 // propagate shared settings to this new view
3451 af.viewport.historyList = av.historyList;
3452 af.viewport.redoList = av.redoList;
3456 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3458 // TODO: check if this method can be called repeatedly without
3459 // side-effects if alignpanel already registered.
3460 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3462 // apply Hidden regions to view.
3463 if (hiddenSeqs != null)
3465 for (int s = 0; s < JSEQ.length; s++)
3467 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3469 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3472 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3474 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3477 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3480 for (int s = 0; s < hiddenSeqs.size(); s++)
3482 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3485 af.viewport.hideSequence(hseqs);
3488 // recover view properties and display parameters
3489 if (view.getViewName() != null)
3491 af.viewport.viewName = view.getViewName();
3492 af.setInitialTabVisible();
3494 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3497 af.viewport.setShowAnnotation(view.getShowAnnotation());
3498 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3500 af.viewport.setColourText(view.getShowColourText());
3502 af.viewport.setConservationSelected(view.getConservationSelected());
3503 af.viewport.setShowJVSuffix(view.getShowFullId());
3504 af.viewport.setRightAlignIds(view.getRightAlignIds());
3505 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3506 .getFontStyle(), view.getFontSize()));
3507 af.alignPanel.fontChanged();
3508 af.viewport.setRenderGaps(view.getRenderGaps());
3509 af.viewport.setWrapAlignment(view.getWrapAlignment());
3510 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3511 af.viewport.setShowAnnotation(view.getShowAnnotation());
3512 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3514 af.viewport.setShowBoxes(view.getShowBoxes());
3516 af.viewport.setShowText(view.getShowText());
3518 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3519 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3520 af.viewport.thresholdTextColour = view.getTextColThreshold();
3521 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3522 .isShowUnconserved() : false);
3523 af.viewport.setStartRes(view.getStartRes());
3524 af.viewport.setStartSeq(view.getStartSeq());
3526 ColourSchemeI cs = null;
3527 // apply colourschemes
3528 if (view.getBgColour() != null)
3530 if (view.getBgColour().startsWith("ucs"))
3532 cs = GetUserColourScheme(jms, view.getBgColour());
3534 else if (view.getBgColour().startsWith("Annotation"))
3536 AnnotationColours viewAnnColour = view.getAnnotationColours();
3537 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3544 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3549 cs.setThreshold(view.getPidThreshold(), true);
3550 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3554 af.viewport.setGlobalColourScheme(cs);
3555 af.viewport.setColourAppliesToAllGroups(false);
3557 if (view.getConservationSelected() && cs != null)
3559 cs.setConservationInc(view.getConsThreshold());
3562 af.changeColour(cs);
3564 af.viewport.setColourAppliesToAllGroups(true);
3566 if (view.getShowSequenceFeatures())
3568 af.viewport.showSequenceFeatures = true;
3570 if (view.hasCentreColumnLabels())
3572 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3574 if (view.hasIgnoreGapsinConsensus())
3576 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3579 if (view.hasFollowHighlight())
3581 af.viewport.followHighlight = view.getFollowHighlight();
3583 if (view.hasFollowSelection())
3585 af.viewport.followSelection = view.getFollowSelection();
3587 if (view.hasShowConsensusHistogram())
3589 af.viewport.setShowConsensusHistogram(view
3590 .getShowConsensusHistogram());
3594 af.viewport.setShowConsensusHistogram(true);
3596 if (view.hasShowSequenceLogo())
3598 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3602 af.viewport.setShowSequenceLogo(false);
3604 if (view.hasNormaliseSequenceLogo())
3606 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3608 if (view.hasShowDbRefTooltip())
3610 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3612 if (view.hasShowNPfeatureTooltip())
3614 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3616 if (view.hasShowGroupConsensus())
3618 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3622 af.viewport.setShowGroupConsensus(false);
3624 if (view.hasShowGroupConservation())
3626 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3630 af.viewport.setShowGroupConservation(false);
3633 // recover featre settings
3634 if (jms.getFeatureSettings() != null)
3636 af.viewport.setFeaturesDisplayed(new Hashtable());
3637 String[] renderOrder = new String[jms.getFeatureSettings()
3638 .getSettingCount()];
3639 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3641 Setting setting = jms.getFeatureSettings().getSetting(fs);
3642 if (setting.hasMincolour())
3644 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3645 new java.awt.Color(setting.getMincolour()),
3646 new java.awt.Color(setting.getColour()),
3647 setting.getMin(), setting.getMax()) : new GraduatedColor(
3648 new java.awt.Color(setting.getMincolour()),
3649 new java.awt.Color(setting.getColour()), 0, 1);
3650 if (setting.hasThreshold())
3652 gc.setThresh(setting.getThreshold());
3653 gc.setThreshType(setting.getThreshstate());
3655 gc.setAutoScaled(true); // default
3656 if (setting.hasAutoScale())
3658 gc.setAutoScaled(setting.getAutoScale());
3660 if (setting.hasColourByLabel())
3662 gc.setColourByLabel(setting.getColourByLabel());
3664 // and put in the feature colour table.
3665 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3666 setting.getType(), gc);
3670 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3672 new java.awt.Color(setting.getColour()));
3674 renderOrder[fs] = setting.getType();
3675 if (setting.hasOrder())
3677 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3678 setting.getType(), setting.getOrder());
3682 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3684 fs / jms.getFeatureSettings().getSettingCount());
3686 if (setting.getDisplay())
3688 af.viewport.getFeaturesDisplayed().put(setting.getType(), new Integer(
3689 setting.getColour()));
3692 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3694 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3695 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3697 Group grp = jms.getFeatureSettings().getGroup(gs);
3698 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3702 if (view.getHiddenColumnsCount() > 0)
3704 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3706 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3707 .getHiddenColumns(c).getEnd() // +1
3711 if (view.getCalcIdParam() != null)
3713 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3715 if (calcIdParam != null)
3717 if (recoverCalcIdParam(calcIdParam, af.viewport))
3722 warn("Couldn't recover parameters for "
3723 + calcIdParam.getCalcId());
3728 af.setMenusFromViewport(af.viewport);
3729 // TODO: we don't need to do this if the viewport is aready visible.
3730 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3732 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3733 reorderAutoannotation(af, al, autoAlan);
3734 af.alignPanel.alignmentChanged();
3738 private ColourSchemeI constructAnnotationColour(
3739 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3740 JalviewModelSequence jms, boolean checkGroupAnnColour)
3742 boolean propagateAnnColour = false;
3743 ColourSchemeI cs = null;
3744 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3745 if (checkGroupAnnColour && al.getGroups() != null
3746 && al.getGroups().size() > 0)
3748 // pre 2.8.1 behaviour
3749 // check to see if we should transfer annotation colours
3750 propagateAnnColour = true;
3751 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3753 if (sg.cs instanceof AnnotationColourGradient)
3755 propagateAnnColour = false;
3759 // int find annotation
3760 if (annAlignment.getAlignmentAnnotation() != null)
3762 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3764 if (annAlignment.getAlignmentAnnotation()[i].label
3765 .equals(viewAnnColour.getAnnotation()))
3767 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3769 annAlignment.getAlignmentAnnotation()[i]
3770 .setThreshold(new jalview.datamodel.GraphLine(
3771 viewAnnColour.getThreshold(), "Threshold",
3772 java.awt.Color.black)
3777 if (viewAnnColour.getColourScheme().equals("None"))
3779 cs = new AnnotationColourGradient(
3780 annAlignment.getAlignmentAnnotation()[i],
3781 new java.awt.Color(viewAnnColour.getMinColour()),
3782 new java.awt.Color(viewAnnColour.getMaxColour()),
3783 viewAnnColour.getAboveThreshold());
3785 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3787 cs = new AnnotationColourGradient(
3788 annAlignment.getAlignmentAnnotation()[i],
3789 GetUserColourScheme(jms,
3790 viewAnnColour.getColourScheme()),
3791 viewAnnColour.getAboveThreshold());
3795 cs = new AnnotationColourGradient(
3796 annAlignment.getAlignmentAnnotation()[i],
3797 ColourSchemeProperty.getColour(al,
3798 viewAnnColour.getColourScheme()),
3799 viewAnnColour.getAboveThreshold());
3801 if (viewAnnColour.hasPerSequence())
3803 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3806 if (viewAnnColour.hasPredefinedColours())
3808 ((AnnotationColourGradient) cs)
3809 .setPredefinedColours(viewAnnColour
3810 .isPredefinedColours());
3812 if (propagateAnnColour && al.getGroups() != null)
3814 // Also use these settings for all the groups
3815 for (int g = 0; g < al.getGroups().size(); g++)
3817 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3825 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3826 * new AnnotationColourGradient(
3827 * annAlignment.getAlignmentAnnotation()[i], new
3828 * java.awt.Color(viewAnnColour. getMinColour()), new
3829 * java.awt.Color(viewAnnColour. getMaxColour()),
3830 * viewAnnColour.getAboveThreshold()); } else
3833 sg.cs = new AnnotationColourGradient(
3834 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3835 viewAnnColour.getAboveThreshold());
3836 if (cs instanceof AnnotationColourGradient)
3838 if (viewAnnColour.hasPerSequence())
3840 ((AnnotationColourGradient) cs)
3841 .setSeqAssociated(viewAnnColour.isPerSequence());
3843 if (viewAnnColour.hasPredefinedColours())
3845 ((AnnotationColourGradient) cs)
3846 .setPredefinedColours(viewAnnColour
3847 .isPredefinedColours());
3863 private void reorderAutoannotation(AlignFrame af, Alignment al,
3864 ArrayList<JvAnnotRow> autoAlan)
3866 // copy over visualization settings for autocalculated annotation in the
3868 if (al.getAlignmentAnnotation() != null)
3871 * Kludge for magic autoannotation names (see JAL-811)
3873 String[] magicNames = new String[]
3874 { "Consensus", "Quality", "Conservation" };
3875 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3876 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3877 for (String nm : magicNames)
3879 visan.put(nm, nullAnnot);
3881 for (JvAnnotRow auan : autoAlan)
3883 visan.put(auan.template.label
3884 + (auan.template.getCalcId() == null ? "" : "\t"
3885 + auan.template.getCalcId()), auan);
3887 int hSize = al.getAlignmentAnnotation().length;
3888 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3889 // work through any autoCalculated annotation already on the view
3890 // removing it if it should be placed in a different location on the
3891 // annotation panel.
3892 List<String> remains = new ArrayList(visan.keySet());
3893 for (int h = 0; h < hSize; h++)
3895 jalview.datamodel.AlignmentAnnotation jalan = al
3896 .getAlignmentAnnotation()[h];
3897 if (jalan.autoCalculated)
3900 JvAnnotRow valan = visan.get(k = jalan.label);
3901 if (jalan.getCalcId() != null)
3903 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3908 // delete the auto calculated row from the alignment
3909 al.deleteAnnotation(jalan, false);
3913 if (valan != nullAnnot)
3915 if (jalan != valan.template)
3917 // newly created autoannotation row instance
3918 // so keep a reference to the visible annotation row
3919 // and copy over all relevant attributes
3920 if (valan.template.graphHeight >= 0)
3923 jalan.graphHeight = valan.template.graphHeight;
3925 jalan.visible = valan.template.visible;
3927 reorder.add(new JvAnnotRow(valan.order, jalan));
3932 // Add any (possibly stale) autocalculated rows that were not appended to
3933 // the view during construction
3934 for (String other : remains)
3936 JvAnnotRow othera = visan.get(other);
3937 if (othera != nullAnnot && othera.template.getCalcId() != null
3938 && othera.template.getCalcId().length() > 0)
3940 reorder.add(othera);
3943 // now put the automatic annotation in its correct place
3944 int s = 0, srt[] = new int[reorder.size()];
3945 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3946 for (JvAnnotRow jvar : reorder)
3949 srt[s++] = jvar.order;
3952 jalview.util.QuickSort.sort(srt, rws);
3953 // and re-insert the annotation at its correct position
3954 for (JvAnnotRow jvar : rws)
3956 al.addAnnotation(jvar.template, jvar.order);
3958 af.alignPanel.adjustAnnotationHeight();
3962 Hashtable skipList = null;
3965 * TODO remove this method
3968 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3969 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3970 * throw new Error("Implementation Error. No skipList defined for this
3971 * Jalview2XML instance."); } return (AlignFrame)
3972 * skipList.get(view.getSequenceSetId()); }
3976 * Check if the Jalview view contained in object should be skipped or not.
3979 * @return true if view's sequenceSetId is a key in skipList
3981 private boolean skipViewport(JalviewModel object)
3983 if (skipList == null)
3988 if (skipList.containsKey(id = object.getJalviewModelSequence()
3989 .getViewport()[0].getSequenceSetId()))
3991 if (Cache.log != null && Cache.log.isDebugEnabled())
3993 Cache.log.debug("Skipping seuqence set id " + id);
4000 public void AddToSkipList(AlignFrame af)
4002 if (skipList == null)
4004 skipList = new Hashtable();
4006 skipList.put(af.getViewport().getSequenceSetId(), af);
4009 public void clearSkipList()
4011 if (skipList != null)
4018 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4019 boolean ignoreUnrefed)
4021 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4022 Vector dseqs = null;
4025 // create a list of new dataset sequences
4026 dseqs = new Vector();
4028 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4030 Sequence vamsasSeq = vamsasSet.getSequence(i);
4031 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4033 // create a new dataset
4036 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4037 dseqs.copyInto(dsseqs);
4038 ds = new jalview.datamodel.Alignment(dsseqs);
4039 debug("Created new dataset " + vamsasSet.getDatasetId()
4040 + " for alignment " + System.identityHashCode(al));
4041 addDatasetRef(vamsasSet.getDatasetId(), ds);
4043 // set the dataset for the newly imported alignment.
4044 if (al.getDataset() == null && !ignoreUnrefed)
4053 * sequence definition to create/merge dataset sequence for
4057 * vector to add new dataset sequence to
4059 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4060 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4062 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4064 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4065 .get(vamsasSeq.getId());
4066 jalview.datamodel.SequenceI dsq = null;
4067 if (sq != null && sq.getDatasetSequence() != null)
4069 dsq = sq.getDatasetSequence();
4071 if (sq == null && ignoreUnrefed)
4075 String sqid = vamsasSeq.getDsseqid();
4078 // need to create or add a new dataset sequence reference to this sequence
4081 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4086 // make a new dataset sequence
4087 dsq = sq.createDatasetSequence();
4090 // make up a new dataset reference for this sequence
4091 sqid = seqHash(dsq);
4093 dsq.setVamsasId(uniqueSetSuffix + sqid);
4094 seqRefIds.put(sqid, dsq);
4099 dseqs.addElement(dsq);
4104 ds.addSequence(dsq);
4110 { // make this dataset sequence sq's dataset sequence
4111 sq.setDatasetSequence(dsq);
4112 // and update the current dataset alignment
4117 if (!dseqs.contains(dsq))
4124 if (ds.findIndex(dsq) < 0)
4126 ds.addSequence(dsq);
4133 // TODO: refactor this as a merge dataset sequence function
4134 // now check that sq (the dataset sequence) sequence really is the union of
4135 // all references to it
4136 // boolean pre = sq.getStart() < dsq.getStart();
4137 // boolean post = sq.getEnd() > dsq.getEnd();
4141 StringBuffer sb = new StringBuffer();
4142 String newres = jalview.analysis.AlignSeq.extractGaps(
4143 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4144 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4145 && newres.length() > dsq.getLength())
4147 // Update with the longer sequence.
4151 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4152 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4153 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4154 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4156 dsq.setSequence(newres);
4158 // TODO: merges will never happen if we 'know' we have the real dataset
4159 // sequence - this should be detected when id==dssid
4161 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4162 // + (pre ? "prepended" : "") + " "
4163 // + (post ? "appended" : ""));
4168 java.util.Hashtable datasetIds = null;
4170 java.util.IdentityHashMap dataset2Ids = null;
4172 private Alignment getDatasetFor(String datasetId)
4174 if (datasetIds == null)
4176 datasetIds = new Hashtable();
4179 if (datasetIds.containsKey(datasetId))
4181 return (Alignment) datasetIds.get(datasetId);
4186 private void addDatasetRef(String datasetId, Alignment dataset)
4188 if (datasetIds == null)
4190 datasetIds = new Hashtable();
4192 datasetIds.put(datasetId, dataset);
4196 * make a new dataset ID for this jalview dataset alignment
4201 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4203 if (dataset.getDataset() != null)
4205 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4207 String datasetId = makeHashCode(dataset, null);
4208 if (datasetId == null)
4210 // make a new datasetId and record it
4211 if (dataset2Ids == null)
4213 dataset2Ids = new IdentityHashMap();
4217 datasetId = (String) dataset2Ids.get(dataset);
4219 if (datasetId == null)
4221 datasetId = "ds" + dataset2Ids.size() + 1;
4222 dataset2Ids.put(dataset, datasetId);
4228 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4230 for (int d = 0; d < sequence.getDBRefCount(); d++)
4232 DBRef dr = sequence.getDBRef(d);
4233 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4234 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4235 .getVersion(), sequence.getDBRef(d).getAccessionId());
4236 if (dr.getMapping() != null)
4238 entry.setMap(addMapping(dr.getMapping()));
4240 datasetSequence.addDBRef(entry);
4244 private jalview.datamodel.Mapping addMapping(Mapping m)
4246 SequenceI dsto = null;
4247 // Mapping m = dr.getMapping();
4248 int fr[] = new int[m.getMapListFromCount() * 2];
4249 Enumeration f = m.enumerateMapListFrom();
4250 for (int _i = 0; f.hasMoreElements(); _i += 2)
4252 MapListFrom mf = (MapListFrom) f.nextElement();
4253 fr[_i] = mf.getStart();
4254 fr[_i + 1] = mf.getEnd();
4256 int fto[] = new int[m.getMapListToCount() * 2];
4257 f = m.enumerateMapListTo();
4258 for (int _i = 0; f.hasMoreElements(); _i += 2)
4260 MapListTo mf = (MapListTo) f.nextElement();
4261 fto[_i] = mf.getStart();
4262 fto[_i + 1] = mf.getEnd();
4264 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4265 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4266 if (m.getMappingChoice() != null)
4268 MappingChoice mc = m.getMappingChoice();
4269 if (mc.getDseqFor() != null)
4271 String dsfor = "" + mc.getDseqFor();
4272 if (seqRefIds.containsKey(dsfor))
4277 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4281 frefedSequence.add(new Object[]
4288 * local sequence definition
4290 Sequence ms = mc.getSequence();
4291 jalview.datamodel.Sequence djs = null;
4292 String sqid = ms.getDsseqid();
4293 if (sqid != null && sqid.length() > 0)
4296 * recover dataset sequence
4298 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4303 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4304 sqid = ((Object) ms).toString(); // make up a new hascode for
4305 // undefined dataset sequence hash
4306 // (unlikely to happen)
4312 * make a new dataset sequence and add it to refIds hash
4314 djs = new jalview.datamodel.Sequence(ms.getName(),
4316 djs.setStart(jmap.getMap().getToLowest());
4317 djs.setEnd(jmap.getMap().getToHighest());
4318 djs.setVamsasId(uniqueSetSuffix + sqid);
4320 seqRefIds.put(sqid, djs);
4323 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4332 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4333 boolean keepSeqRefs)
4336 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4342 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4346 uniqueSetSuffix = "";
4347 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4352 if (this.frefedSequence == null)
4354 frefedSequence = new Vector();
4357 viewportsAdded = new Hashtable();
4359 AlignFrame af = LoadFromObject(jm, null, false, null);
4360 af.alignPanels.clear();
4361 af.closeMenuItem_actionPerformed(true);
4364 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4365 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4366 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4367 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4368 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4371 return af.alignPanel;
4375 * flag indicating if hashtables should be cleared on finalization TODO this
4376 * flag may not be necessary
4378 private final boolean _cleartables = true;
4380 private Hashtable jvids2vobj;
4385 * @see java.lang.Object#finalize()
4388 protected void finalize() throws Throwable
4390 // really make sure we have no buried refs left.
4395 this.seqRefIds = null;
4396 this.seqsToIds = null;
4400 private void warn(String msg)
4405 private void warn(String msg, Exception e)
4407 if (Cache.log != null)
4411 Cache.log.warn(msg, e);
4415 Cache.log.warn(msg);
4420 System.err.println("Warning: " + msg);
4423 e.printStackTrace();
4428 private void debug(String string)
4430 debug(string, null);
4433 private void debug(String msg, Exception e)
4435 if (Cache.log != null)
4439 Cache.log.debug(msg, e);
4443 Cache.log.debug(msg);
4448 System.err.println("Warning: " + msg);
4451 e.printStackTrace();
4457 * set the object to ID mapping tables used to write/recover objects and XML
4458 * ID strings for the jalview project. If external tables are provided then
4459 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4460 * object goes out of scope. - also populates the datasetIds hashtable with
4461 * alignment objects containing dataset sequences
4464 * Map from ID strings to jalview datamodel
4466 * Map from jalview datamodel to ID strings
4470 public void setObjectMappingTables(Hashtable vobj2jv,
4471 IdentityHashMap jv2vobj)
4473 this.jv2vobj = jv2vobj;
4474 this.vobj2jv = vobj2jv;
4475 Iterator ds = jv2vobj.keySet().iterator();
4477 while (ds.hasNext())
4479 Object jvobj = ds.next();
4480 id = jv2vobj.get(jvobj).toString();
4481 if (jvobj instanceof jalview.datamodel.Alignment)
4483 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4485 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4488 else if (jvobj instanceof jalview.datamodel.Sequence)
4490 // register sequence object so the XML parser can recover it.
4491 if (seqRefIds == null)
4493 seqRefIds = new Hashtable();
4495 if (seqsToIds == null)
4497 seqsToIds = new IdentityHashMap();
4499 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4500 seqsToIds.put(jvobj, id);
4502 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4504 if (annotationIds == null)
4506 annotationIds = new Hashtable();
4509 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4510 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4511 if (jvann.annotationId == null)
4513 jvann.annotationId = anid;
4515 if (!jvann.annotationId.equals(anid))
4517 // TODO verify that this is the correct behaviour
4518 this.warn("Overriding Annotation ID for " + anid
4519 + " from different id : " + jvann.annotationId);
4520 jvann.annotationId = anid;
4523 else if (jvobj instanceof String)
4525 if (jvids2vobj == null)
4527 jvids2vobj = new Hashtable();
4528 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4533 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4539 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4540 * objects created from the project archive. If string is null (default for
4541 * construction) then suffix will be set automatically.
4545 public void setUniqueSetSuffix(String string)
4547 uniqueSetSuffix = string;
4552 * uses skipList2 as the skipList for skipping views on sequence sets
4553 * associated with keys in the skipList
4557 public void setSkipList(Hashtable skipList2)
4559 skipList = skipList2;