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.schemabinding.version2.AlcodMap;
31 import jalview.schemabinding.version2.Alcodon;
32 import jalview.schemabinding.version2.AlcodonFrame;
33 import jalview.schemabinding.version2.Annotation;
34 import jalview.schemabinding.version2.AnnotationColours;
35 import jalview.schemabinding.version2.AnnotationElement;
36 import jalview.schemabinding.version2.CalcIdParam;
37 import jalview.schemabinding.version2.DBRef;
38 import jalview.schemabinding.version2.Features;
39 import jalview.schemabinding.version2.Group;
40 import jalview.schemabinding.version2.HiddenColumns;
41 import jalview.schemabinding.version2.JGroup;
42 import jalview.schemabinding.version2.JSeq;
43 import jalview.schemabinding.version2.JalviewModel;
44 import jalview.schemabinding.version2.JalviewModelSequence;
45 import jalview.schemabinding.version2.MapListFrom;
46 import jalview.schemabinding.version2.MapListTo;
47 import jalview.schemabinding.version2.Mapping;
48 import jalview.schemabinding.version2.MappingChoice;
49 import jalview.schemabinding.version2.OtherData;
50 import jalview.schemabinding.version2.PdbentryItem;
51 import jalview.schemabinding.version2.Pdbids;
52 import jalview.schemabinding.version2.Property;
53 import jalview.schemabinding.version2.Sequence;
54 import jalview.schemabinding.version2.SequenceSet;
55 import jalview.schemabinding.version2.SequenceSetProperties;
56 import jalview.schemabinding.version2.Setting;
57 import jalview.schemabinding.version2.StructureState;
58 import jalview.schemabinding.version2.ThresholdLine;
59 import jalview.schemabinding.version2.Tree;
60 import jalview.schemabinding.version2.UserColours;
61 import jalview.schemabinding.version2.Viewport;
62 import jalview.schemes.AnnotationColourGradient;
63 import jalview.schemes.ColourSchemeI;
64 import jalview.schemes.ColourSchemeProperty;
65 import jalview.schemes.GraduatedColor;
66 import jalview.schemes.ResidueColourScheme;
67 import jalview.schemes.ResidueProperties;
68 import jalview.schemes.UserColourScheme;
69 import jalview.structure.StructureSelectionManager;
70 import jalview.structures.models.AAStructureBindingModel;
71 import jalview.util.MessageManager;
72 import jalview.util.Platform;
73 import jalview.util.jarInputStreamProvider;
74 import jalview.viewmodel.AlignmentViewport;
75 import jalview.ws.jws2.Jws2Discoverer;
76 import jalview.ws.jws2.dm.AAConSettings;
77 import jalview.ws.jws2.jabaws2.Jws2Instance;
78 import jalview.ws.params.ArgumentI;
79 import jalview.ws.params.AutoCalcSetting;
80 import jalview.ws.params.WsParamSetI;
82 import java.awt.Rectangle;
83 import java.io.BufferedReader;
84 import java.io.DataInputStream;
85 import java.io.DataOutputStream;
87 import java.io.FileInputStream;
88 import java.io.FileOutputStream;
89 import java.io.IOException;
90 import java.io.InputStreamReader;
91 import java.io.OutputStreamWriter;
92 import java.io.PrintWriter;
93 import java.lang.reflect.InvocationTargetException;
94 import java.net.MalformedURLException;
96 import java.util.ArrayList;
97 import java.util.Enumeration;
98 import java.util.HashMap;
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;
105 import java.util.Map.Entry;
106 import java.util.Set;
107 import java.util.StringTokenizer;
108 import java.util.Vector;
109 import java.util.jar.JarEntry;
110 import java.util.jar.JarInputStream;
111 import java.util.jar.JarOutputStream;
113 import javax.swing.JInternalFrame;
114 import javax.swing.JOptionPane;
115 import javax.swing.SwingUtilities;
117 import org.exolab.castor.xml.Unmarshaller;
120 * Write out the current jalview desktop state as a Jalview XML stream.
122 * Note: the vamsas objects referred to here are primitive versions of the
123 * VAMSAS project schema elements - they are not the same and most likely never
127 * @version $Revision: 1.134 $
129 public class Jalview2XML
133 * A data bean to hold stored data about a structure viewer.
135 public class ViewerData
146 public boolean alignWithPanel;
148 public boolean colourWithAlignPanel;
150 public boolean colourByViewer;
152 String stateData = "";
154 // todo: java bean in place of Object []
155 private Map<File, Object[]> fileData = new HashMap<File, Object[]>();
157 public ViewerData(int x, int y, int width, int height,
158 boolean alignWithPanel, boolean colourWithAlignPanel,
159 boolean colourByViewer)
164 this.height = height;
165 this.alignWithPanel = alignWithPanel;
166 this.colourWithAlignPanel = colourWithAlignPanel;
167 this.colourByViewer = colourByViewer;
173 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
174 * of sequence objects are created.
176 IdentityHashMap<SequenceI, String> seqsToIds = null;
179 * jalview XML Sequence ID to jalview sequence object reference (both dataset
180 * and alignment sequences. Populated as XML reps of sequence objects are
183 Map<String, SequenceI> seqRefIds = null;
185 Vector frefedSequence = null;
187 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
190 * create/return unique hash string for sq
193 * @return new or existing unique string for sq
195 String seqHash(SequenceI sq)
197 if (seqsToIds == null)
201 if (seqsToIds.containsKey(sq))
203 return seqsToIds.get(sq);
207 // create sequential key
208 String key = "sq" + (seqsToIds.size() + 1);
209 key = makeHashCode(sq, key); // check we don't have an external reference
211 seqsToIds.put(sq, key);
220 if (seqRefIds != null)
224 if (seqsToIds != null)
234 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
235 // seqRefIds = new Hashtable();
236 // seqsToIds = new IdentityHashMap();
242 if (seqsToIds == null)
244 seqsToIds = new IdentityHashMap<SequenceI, String>();
246 if (seqRefIds == null)
248 seqRefIds = new HashMap<String, SequenceI>();
256 public Jalview2XML(boolean raiseGUI)
258 this.raiseGUI = raiseGUI;
261 public void resolveFrefedSequences()
263 if (frefedSequence.size() > 0)
265 int r = 0, rSize = frefedSequence.size();
268 Object[] ref = (Object[]) frefedSequence.elementAt(r);
271 String sref = (String) ref[0];
272 if (seqRefIds.containsKey(sref))
274 if (ref[1] instanceof jalview.datamodel.Mapping)
276 SequenceI seq = seqRefIds.get(sref);
277 while (seq.getDatasetSequence() != null)
279 seq = seq.getDatasetSequence();
281 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
285 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
287 SequenceI seq = seqRefIds.get(sref);
288 while (seq.getDatasetSequence() != null)
290 seq = seq.getDatasetSequence();
293 && ref[2] instanceof jalview.datamodel.Mapping)
295 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
296 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
297 seq, mp.getTo(), mp.getMap());
302 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
303 + ref[2].getClass() + " type objects.");
309 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
310 + ref[1].getClass() + " type objects.");
313 frefedSequence.remove(r);
319 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
321 + " with objecttype "
322 + ref[1].getClass());
329 frefedSequence.remove(r);
337 * This maintains a list of viewports, the key being the seqSetId. Important
338 * to set historyItem and redoList for multiple views
340 Hashtable viewportsAdded;
342 Hashtable annotationIds = new Hashtable();
344 String uniqueSetSuffix = "";
347 * List of pdbfiles added to Jar
349 List<String> pdbfiles = null;
351 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
352 public void saveState(File statefile)
354 FileOutputStream fos = null;
357 fos = new FileOutputStream(statefile);
358 JarOutputStream jout = new JarOutputStream(fos);
361 } catch (Exception e)
363 // TODO: inform user of the problem - they need to know if their data was
365 if (errorMessage == null)
367 errorMessage = "Couldn't write Jalview Archive to output file '"
368 + statefile + "' - See console error log for details";
372 errorMessage += "(output file was '" + statefile + "')";
382 } catch (IOException e)
392 * Writes a jalview project archive to the given Jar output stream.
396 public void saveState(JarOutputStream jout)
398 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
405 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
410 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
411 // //////////////////////////////////////////////////
413 Vector shortNames = new Vector();
416 for (int i = frames.length - 1; i > -1; i--)
418 if (frames[i] instanceof AlignFrame)
420 AlignFrame af = (AlignFrame) frames[i];
423 && skipList.containsKey(af.getViewport()
424 .getSequenceSetId()))
429 String shortName = af.getTitle();
431 if (shortName.indexOf(File.separatorChar) > -1)
433 shortName = shortName.substring(shortName
434 .lastIndexOf(File.separatorChar) + 1);
439 while (shortNames.contains(shortName))
441 if (shortName.endsWith("_" + (count - 1)))
443 shortName = shortName
444 .substring(0, shortName.lastIndexOf("_"));
447 shortName = shortName.concat("_" + count);
451 shortNames.addElement(shortName);
453 if (!shortName.endsWith(".xml"))
455 shortName = shortName + ".xml";
458 int ap, apSize = af.alignPanels.size();
460 for (ap = 0; ap < apSize; ap++)
462 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
464 String fileName = apSize == 1 ? shortName : ap + shortName;
465 if (!fileName.endsWith(".xml"))
467 fileName = fileName + ".xml";
470 saveState(apanel, fileName, jout);
472 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
474 if (!dsses.containsKey(dssid))
476 dsses.put(dssid, af);
483 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
489 } catch (Exception foo)
494 } catch (Exception ex)
496 // TODO: inform user of the problem - they need to know if their data was
498 if (errorMessage == null)
500 errorMessage = "Couldn't write Jalview Archive - see error output for details";
502 ex.printStackTrace();
506 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
507 public boolean saveAlignment(AlignFrame af, String jarFile,
512 int ap, apSize = af.alignPanels.size();
513 FileOutputStream fos = new FileOutputStream(jarFile);
514 JarOutputStream jout = new JarOutputStream(fos);
515 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
516 for (ap = 0; ap < apSize; ap++)
518 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
520 String jfileName = apSize == 1 ? fileName : fileName + ap;
521 if (!jfileName.endsWith(".xml"))
523 jfileName = jfileName + ".xml";
525 saveState(apanel, jfileName, jout);
526 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
528 if (!dsses.containsKey(dssid))
530 dsses.put(dssid, af);
533 writeDatasetFor(dsses, fileName, jout);
537 } catch (Exception foo)
543 } catch (Exception ex)
545 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
546 ex.printStackTrace();
551 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
552 String fileName, JarOutputStream jout)
555 for (String dssids : dsses.keySet())
557 AlignFrame _af = dsses.get(dssids);
558 String jfileName = fileName + " Dataset for " + _af.getTitle();
559 if (!jfileName.endsWith(".xml"))
561 jfileName = jfileName + ".xml";
563 saveState(_af.alignPanel, jfileName, true, jout);
568 * create a JalviewModel from an alignment view and marshall it to a
572 * panel to create jalview model for
574 * name of alignment panel written to output stream
580 public JalviewModel saveState(AlignmentPanel ap, String fileName,
581 JarOutputStream jout)
583 return saveState(ap, fileName, false, jout);
587 * create a JalviewModel from an alignment view and marshall it to a
591 * panel to create jalview model for
593 * name of alignment panel written to output stream
595 * when true, only write the dataset for the alignment, not the data
596 * associated with the view.
602 public JalviewModel saveState(AlignmentPanel ap, String fileName,
603 boolean storeDS, JarOutputStream jout)
606 List<String> viewIds = new ArrayList<String>();
607 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
609 AlignViewport av = ap.av;
611 JalviewModel object = new JalviewModel();
612 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
614 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
615 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
616 "Development Build"));
618 jalview.datamodel.AlignmentI jal = av.getAlignment();
620 if (av.hasHiddenRows())
622 jal = jal.getHiddenSequences().getFullAlignment();
625 SequenceSet vamsasSet = new SequenceSet();
627 JalviewModelSequence jms = new JalviewModelSequence();
629 vamsasSet.setGapChar(jal.getGapCharacter() + "");
631 if (jal.getDataset() != null)
633 // dataset id is the dataset's hashcode
634 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
637 // switch jal and the dataset
638 jal = jal.getDataset();
641 if (jal.getProperties() != null)
643 Enumeration en = jal.getProperties().keys();
644 while (en.hasMoreElements())
646 String key = en.nextElement().toString();
647 SequenceSetProperties ssp = new SequenceSetProperties();
649 ssp.setValue(jal.getProperties().get(key).toString());
650 vamsasSet.addSequenceSetProperties(ssp);
655 Set<String> calcIdSet = new HashSet<String>();
659 jalview.datamodel.SequenceI jds, jdatasq;
660 for (int i = 0; i < jal.getHeight(); i++)
662 jds = jal.getSequenceAt(i);
663 jdatasq = jds.getDatasetSequence() == null ? jds : jds
664 .getDatasetSequence();
667 if (seqRefIds.get(id) != null)
669 // This happens for two reasons: 1. multiple views are being serialised.
670 // 2. the hashCode has collided with another sequence's code. This DOES
671 // HAPPEN! (PF00072.15.stk does this)
672 // JBPNote: Uncomment to debug writing out of files that do not read
673 // back in due to ArrayOutOfBoundExceptions.
674 // System.err.println("vamsasSeq backref: "+id+"");
675 // System.err.println(jds.getName()+"
676 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
677 // System.err.println("Hashcode: "+seqHash(jds));
678 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
679 // System.err.println(rsq.getName()+"
680 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
681 // System.err.println("Hashcode: "+seqHash(rsq));
685 vamsasSeq = createVamsasSequence(id, jds);
686 vamsasSet.addSequence(vamsasSeq);
687 seqRefIds.put(id, jds);
691 jseq.setStart(jds.getStart());
692 jseq.setEnd(jds.getEnd());
693 jseq.setColour(av.getSequenceColour(jds).getRGB());
695 jseq.setId(id); // jseq id should be a string not a number
698 // Store any sequences this sequence represents
699 if (av.hasHiddenRows())
701 jseq.setHidden(av.getAlignment().getHiddenSequences()
704 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
706 jalview.datamodel.SequenceI[] reps = av
707 .getRepresentedSequences(jal.getSequenceAt(i))
708 .getSequencesInOrder(jal);
710 for (int h = 0; h < reps.length; h++)
712 if (reps[h] != jal.getSequenceAt(i))
714 jseq.addHiddenSequences(jal.findIndex(reps[h]));
721 if (jdatasq.getSequenceFeatures() != null)
723 jalview.datamodel.SequenceFeature[] sf = jdatasq
724 .getSequenceFeatures();
726 while (index < sf.length)
728 Features features = new Features();
730 features.setBegin(sf[index].getBegin());
731 features.setEnd(sf[index].getEnd());
732 features.setDescription(sf[index].getDescription());
733 features.setType(sf[index].getType());
734 features.setFeatureGroup(sf[index].getFeatureGroup());
735 features.setScore(sf[index].getScore());
736 if (sf[index].links != null)
738 for (int l = 0; l < sf[index].links.size(); l++)
740 OtherData keyValue = new OtherData();
741 keyValue.setKey("LINK_" + l);
742 keyValue.setValue(sf[index].links.elementAt(l).toString());
743 features.addOtherData(keyValue);
746 if (sf[index].otherDetails != null)
749 Enumeration keys = sf[index].otherDetails.keys();
750 while (keys.hasMoreElements())
752 key = keys.nextElement().toString();
753 OtherData keyValue = new OtherData();
754 keyValue.setKey(key);
755 keyValue.setValue(sf[index].otherDetails.get(key).toString());
756 features.addOtherData(keyValue);
760 jseq.addFeatures(features);
765 if (jdatasq.getPDBId() != null)
767 Enumeration en = jdatasq.getPDBId().elements();
768 while (en.hasMoreElements())
770 Pdbids pdb = new Pdbids();
771 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
774 pdb.setId(entry.getId());
775 pdb.setType(entry.getType());
778 * Store any structure views associated with this sequence. This
779 * section copes with duplicate entries in the project, so a dataset
780 * only view *should* be coped with sensibly.
782 // This must have been loaded, is it still visible?
783 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
784 String matchedFile = null;
785 for (int f = frames.length - 1; f > -1; f--)
787 if (frames[f] instanceof StructureViewerBase)
789 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
790 matchedFile = saveStructureState(ap, jds, pdb, entry,
791 viewIds, matchedFile, viewFrame);
795 if (matchedFile != null || entry.getFile() != null)
797 if (entry.getFile() != null)
800 matchedFile = entry.getFile();
802 pdb.setFile(matchedFile); // entry.getFile());
803 if (pdbfiles == null)
805 pdbfiles = new ArrayList<String>();
808 if (!pdbfiles.contains(entry.getId()))
810 pdbfiles.add(entry.getId());
811 DataInputStream dis = null;
814 File file = new File(matchedFile);
815 if (file.exists() && jout != null)
817 byte[] data = new byte[(int) file.length()];
818 jout.putNextEntry(new JarEntry(entry.getId()));
819 dis = new DataInputStream(
820 new FileInputStream(file));
823 DataOutputStream dout = new DataOutputStream(jout);
824 dout.write(data, 0, data.length);
828 } catch (Exception ex)
830 ex.printStackTrace();
838 } catch (IOException e)
848 if (entry.getProperty() != null)
850 PdbentryItem item = new PdbentryItem();
851 Hashtable properties = entry.getProperty();
852 Enumeration en2 = properties.keys();
853 while (en2.hasMoreElements())
855 Property prop = new Property();
856 String key = en2.nextElement().toString();
858 prop.setValue(properties.get(key).toString());
859 item.addProperty(prop);
861 pdb.addPdbentryItem(item);
871 if (!storeDS && av.hasHiddenRows())
873 jal = av.getAlignment();
876 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
878 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
879 for (int i = 0; i < jac.length; i++)
881 AlcodonFrame alc = new AlcodonFrame();
882 vamsasSet.addAlcodonFrame(alc);
883 for (int p = 0; p < jac[i].aaWidth; p++)
885 Alcodon cmap = new Alcodon();
886 if (jac[i].codons[p] != null)
888 // Null codons indicate a gapped column in the translated peptide
890 cmap.setPos1(jac[i].codons[p][0]);
891 cmap.setPos2(jac[i].codons[p][1]);
892 cmap.setPos3(jac[i].codons[p][2]);
894 alc.addAlcodon(cmap);
896 if (jac[i].getProtMappings() != null
897 && jac[i].getProtMappings().length > 0)
899 SequenceI[] dnas = jac[i].getdnaSeqs();
900 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
901 for (int m = 0; m < pmaps.length; m++)
903 AlcodMap alcmap = new AlcodMap();
904 alcmap.setDnasq(seqHash(dnas[m]));
905 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
907 alc.addAlcodMap(alcmap);
914 // /////////////////////////////////
915 if (!storeDS && av.currentTree != null)
917 // FIND ANY ASSOCIATED TREES
918 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
919 if (Desktop.desktop != null)
921 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
923 for (int t = 0; t < frames.length; t++)
925 if (frames[t] instanceof TreePanel)
927 TreePanel tp = (TreePanel) frames[t];
929 if (tp.treeCanvas.av.getAlignment() == jal)
931 Tree tree = new Tree();
932 tree.setTitle(tp.getTitle());
933 tree.setCurrentTree((av.currentTree == tp.getTree()));
934 tree.setNewick(tp.getTree().toString());
935 tree.setThreshold(tp.treeCanvas.threshold);
937 tree.setFitToWindow(tp.fitToWindow.getState());
938 tree.setFontName(tp.getTreeFont().getName());
939 tree.setFontSize(tp.getTreeFont().getSize());
940 tree.setFontStyle(tp.getTreeFont().getStyle());
941 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
943 tree.setShowBootstrap(tp.bootstrapMenu.getState());
944 tree.setShowDistances(tp.distanceMenu.getState());
946 tree.setHeight(tp.getHeight());
947 tree.setWidth(tp.getWidth());
948 tree.setXpos(tp.getX());
949 tree.setYpos(tp.getY());
950 tree.setId(makeHashCode(tp, null));
959 * store forward refs from an annotationRow to any groups
961 IdentityHashMap groupRefs = new IdentityHashMap();
964 for (SequenceI sq : jal.getSequences())
966 // Store annotation on dataset sequences only
967 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
968 if (aa != null && aa.length > 0)
970 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
977 if (jal.getAlignmentAnnotation() != null)
979 // Store the annotation shown on the alignment.
980 jalview.datamodel.AlignmentAnnotation[] aa = jal
981 .getAlignmentAnnotation();
982 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
987 if (jal.getGroups() != null)
989 JGroup[] groups = new JGroup[jal.getGroups().size()];
991 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
993 groups[++i] = new JGroup();
995 groups[i].setStart(sg.getStartRes());
996 groups[i].setEnd(sg.getEndRes());
997 groups[i].setName(sg.getName());
998 if (groupRefs.containsKey(sg))
1000 // group has references so set it's ID field
1001 groups[i].setId(groupRefs.get(sg).toString());
1005 if (sg.cs.conservationApplied())
1007 groups[i].setConsThreshold(sg.cs.getConservationInc());
1009 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1011 groups[i].setColour(setUserColourScheme(sg.cs, userColours,
1017 .setColour(ColourSchemeProperty.getColourName(sg.cs));
1020 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1022 groups[i].setColour("AnnotationColourGradient");
1023 groups[i].setAnnotationColours(constructAnnotationColours(
1024 (jalview.schemes.AnnotationColourGradient) sg.cs,
1027 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1030 .setColour(setUserColourScheme(sg.cs, userColours, jms));
1034 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1037 groups[i].setPidThreshold(sg.cs.getThreshold());
1040 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1041 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1042 groups[i].setDisplayText(sg.getDisplayText());
1043 groups[i].setColourText(sg.getColourText());
1044 groups[i].setTextCol1(sg.textColour.getRGB());
1045 groups[i].setTextCol2(sg.textColour2.getRGB());
1046 groups[i].setTextColThreshold(sg.thresholdTextColour);
1047 groups[i].setShowUnconserved(sg.getShowNonconserved());
1048 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1049 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1050 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1051 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1052 for (int s = 0; s < sg.getSize(); s++)
1054 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1056 groups[i].addSeq(seqHash(seq));
1060 jms.setJGroup(groups);
1064 // /////////SAVE VIEWPORT
1065 Viewport view = new Viewport();
1066 view.setTitle(ap.alignFrame.getTitle());
1067 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1068 av.getSequenceSetId()));
1069 view.setId(av.getViewId());
1070 view.setViewName(av.viewName);
1071 view.setGatheredViews(av.gatherViewsHere);
1073 if (ap.av.explodedPosition != null)
1075 view.setXpos(av.explodedPosition.x);
1076 view.setYpos(av.explodedPosition.y);
1077 view.setWidth(av.explodedPosition.width);
1078 view.setHeight(av.explodedPosition.height);
1082 view.setXpos(ap.alignFrame.getBounds().x);
1083 view.setYpos(ap.alignFrame.getBounds().y);
1084 view.setWidth(ap.alignFrame.getBounds().width);
1085 view.setHeight(ap.alignFrame.getBounds().height);
1088 view.setStartRes(av.startRes);
1089 view.setStartSeq(av.startSeq);
1091 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1093 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1096 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1098 AnnotationColours ac = constructAnnotationColours(
1099 (jalview.schemes.AnnotationColourGradient) av
1100 .getGlobalColourScheme(),
1103 view.setAnnotationColours(ac);
1104 view.setBgColour("AnnotationColourGradient");
1108 view.setBgColour(ColourSchemeProperty.getColourName(av
1109 .getGlobalColourScheme()));
1112 ColourSchemeI cs = av.getGlobalColourScheme();
1116 if (cs.conservationApplied())
1118 view.setConsThreshold(cs.getConservationInc());
1119 if (cs instanceof jalview.schemes.UserColourScheme)
1121 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1125 if (cs instanceof ResidueColourScheme)
1127 view.setPidThreshold(cs.getThreshold());
1131 view.setConservationSelected(av.getConservationSelected());
1132 view.setPidSelected(av.getAbovePIDThreshold());
1133 view.setFontName(av.font.getName());
1134 view.setFontSize(av.font.getSize());
1135 view.setFontStyle(av.font.getStyle());
1136 view.setRenderGaps(av.renderGaps);
1137 view.setShowAnnotation(av.getShowAnnotation());
1138 view.setShowBoxes(av.getShowBoxes());
1139 view.setShowColourText(av.getColourText());
1140 view.setShowFullId(av.getShowJVSuffix());
1141 view.setRightAlignIds(av.isRightAlignIds());
1142 view.setShowSequenceFeatures(av.showSequenceFeatures);
1143 view.setShowText(av.getShowText());
1144 view.setShowUnconserved(av.getShowUnconserved());
1145 view.setWrapAlignment(av.getWrapAlignment());
1146 view.setTextCol1(av.textColour.getRGB());
1147 view.setTextCol2(av.textColour2.getRGB());
1148 view.setTextColThreshold(av.thresholdTextColour);
1149 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1150 view.setShowSequenceLogo(av.isShowSequenceLogo());
1151 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1152 view.setShowGroupConsensus(av.isShowGroupConsensus());
1153 view.setShowGroupConservation(av.isShowGroupConservation());
1154 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1155 view.setShowDbRefTooltip(av.isShowDbRefs());
1156 view.setFollowHighlight(av.followHighlight);
1157 view.setFollowSelection(av.followSelection);
1158 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1159 if (av.getFeaturesDisplayed() != null)
1161 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1163 String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder;
1165 Vector settingsAdded = new Vector();
1166 Object gstyle = null;
1167 GraduatedColor gcol = null;
1168 if (renderOrder != null)
1170 for (int ro = 0; ro < renderOrder.length; ro++)
1172 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1173 .getFeatureStyle(renderOrder[ro]);
1174 Setting setting = new Setting();
1175 setting.setType(renderOrder[ro]);
1176 if (gstyle instanceof GraduatedColor)
1178 gcol = (GraduatedColor) gstyle;
1179 setting.setColour(gcol.getMaxColor().getRGB());
1180 setting.setMincolour(gcol.getMinColor().getRGB());
1181 setting.setMin(gcol.getMin());
1182 setting.setMax(gcol.getMax());
1183 setting.setColourByLabel(gcol.isColourByLabel());
1184 setting.setAutoScale(gcol.isAutoScale());
1185 setting.setThreshold(gcol.getThresh());
1186 setting.setThreshstate(gcol.getThreshType());
1190 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1191 .getColour(renderOrder[ro]).getRGB());
1194 setting.setDisplay(av.getFeaturesDisplayed()
1195 .containsKey(renderOrder[ro]));
1196 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1197 .getOrder(renderOrder[ro]);
1200 setting.setOrder(rorder);
1202 fs.addSetting(setting);
1203 settingsAdded.addElement(renderOrder[ro]);
1207 // Make sure we save none displayed feature settings
1208 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureColours
1209 .keySet().iterator();
1210 while (en.hasNext())
1212 String key = en.next().toString();
1213 if (settingsAdded.contains(key))
1218 Setting setting = new Setting();
1219 setting.setType(key);
1220 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1221 .getColour(key).getRGB());
1223 setting.setDisplay(false);
1224 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1228 setting.setOrder(rorder);
1230 fs.addSetting(setting);
1231 settingsAdded.addElement(key);
1233 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups
1234 .keySet().iterator();
1235 Vector groupsAdded = new Vector();
1236 while (en.hasNext())
1238 String grp = en.next().toString();
1239 if (groupsAdded.contains(grp))
1243 Group g = new Group();
1245 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1246 .getFeatureRenderer().featureGroups.get(grp))
1249 groupsAdded.addElement(grp);
1251 jms.setFeatureSettings(fs);
1255 if (av.hasHiddenColumns())
1257 if (av.getColumnSelection() == null
1258 || av.getColumnSelection().getHiddenColumns() == null)
1260 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1264 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1267 int[] region = (int[]) av.getColumnSelection()
1268 .getHiddenColumns().elementAt(c);
1269 HiddenColumns hc = new HiddenColumns();
1270 hc.setStart(region[0]);
1271 hc.setEnd(region[1]);
1272 view.addHiddenColumns(hc);
1276 if (calcIdSet.size() > 0)
1278 for (String calcId : calcIdSet)
1280 if (calcId.trim().length() > 0)
1282 CalcIdParam cidp = createCalcIdParam(calcId, av);
1283 // Some calcIds have no parameters.
1286 view.addCalcIdParam(cidp);
1292 jms.addViewport(view);
1294 object.setJalviewModelSequence(jms);
1295 object.getVamsasModel().addSequenceSet(vamsasSet);
1297 if (jout != null && fileName != null)
1299 // We may not want to write the object to disk,
1300 // eg we can copy the alignViewport to a new view object
1301 // using save and then load
1304 JarEntry entry = new JarEntry(fileName);
1305 jout.putNextEntry(entry);
1306 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1308 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1310 marshaller.marshal(object);
1313 } catch (Exception ex)
1315 // TODO: raise error in GUI if marshalling failed.
1316 ex.printStackTrace();
1323 * Save the state of a structure viewer
1328 * the archive XML element under which to save the state
1331 * @param matchedFile
1335 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1336 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1337 String matchedFile, StructureViewerBase viewFrame)
1339 final AAStructureBindingModel bindingModel = viewFrame
1341 for (int peid = 0; peid < bindingModel
1342 .getPdbCount(); peid++)
1344 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1345 final String pdbId = pdbentry.getId();
1346 if (!pdbId.equals(entry.getId())
1347 && !(entry.getId().length() > 4 && entry.getId()
1349 .startsWith(pdbId.toLowerCase())))
1353 if (matchedFile == null)
1355 matchedFile = pdbentry.getFile();
1357 else if (!matchedFile.equals(pdbentry
1361 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1362 + pdbentry.getFile());
1366 // can get at it if the ID
1367 // match is ambiguous (e.g.
1369 String statestring = viewFrame.getStateInfo();
1371 for (int smap = 0; smap < viewFrame.getBinding()
1372 .getSequence()[peid].length; smap++)
1374 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1375 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1377 StructureState state = new StructureState();
1378 state.setVisible(true);
1379 state.setXpos(viewFrame.getX());
1380 state.setYpos(viewFrame.getY());
1381 state.setWidth(viewFrame.getWidth());
1382 state.setHeight(viewFrame.getHeight());
1383 final String viewId = viewFrame.getViewId();
1384 state.setViewId(viewId);
1385 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1386 state.setColourwithAlignPanel(viewFrame
1387 .isUsedforcolourby(ap));
1388 state.setColourByJmol(viewFrame.isColouredByViewer());
1390 * Only store each structure viewer's state once in each XML document.
1392 if (!viewIds.contains(viewId))
1394 viewIds.add(viewId);
1395 state.setContent(statestring.replaceAll("\n", ""));
1399 state.setContent("# duplicate state");
1401 pdb.addStructureState(state);
1408 private AnnotationColours constructAnnotationColours(
1409 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1410 JalviewModelSequence jms)
1412 AnnotationColours ac = new AnnotationColours();
1413 ac.setAboveThreshold(acg.getAboveThreshold());
1414 ac.setThreshold(acg.getAnnotationThreshold());
1415 ac.setAnnotation(acg.getAnnotation());
1416 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1418 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1423 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1427 ac.setMaxColour(acg.getMaxColour().getRGB());
1428 ac.setMinColour(acg.getMinColour().getRGB());
1429 ac.setPerSequence(acg.isSeqAssociated());
1430 ac.setPredefinedColours(acg.isPredefinedColours());
1434 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1435 IdentityHashMap groupRefs, AlignmentViewport av,
1436 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1439 for (int i = 0; i < aa.length; i++)
1441 Annotation an = new Annotation();
1443 if (aa[i].annotationId != null)
1445 annotationIds.put(aa[i].annotationId, aa[i]);
1448 an.setId(aa[i].annotationId);
1450 an.setVisible(aa[i].visible);
1452 an.setDescription(aa[i].description);
1454 if (aa[i].sequenceRef != null)
1456 // TODO later annotation sequenceRef should be the XML ID of the
1457 // sequence rather than its display name
1458 an.setSequenceRef(aa[i].sequenceRef.getName());
1460 if (aa[i].groupRef != null)
1462 Object groupIdr = groupRefs.get(aa[i].groupRef);
1463 if (groupIdr == null)
1465 // make a locally unique String
1466 groupRefs.put(aa[i].groupRef,
1467 groupIdr = ("" + System.currentTimeMillis()
1468 + aa[i].groupRef.getName() + groupRefs.size()));
1470 an.setGroupRef(groupIdr.toString());
1473 // store all visualization attributes for annotation
1474 an.setGraphHeight(aa[i].graphHeight);
1475 an.setCentreColLabels(aa[i].centreColLabels);
1476 an.setScaleColLabels(aa[i].scaleColLabel);
1477 an.setShowAllColLabels(aa[i].showAllColLabels);
1478 an.setBelowAlignment(aa[i].belowAlignment);
1480 if (aa[i].graph > 0)
1483 an.setGraphType(aa[i].graph);
1484 an.setGraphGroup(aa[i].graphGroup);
1485 if (aa[i].getThreshold() != null)
1487 ThresholdLine line = new ThresholdLine();
1488 line.setLabel(aa[i].getThreshold().label);
1489 line.setValue(aa[i].getThreshold().value);
1490 line.setColour(aa[i].getThreshold().colour.getRGB());
1491 an.setThresholdLine(line);
1499 an.setLabel(aa[i].label);
1501 if (aa[i] == av.getAlignmentQualityAnnot()
1502 || aa[i] == av.getAlignmentConservationAnnotation()
1503 || aa[i] == av.getAlignmentConsensusAnnotation()
1504 || aa[i].autoCalculated)
1506 // new way of indicating autocalculated annotation -
1507 an.setAutoCalculated(aa[i].autoCalculated);
1509 if (aa[i].hasScore())
1511 an.setScore(aa[i].getScore());
1514 if (aa[i].getCalcId() != null)
1516 calcIdSet.add(aa[i].getCalcId());
1517 an.setCalcId(aa[i].getCalcId());
1519 if (aa[i].hasProperties())
1521 for (String pr : aa[i].getProperties())
1523 Property prop = new Property();
1525 prop.setValue(aa[i].getProperty(pr));
1526 an.addProperty(prop);
1529 AnnotationElement ae;
1530 if (aa[i].annotations != null)
1532 an.setScoreOnly(false);
1533 for (int a = 0; a < aa[i].annotations.length; a++)
1535 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1540 ae = new AnnotationElement();
1541 if (aa[i].annotations[a].description != null)
1543 ae.setDescription(aa[i].annotations[a].description);
1545 if (aa[i].annotations[a].displayCharacter != null)
1547 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1550 if (!Float.isNaN(aa[i].annotations[a].value))
1552 ae.setValue(aa[i].annotations[a].value);
1556 if (aa[i].annotations[a].secondaryStructure > ' ')
1558 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1562 if (aa[i].annotations[a].colour != null
1563 && aa[i].annotations[a].colour != java.awt.Color.black)
1565 ae.setColour(aa[i].annotations[a].colour.getRGB());
1568 an.addAnnotationElement(ae);
1569 if (aa[i].autoCalculated)
1571 // only write one non-null entry into the annotation row -
1572 // sufficient to get the visualization attributes necessary to
1580 an.setScoreOnly(true);
1582 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1584 // skip autocalculated annotation - these are only provided for
1586 vamsasSet.addAnnotation(an);
1592 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1594 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1595 if (settings != null)
1597 CalcIdParam vCalcIdParam = new CalcIdParam();
1598 vCalcIdParam.setCalcId(calcId);
1599 vCalcIdParam.addServiceURL(settings.getServiceURI());
1600 // generic URI allowing a third party to resolve another instance of the
1601 // service used for this calculation
1602 for (String urls : settings.getServiceURLs())
1604 vCalcIdParam.addServiceURL(urls);
1606 vCalcIdParam.setVersion("1.0");
1607 if (settings.getPreset() != null)
1609 WsParamSetI setting = settings.getPreset();
1610 vCalcIdParam.setName(setting.getName());
1611 vCalcIdParam.setDescription(setting.getDescription());
1615 vCalcIdParam.setName("");
1616 vCalcIdParam.setDescription("Last used parameters");
1618 // need to be able to recover 1) settings 2) user-defined presets or
1619 // recreate settings from preset 3) predefined settings provided by
1620 // service - or settings that can be transferred (or discarded)
1621 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1623 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1624 // todo - decide if updateImmediately is needed for any projects.
1626 return vCalcIdParam;
1631 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1634 if (calcIdParam.getVersion().equals("1.0"))
1636 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1637 .getPreferredServiceFor(calcIdParam.getServiceURL());
1638 if (service != null)
1640 WsParamSetI parmSet = null;
1643 parmSet = service.getParamStore().parseServiceParameterFile(
1644 calcIdParam.getName(), calcIdParam.getDescription(),
1645 calcIdParam.getServiceURL(),
1646 calcIdParam.getParameters().replace("|\\n|", "\n"));
1647 } catch (IOException x)
1649 warn("Couldn't parse parameter data for "
1650 + calcIdParam.getCalcId(), x);
1653 List<ArgumentI> argList = null;
1654 if (calcIdParam.getName().length() > 0)
1656 parmSet = service.getParamStore()
1657 .getPreset(calcIdParam.getName());
1658 if (parmSet != null)
1660 // TODO : check we have a good match with settings in AACon -
1661 // otherwise we'll need to create a new preset
1666 argList = parmSet.getArguments();
1669 AAConSettings settings = new AAConSettings(
1670 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1671 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1672 calcIdParam.isNeedsUpdate());
1677 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1681 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1685 * External mapping between jalview objects and objects yielding a valid and
1686 * unique object ID string. This is null for normal Jalview project IO, but
1687 * non-null when a jalview project is being read or written as part of a
1690 IdentityHashMap jv2vobj = null;
1693 * Construct a unique ID for jvobj using either existing bindings or if none
1694 * exist, the result of the hashcode call for the object.
1697 * jalview data object
1698 * @return unique ID for referring to jvobj
1700 private String makeHashCode(Object jvobj, String altCode)
1702 if (jv2vobj != null)
1704 Object id = jv2vobj.get(jvobj);
1707 return id.toString();
1709 // check string ID mappings
1710 if (jvids2vobj != null && jvobj instanceof String)
1712 id = jvids2vobj.get(jvobj);
1716 return id.toString();
1718 // give up and warn that something has gone wrong
1719 warn("Cannot find ID for object in external mapping : " + jvobj);
1725 * return local jalview object mapped to ID, if it exists
1729 * @return null or object bound to idcode
1731 private Object retrieveExistingObj(String idcode)
1733 if (idcode != null && vobj2jv != null)
1735 return vobj2jv.get(idcode);
1741 * binding from ID strings from external mapping table to jalview data model
1744 private Hashtable vobj2jv;
1746 private Sequence createVamsasSequence(String id, SequenceI jds)
1748 return createVamsasSequence(true, id, jds, null);
1751 private Sequence createVamsasSequence(boolean recurse, String id,
1752 SequenceI jds, SequenceI parentseq)
1754 Sequence vamsasSeq = new Sequence();
1755 vamsasSeq.setId(id);
1756 vamsasSeq.setName(jds.getName());
1757 vamsasSeq.setSequence(jds.getSequenceAsString());
1758 vamsasSeq.setDescription(jds.getDescription());
1759 jalview.datamodel.DBRefEntry[] dbrefs = null;
1760 if (jds.getDatasetSequence() != null)
1762 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1763 if (jds.getDatasetSequence().getDBRef() != null)
1765 dbrefs = jds.getDatasetSequence().getDBRef();
1770 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1771 // dataset sequences only
1772 dbrefs = jds.getDBRef();
1776 for (int d = 0; d < dbrefs.length; d++)
1778 DBRef dbref = new DBRef();
1779 dbref.setSource(dbrefs[d].getSource());
1780 dbref.setVersion(dbrefs[d].getVersion());
1781 dbref.setAccessionId(dbrefs[d].getAccessionId());
1782 if (dbrefs[d].hasMap())
1784 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1786 dbref.setMapping(mp);
1788 vamsasSeq.addDBRef(dbref);
1794 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1795 SequenceI parentseq, SequenceI jds, boolean recurse)
1798 if (jmp.getMap() != null)
1802 jalview.util.MapList mlst = jmp.getMap();
1803 int r[] = mlst.getFromRanges();
1804 for (int s = 0; s < r.length; s += 2)
1806 MapListFrom mfrom = new MapListFrom();
1807 mfrom.setStart(r[s]);
1808 mfrom.setEnd(r[s + 1]);
1809 mp.addMapListFrom(mfrom);
1811 r = mlst.getToRanges();
1812 for (int s = 0; s < r.length; s += 2)
1814 MapListTo mto = new MapListTo();
1816 mto.setEnd(r[s + 1]);
1817 mp.addMapListTo(mto);
1819 mp.setMapFromUnit(mlst.getFromRatio());
1820 mp.setMapToUnit(mlst.getToRatio());
1821 if (jmp.getTo() != null)
1823 MappingChoice mpc = new MappingChoice();
1825 && (parentseq != jmp.getTo() || parentseq
1826 .getDatasetSequence() != jmp.getTo()))
1828 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1834 SequenceI ps = null;
1835 if (parentseq != jmp.getTo()
1836 && parentseq.getDatasetSequence() != jmp.getTo())
1838 // chaining dbref rather than a handshaking one
1839 jmpid = seqHash(ps = jmp.getTo());
1843 jmpid = seqHash(ps = parentseq);
1845 mpc.setDseqFor(jmpid);
1846 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1848 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1849 seqRefIds.put(mpc.getDseqFor(), ps);
1853 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1856 mp.setMappingChoice(mpc);
1862 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
1863 List<UserColourScheme> userColours, JalviewModelSequence jms)
1866 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1867 boolean newucs = false;
1868 if (!userColours.contains(ucs))
1870 userColours.add(ucs);
1873 id = "ucs" + userColours.indexOf(ucs);
1876 // actually create the scheme's entry in the XML model
1877 java.awt.Color[] colours = ucs.getColours();
1878 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1879 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1881 for (int i = 0; i < colours.length; i++)
1883 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1884 col.setName(ResidueProperties.aa[i]);
1885 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1886 jbucs.addColour(col);
1888 if (ucs.getLowerCaseColours() != null)
1890 colours = ucs.getLowerCaseColours();
1891 for (int i = 0; i < colours.length; i++)
1893 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1894 col.setName(ResidueProperties.aa[i].toLowerCase());
1895 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1896 jbucs.addColour(col);
1901 uc.setUserColourScheme(jbucs);
1902 jms.addUserColours(uc);
1908 jalview.schemes.UserColourScheme getUserColourScheme(
1909 JalviewModelSequence jms, String id)
1911 UserColours[] uc = jms.getUserColours();
1912 UserColours colours = null;
1914 for (int i = 0; i < uc.length; i++)
1916 if (uc[i].getId().equals(id))
1924 java.awt.Color[] newColours = new java.awt.Color[24];
1926 for (int i = 0; i < 24; i++)
1928 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1929 .getUserColourScheme().getColour(i).getRGB(), 16));
1932 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1935 if (colours.getUserColourScheme().getColourCount() > 24)
1937 newColours = new java.awt.Color[23];
1938 for (int i = 0; i < 23; i++)
1940 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1941 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1943 ucs.setLowerCaseColours(newColours);
1950 * contains last error message (if any) encountered by XML loader.
1952 String errorMessage = null;
1955 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1956 * exceptions are raised during project XML parsing
1958 public boolean attemptversion1parse = true;
1961 * Load a jalview project archive from a jar file
1964 * - HTTP URL or filename
1966 public AlignFrame loadJalviewAlign(final String file)
1969 jalview.gui.AlignFrame af = null;
1973 // create list to store references for any new Jmol viewers created
1974 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1975 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1976 // Workaround is to make sure caller implements the JarInputStreamProvider
1978 // so we can re-open the jar input stream for each entry.
1980 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1981 af = loadJalviewAlign(jprovider);
1983 } catch (MalformedURLException e)
1985 errorMessage = "Invalid URL format for '" + file + "'";
1991 SwingUtilities.invokeAndWait(new Runnable()
1995 setLoadingFinishedForNewStructureViewers();
1998 } catch (Exception x)
2006 private jarInputStreamProvider createjarInputStreamProvider(
2007 final String file) throws MalformedURLException
2010 errorMessage = null;
2011 uniqueSetSuffix = null;
2013 viewportsAdded = null;
2014 frefedSequence = null;
2016 if (file.startsWith("http://"))
2018 url = new URL(file);
2020 final URL _url = url;
2021 return new jarInputStreamProvider()
2025 public JarInputStream getJarInputStream() throws IOException
2029 return new JarInputStream(_url.openStream());
2033 return new JarInputStream(new FileInputStream(file));
2038 public String getFilename()
2046 * Recover jalview session from a jalview project archive. Caller may
2047 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2048 * themselves. Any null fields will be initialised with default values,
2049 * non-null fields are left alone.
2054 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2056 errorMessage = null;
2057 if (uniqueSetSuffix == null)
2059 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2061 if (seqRefIds == null)
2063 seqRefIds = new HashMap<String, SequenceI>();
2065 if (viewportsAdded == null)
2067 viewportsAdded = new Hashtable();
2069 if (frefedSequence == null)
2071 frefedSequence = new Vector();
2074 jalview.gui.AlignFrame af = null, _af = null;
2075 Hashtable gatherToThisFrame = new Hashtable();
2076 final String file = jprovider.getFilename();
2079 JarInputStream jin = null;
2080 JarEntry jarentry = null;
2085 jin = jprovider.getJarInputStream();
2086 for (int i = 0; i < entryCount; i++)
2088 jarentry = jin.getNextJarEntry();
2091 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2093 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2094 JalviewModel object = new JalviewModel();
2096 Unmarshaller unmar = new Unmarshaller(object);
2097 unmar.setValidation(false);
2098 object = (JalviewModel) unmar.unmarshal(in);
2099 if (true) // !skipViewport(object))
2101 _af = loadFromObject(object, file, true, jprovider);
2102 if (object.getJalviewModelSequence().getViewportCount() > 0)
2105 if (af.viewport.gatherViewsHere)
2107 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2113 else if (jarentry != null)
2115 // Some other file here.
2118 } while (jarentry != null);
2119 resolveFrefedSequences();
2120 } catch (java.io.FileNotFoundException ex)
2122 ex.printStackTrace();
2123 errorMessage = "Couldn't locate Jalview XML file : " + file;
2124 System.err.println("Exception whilst loading jalview XML file : "
2126 } catch (java.net.UnknownHostException ex)
2128 ex.printStackTrace();
2129 errorMessage = "Couldn't locate Jalview XML file : " + file;
2130 System.err.println("Exception whilst loading jalview XML file : "
2132 } catch (Exception ex)
2134 System.err.println("Parsing as Jalview Version 2 file failed.");
2135 ex.printStackTrace(System.err);
2136 if (attemptversion1parse)
2138 // Is Version 1 Jar file?
2141 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2142 } catch (Exception ex2)
2144 System.err.println("Exception whilst loading as jalviewXMLV1:");
2145 ex2.printStackTrace();
2149 if (Desktop.instance != null)
2151 Desktop.instance.stopLoading();
2155 System.out.println("Successfully loaded archive file");
2158 ex.printStackTrace();
2160 System.err.println("Exception whilst loading jalview XML file : "
2162 } catch (OutOfMemoryError e)
2164 // Don't use the OOM Window here
2165 errorMessage = "Out of memory loading jalview XML file";
2166 System.err.println("Out of memory whilst loading jalview XML file");
2167 e.printStackTrace();
2170 if (Desktop.instance != null)
2172 Desktop.instance.stopLoading();
2175 Enumeration en = gatherToThisFrame.elements();
2176 while (en.hasMoreElements())
2178 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2180 if (errorMessage != null)
2188 * check errorMessage for a valid error message and raise an error box in the
2189 * GUI or write the current errorMessage to stderr and then clear the error
2192 protected void reportErrors()
2194 reportErrors(false);
2197 protected void reportErrors(final boolean saving)
2199 if (errorMessage != null)
2201 final String finalErrorMessage = errorMessage;
2204 javax.swing.SwingUtilities.invokeLater(new Runnable()
2209 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2210 finalErrorMessage, "Error "
2211 + (saving ? "saving" : "loading")
2212 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2218 System.err.println("Problem loading Jalview file: " + errorMessage);
2221 errorMessage = null;
2224 Hashtable<String, String> alreadyLoadedPDB;
2227 * when set, local views will be updated from view stored in JalviewXML
2228 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2229 * sync if this is set to true.
2231 private final boolean updateLocalViews = false;
2233 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2235 if (alreadyLoadedPDB == null)
2237 alreadyLoadedPDB = new Hashtable();
2240 if (alreadyLoadedPDB.containsKey(pdbId))
2242 return alreadyLoadedPDB.get(pdbId).toString();
2247 JarInputStream jin = jprovider.getJarInputStream();
2249 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2250 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2251 * FileInputStream(jprovider)); }
2254 JarEntry entry = null;
2257 entry = jin.getNextJarEntry();
2258 } while (entry != null && !entry.getName().equals(pdbId));
2261 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2262 File outFile = File.createTempFile("jalview_pdb", ".txt");
2263 outFile.deleteOnExit();
2264 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2267 while ((data = in.readLine()) != null)
2274 } catch (Exception foo)
2279 String t = outFile.getAbsolutePath();
2280 alreadyLoadedPDB.put(pdbId, t);
2285 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2287 } catch (Exception ex)
2289 ex.printStackTrace();
2295 private class JvAnnotRow
2297 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2304 * persisted version of annotation row from which to take vis properties
2306 public jalview.datamodel.AlignmentAnnotation template;
2309 * original position of the annotation row in the alignment
2315 * Load alignment frame from jalview XML DOM object
2320 * filename source string
2321 * @param loadTreesAndStructures
2322 * when false only create Viewport
2324 * data source provider
2325 * @return alignment frame created from view stored in DOM
2327 AlignFrame loadFromObject(JalviewModel object, String file,
2328 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2330 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2331 Sequence[] vamsasSeq = vamsasSet.getSequence();
2333 JalviewModelSequence jms = object.getJalviewModelSequence();
2335 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2338 // ////////////////////////////////
2341 Vector hiddenSeqs = null;
2342 jalview.datamodel.Sequence jseq;
2344 ArrayList tmpseqs = new ArrayList();
2346 boolean multipleView = false;
2348 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2349 int vi = 0; // counter in vamsasSeq array
2350 for (int i = 0; i < jseqs.length; i++)
2352 String seqId = jseqs[i].getId();
2354 if (seqRefIds.get(seqId) != null)
2356 tmpseqs.add(seqRefIds.get(seqId));
2357 multipleView = true;
2361 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2362 vamsasSeq[vi].getSequence());
2363 jseq.setDescription(vamsasSeq[vi].getDescription());
2364 jseq.setStart(jseqs[i].getStart());
2365 jseq.setEnd(jseqs[i].getEnd());
2366 jseq.setVamsasId(uniqueSetSuffix + seqId);
2367 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2372 if (jseqs[i].getHidden())
2374 if (hiddenSeqs == null)
2376 hiddenSeqs = new Vector();
2379 hiddenSeqs.addElement(seqRefIds.get(seqId));
2385 // Create the alignment object from the sequence set
2386 // ///////////////////////////////
2387 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2390 tmpseqs.toArray(orderedSeqs);
2392 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2395 // / Add the alignment properties
2396 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2398 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2399 al.setProperty(ssp.getKey(), ssp.getValue());
2403 // SequenceFeatures are added to the DatasetSequence,
2404 // so we must create or recover the dataset before loading features
2405 // ///////////////////////////////
2406 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2408 // older jalview projects do not have a dataset id.
2409 al.setDataset(null);
2413 // recover dataset - passing on flag indicating if this a 'viewless'
2414 // sequence set (a.k.a. a stored dataset for the project)
2415 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2416 .getViewportCount() == 0);
2418 // ///////////////////////////////
2420 Hashtable pdbloaded = new Hashtable();
2423 // load sequence features, database references and any associated PDB
2424 // structures for the alignment
2425 for (int i = 0; i < vamsasSeq.length; i++)
2427 if (jseqs[i].getFeaturesCount() > 0)
2429 Features[] features = jseqs[i].getFeatures();
2430 for (int f = 0; f < features.length; f++)
2432 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2433 features[f].getType(), features[f].getDescription(),
2434 features[f].getStatus(), features[f].getBegin(),
2435 features[f].getEnd(), features[f].getFeatureGroup());
2437 sf.setScore(features[f].getScore());
2438 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2440 OtherData keyValue = features[f].getOtherData(od);
2441 if (keyValue.getKey().startsWith("LINK"))
2443 sf.addLink(keyValue.getValue());
2447 sf.setValue(keyValue.getKey(), keyValue.getValue());
2452 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2455 if (vamsasSeq[i].getDBRefCount() > 0)
2457 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2459 if (jseqs[i].getPdbidsCount() > 0)
2461 Pdbids[] ids = jseqs[i].getPdbids();
2462 for (int p = 0; p < ids.length; p++)
2464 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2465 entry.setId(ids[p].getId());
2466 entry.setType(ids[p].getType());
2467 if (ids[p].getFile() != null)
2469 if (!pdbloaded.containsKey(ids[p].getFile()))
2471 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2475 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2478 StructureSelectionManager.getStructureSelectionManager(
2480 .registerPDBEntry(entry);
2481 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2485 } // end !multipleview
2487 // ///////////////////////////////
2488 // LOAD SEQUENCE MAPPINGS
2490 if (vamsasSet.getAlcodonFrameCount() > 0)
2492 // TODO Potentially this should only be done once for all views of an
2494 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2495 for (int i = 0; i < alc.length; i++)
2497 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2498 alc[i].getAlcodonCount());
2499 if (alc[i].getAlcodonCount() > 0)
2501 Alcodon[] alcods = alc[i].getAlcodon();
2502 for (int p = 0; p < cf.codons.length; p++)
2504 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2505 && alcods[p].hasPos3())
2507 // translated codons require three valid positions
2508 cf.codons[p] = new int[3];
2509 cf.codons[p][0] = (int) alcods[p].getPos1();
2510 cf.codons[p][1] = (int) alcods[p].getPos2();
2511 cf.codons[p][2] = (int) alcods[p].getPos3();
2515 cf.codons[p] = null;
2519 if (alc[i].getAlcodMapCount() > 0)
2521 AlcodMap[] maps = alc[i].getAlcodMap();
2522 for (int m = 0; m < maps.length; m++)
2524 SequenceI dnaseq = seqRefIds
2525 .get(maps[m].getDnasq());
2527 jalview.datamodel.Mapping mapping = null;
2528 // attach to dna sequence reference.
2529 if (maps[m].getMapping() != null)
2531 mapping = addMapping(maps[m].getMapping());
2535 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2540 frefedSequence.add(new Object[]
2541 { maps[m].getDnasq(), cf, mapping });
2545 al.addCodonFrame(cf);
2550 // ////////////////////////////////
2552 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2554 * store any annotations which forward reference a group's ID
2556 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2558 if (vamsasSet.getAnnotationCount() > 0)
2560 Annotation[] an = vamsasSet.getAnnotation();
2562 for (int i = 0; i < an.length; i++)
2565 * test if annotation is automatically calculated for this view only
2567 boolean autoForView = false;
2568 if (an[i].getLabel().equals("Quality")
2569 || an[i].getLabel().equals("Conservation")
2570 || an[i].getLabel().equals("Consensus"))
2572 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2574 if (!an[i].hasAutoCalculated())
2576 an[i].setAutoCalculated(true);
2580 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2582 // remove ID - we don't recover annotation from other views for
2583 // view-specific annotation
2587 // set visiblity for other annotation in this view
2588 if (an[i].getId() != null
2589 && annotationIds.containsKey(an[i].getId()))
2591 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2592 .get(an[i].getId());
2593 // in principle Visible should always be true for annotation displayed
2594 // in multiple views
2595 if (an[i].hasVisible())
2597 jda.visible = an[i].getVisible();
2600 al.addAnnotation(jda);
2604 // Construct new annotation from model.
2605 AnnotationElement[] ae = an[i].getAnnotationElement();
2606 jalview.datamodel.Annotation[] anot = null;
2607 java.awt.Color firstColour = null;
2609 if (!an[i].getScoreOnly())
2611 anot = new jalview.datamodel.Annotation[al.getWidth()];
2612 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2614 anpos = ae[aa].getPosition();
2616 if (anpos >= anot.length)
2621 anot[anpos] = new jalview.datamodel.Annotation(
2623 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2624 (ae[aa].getSecondaryStructure() == null || ae[aa]
2625 .getSecondaryStructure().length() == 0) ? ' '
2626 : ae[aa].getSecondaryStructure().charAt(0),
2630 // JBPNote: Consider verifying dataflow for IO of secondary
2631 // structure annotation read from Stockholm files
2632 // this was added to try to ensure that
2633 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2635 // anot[ae[aa].getPosition()].displayCharacter = "";
2637 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2638 if (firstColour == null)
2640 firstColour = anot[anpos].colour;
2644 jalview.datamodel.AlignmentAnnotation jaa = null;
2646 if (an[i].getGraph())
2648 float llim = 0, hlim = 0;
2649 // if (autoForView || an[i].isAutoCalculated()) {
2652 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2653 an[i].getDescription(), anot, llim, hlim,
2654 an[i].getGraphType());
2656 jaa.graphGroup = an[i].getGraphGroup();
2657 jaa._linecolour = firstColour;
2658 if (an[i].getThresholdLine() != null)
2660 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2661 .getThresholdLine().getValue(), an[i]
2662 .getThresholdLine().getLabel(), new java.awt.Color(
2663 an[i].getThresholdLine().getColour())));
2666 if (autoForView || an[i].isAutoCalculated())
2668 // Hardwire the symbol display line to ensure that labels for
2669 // histograms are displayed
2675 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2676 an[i].getDescription(), anot);
2677 jaa._linecolour = firstColour;
2679 // register new annotation
2680 if (an[i].getId() != null)
2682 annotationIds.put(an[i].getId(), jaa);
2683 jaa.annotationId = an[i].getId();
2685 // recover sequence association
2686 if (an[i].getSequenceRef() != null)
2688 if (al.findName(an[i].getSequenceRef()) != null)
2690 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2692 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2695 // and make a note of any group association
2696 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2698 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2699 .get(an[i].getGroupRef());
2702 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2703 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2708 if (an[i].hasScore())
2710 jaa.setScore(an[i].getScore());
2712 if (an[i].hasVisible())
2714 jaa.visible = an[i].getVisible();
2717 if (an[i].hasCentreColLabels())
2719 jaa.centreColLabels = an[i].getCentreColLabels();
2722 if (an[i].hasScaleColLabels())
2724 jaa.scaleColLabel = an[i].getScaleColLabels();
2726 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2728 // newer files have an 'autoCalculated' flag and store calculation
2729 // state in viewport properties
2730 jaa.autoCalculated = true; // means annotation will be marked for
2731 // update at end of load.
2733 if (an[i].hasGraphHeight())
2735 jaa.graphHeight = an[i].getGraphHeight();
2737 if (an[i].hasBelowAlignment())
2739 jaa.belowAlignment = an[i].isBelowAlignment();
2741 jaa.setCalcId(an[i].getCalcId());
2742 if (an[i].getPropertyCount() > 0)
2744 for (jalview.schemabinding.version2.Property prop : an[i]
2747 jaa.setProperty(prop.getName(), prop.getValue());
2750 if (jaa.autoCalculated)
2752 autoAlan.add(new JvAnnotRow(i, jaa));
2755 // if (!autoForView)
2757 // add autocalculated group annotation and any user created annotation
2759 al.addAnnotation(jaa);
2763 // ///////////////////////
2765 // Create alignment markup and styles for this view
2766 if (jms.getJGroupCount() > 0)
2768 JGroup[] groups = jms.getJGroup();
2769 boolean addAnnotSchemeGroup = false;
2770 for (int i = 0; i < groups.length; i++)
2772 ColourSchemeI cs = null;
2774 if (groups[i].getColour() != null)
2776 if (groups[i].getColour().startsWith("ucs"))
2778 cs = getUserColourScheme(jms, groups[i].getColour());
2780 else if (groups[i].getColour().equals("AnnotationColourGradient")
2781 && groups[i].getAnnotationColours() != null)
2783 addAnnotSchemeGroup = true;
2788 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2793 cs.setThreshold(groups[i].getPidThreshold(), true);
2797 Vector seqs = new Vector();
2799 for (int s = 0; s < groups[i].getSeqCount(); s++)
2801 String seqId = groups[i].getSeq(s) + "";
2802 jalview.datamodel.SequenceI ts = seqRefIds
2807 seqs.addElement(ts);
2811 if (seqs.size() < 1)
2816 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2817 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2818 groups[i].getDisplayText(), groups[i].getColourText(),
2819 groups[i].getStart(), groups[i].getEnd());
2821 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2823 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2824 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2825 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2826 .isShowUnconserved() : false);
2827 sg.thresholdTextColour = groups[i].getTextColThreshold();
2828 if (groups[i].hasShowConsensusHistogram())
2830 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2833 if (groups[i].hasShowSequenceLogo())
2835 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2837 if (groups[i].hasNormaliseSequenceLogo())
2839 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2841 if (groups[i].hasIgnoreGapsinConsensus())
2843 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2845 if (groups[i].getConsThreshold() != 0)
2847 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2848 "All", ResidueProperties.propHash, 3,
2849 sg.getSequences(null), 0, sg.getWidth() - 1);
2851 c.verdict(false, 25);
2852 sg.cs.setConservation(c);
2855 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2857 // re-instate unique group/annotation row reference
2858 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2859 .get(groups[i].getId());
2862 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2865 if (jaa.autoCalculated)
2867 // match up and try to set group autocalc alignment row for this
2869 if (jaa.label.startsWith("Consensus for "))
2871 sg.setConsensus(jaa);
2873 // match up and try to set group autocalc alignment row for this
2875 if (jaa.label.startsWith("Conservation for "))
2877 sg.setConservationRow(jaa);
2884 if (addAnnotSchemeGroup)
2886 // reconstruct the annotation colourscheme
2887 sg.cs = constructAnnotationColour(
2888 groups[i].getAnnotationColours(), null, al, jms, false);
2894 // only dataset in this model, so just return.
2897 // ///////////////////////////////
2900 // If we just load in the same jar file again, the sequenceSetId
2901 // will be the same, and we end up with multiple references
2902 // to the same sequenceSet. We must modify this id on load
2903 // so that each load of the file gives a unique id
2904 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2905 String viewId = (view.getId() == null ? null : view.getId()
2907 AlignFrame af = null;
2908 AlignViewport av = null;
2909 // now check to see if we really need to create a new viewport.
2910 if (multipleView && viewportsAdded.size() == 0)
2912 // We recovered an alignment for which a viewport already exists.
2913 // TODO: fix up any settings necessary for overlaying stored state onto
2914 // state recovered from another document. (may not be necessary).
2915 // we may need a binding from a viewport in memory to one recovered from
2917 // and then recover its containing af to allow the settings to be applied.
2918 // TODO: fix for vamsas demo
2920 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2922 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2923 if (seqsetobj != null)
2925 if (seqsetobj instanceof String)
2927 uniqueSeqSetId = (String) seqsetobj;
2929 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2935 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2941 * indicate that annotation colours are applied across all groups (pre
2942 * Jalview 2.8.1 behaviour)
2944 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2945 object.getVersion());
2947 AlignmentPanel ap = null;
2948 boolean isnewview = true;
2951 // Check to see if this alignment already has a view id == viewId
2952 jalview.gui.AlignmentPanel views[] = Desktop
2953 .getAlignmentPanels(uniqueSeqSetId);
2954 if (views != null && views.length > 0)
2956 for (int v = 0; v < views.length; v++)
2958 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2960 // recover the existing alignpanel, alignframe, viewport
2961 af = views[v].alignFrame;
2964 // TODO: could even skip resetting view settings if we don't want to
2965 // change the local settings from other jalview processes
2974 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
2975 uniqueSeqSetId, viewId, autoAlan);
2980 // /////////////////////////////////////
2981 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2985 for (int t = 0; t < jms.getTreeCount(); t++)
2988 Tree tree = jms.getTree(t);
2990 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2993 tp = af.ShowNewickTree(
2994 new jalview.io.NewickFile(tree.getNewick()),
2995 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2996 tree.getXpos(), tree.getYpos());
2997 if (tree.getId() != null)
2999 // perhaps bind the tree id to something ?
3004 // update local tree attributes ?
3005 // TODO: should check if tp has been manipulated by user - if so its
3006 // settings shouldn't be modified
3007 tp.setTitle(tree.getTitle());
3008 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3009 .getWidth(), tree.getHeight()));
3010 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3013 tp.treeCanvas.av = av; // af.viewport;
3014 tp.treeCanvas.ap = ap; // af.alignPanel;
3019 warn("There was a problem recovering stored Newick tree: \n"
3020 + tree.getNewick());
3024 tp.fitToWindow.setState(tree.getFitToWindow());
3025 tp.fitToWindow_actionPerformed(null);
3027 if (tree.getFontName() != null)
3029 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3030 .getFontStyle(), tree.getFontSize()));
3034 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3035 .getFontStyle(), tree.getFontSize()));
3038 tp.showPlaceholders(tree.getMarkUnlinked());
3039 tp.showBootstrap(tree.getShowBootstrap());
3040 tp.showDistances(tree.getShowDistances());
3042 tp.treeCanvas.threshold = tree.getThreshold();
3044 if (tree.getCurrentTree())
3046 af.viewport.setCurrentTree(tp.getTree());
3050 } catch (Exception ex)
3052 ex.printStackTrace();
3056 // //LOAD STRUCTURES
3057 if (loadTreesAndStructures)
3059 loadStructures(jprovider, jseqs, af, ap);
3061 // and finally return.
3066 * Load and link any saved structure viewers.
3073 protected void loadStructures(jarInputStreamProvider jprovider,
3074 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3076 // run through all PDB ids on the alignment, and collect mappings between
3077 // jmol view ids and all sequences referring to it
3078 Map<String, ViewerData> jmolViewIds = new HashMap<String, ViewerData>();
3080 for (int i = 0; i < jseqs.length; i++)
3082 if (jseqs[i].getPdbidsCount() > 0)
3084 Pdbids[] ids = jseqs[i].getPdbids();
3085 for (int p = 0; p < ids.length; p++)
3087 final int structureStateCount = ids[p].getStructureStateCount();
3088 for (int s = 0; s < structureStateCount; s++)
3090 // check to see if we haven't already created this structure view
3091 final StructureState structureState = ids[p].getStructureState(s);
3092 String sviewid = (structureState.getViewId() == null) ? null
3093 : structureState.getViewId()
3095 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3096 // Originally : ids[p].getFile()
3097 // : TODO: verify external PDB file recovery still works in normal
3098 // jalview project load
3099 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3100 jpdb.setId(ids[p].getId());
3102 int x = structureState.getXpos();
3103 int y = structureState.getYpos();
3104 int width = structureState.getWidth();
3105 int height = structureState.getHeight();
3107 // Probably don't need to do this anymore...
3108 // Desktop.desktop.getComponentAt(x, y);
3109 // TODO: NOW: check that this recovers the PDB file correctly.
3110 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3111 jalview.datamodel.SequenceI seq = seqRefIds
3112 .get(jseqs[i].getId() + "");
3113 if (sviewid == null)
3115 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3118 if (!jmolViewIds.containsKey(sviewid))
3120 jmolViewIds.put(sviewid, new ViewerData(x, y, width, height,
3121 false, false, true));
3122 // Legacy pre-2.7 conversion JAL-823 :
3123 // do not assume any view has to be linked for colour by
3127 // assemble String[] { pdb files }, String[] { id for each
3128 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3129 // seqs_file 2}, boolean[] {
3130 // linkAlignPanel,superposeWithAlignpanel}} from hash
3131 ViewerData jmoldat = jmolViewIds.get(sviewid);
3132 jmoldat.alignWithPanel |= structureState
3133 .hasAlignwithAlignPanel() ? structureState.getAlignwithAlignPanel() : false;
3134 // never colour by linked panel if not specified
3135 jmoldat.colourWithAlignPanel |= structureState
3136 .hasColourwithAlignPanel() ? structureState.getColourwithAlignPanel()
3138 // default for pre-2.7 projects is that Jmol colouring is enabled
3139 jmoldat.colourByViewer &= structureState
3140 .hasColourByJmol() ? structureState
3141 .getColourByJmol() : true;
3143 if (jmoldat.stateData.length() < structureState.getContent()
3147 jmoldat.stateData = structureState.getContent();
3150 if (ids[p].getFile() != null)
3152 File mapkey = new File(ids[p].getFile());
3153 Object[] seqstrmaps = jmoldat.fileData.get(mapkey);
3154 if (seqstrmaps == null)
3156 jmoldat.fileData.put(mapkey,
3157 seqstrmaps = new Object[]
3158 { pdbFile, ids[p].getId(), new Vector(),
3161 if (!((Vector) seqstrmaps[2]).contains(seq))
3163 ((Vector) seqstrmaps[2]).addElement(seq);
3164 // ((Vector)seqstrmaps[3]).addElement(n) :
3165 // in principle, chains
3166 // should be stored here : do we need to
3167 // TODO: store and recover seq/pdb_id :
3173 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");
3180 // Instantiate the associated structure views
3181 for (Entry<String, ViewerData> entry : jmolViewIds.entrySet())
3183 createOrLinkStructureViewer(entry, af, ap);
3193 protected void createOrLinkStructureViewer(
3194 Entry<String, ViewerData> viewerData, AlignFrame af,
3197 final ViewerData svattrib = viewerData.getValue();
3200 * Search for any viewer windows already open from other alignment views
3201 * that exactly match the stored structure state
3203 StructureViewerBase comp = findMatchingViewer(viewerData);
3207 linkStructureViewer(ap, comp, svattrib);
3212 * Pending an XML element for ViewerType, just check if stateData contains
3213 * "chimera" (part of the chimera session filename).
3215 if (svattrib.stateData.indexOf("chimera") > -1)
3217 createChimeraViewer(viewerData, af);
3221 createJmolViewer(viewerData, af);
3226 * Create a new Chimera viewer.
3231 protected void createChimeraViewer(Entry<String, ViewerData> viewerData,
3234 final ViewerData data = viewerData.getValue();
3235 String chimeraSession = data.stateData;
3236 List<String> pdbfilenames = new ArrayList<String>();
3237 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3238 List<String> pdbids = new ArrayList<String>();
3240 if (new File(chimeraSession).exists())
3242 Set<Entry<File, Object[]>> fileData = data.fileData.entrySet();
3243 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3244 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3245 for (Entry<File, Object[]> pdb : fileData)
3247 String filePath = (String) pdb.getValue()[0];
3248 String pdbId = (String) pdb.getValue()[1];
3249 final Vector seqList = (Vector) pdb.getValue()[2];
3250 PDBEntry pdbentry = new PDBEntry();
3251 pdbentry.setFile(filePath);
3252 pdbentry.setId(pdbId);
3254 SequenceI[] seqs = new SequenceI[seqList.size()];
3255 seqList.copyInto(seqs);
3259 // TODO can/should this be done via StructureViewer (like Jmol)?
3260 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs
3262 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs.size()][]);
3263 ChimeraViewFrame cvf = // new ChimeraViewFrame(data, af);
3264 new ChimeraViewFrame(af.alignPanel, pdbArray, seqsArray);
3268 Cache.log.error("Chimera session file " + chimeraSession
3274 * Create a new Jmol window. First parse the Jmol state to translate filenames
3275 * loaded into the view, and record the order in which files are shown in the
3276 * Jmol view, so we can add the sequence mappings in same order.
3281 protected void createJmolViewer(
3282 final Entry<String, ViewerData> viewerData, AlignFrame af)
3284 final ViewerData svattrib = viewerData.getValue();
3285 String state = svattrib.stateData;
3286 List<String> pdbfilenames = new ArrayList<String>();
3287 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3288 List<String> pdbids = new ArrayList<String>();
3289 StringBuilder newFileLoc = new StringBuilder(64);
3290 int cp = 0, ncp, ecp;
3291 Map<File, Object[]> oldFiles = svattrib.fileData;
3292 while ((ncp = state.indexOf("load ", cp)) > -1)
3296 // look for next filename in load statement
3297 newFileLoc.append(state.substring(cp,
3298 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3299 String oldfilenam = state.substring(ncp,
3300 ecp = state.indexOf("\"", ncp));
3301 // recover the new mapping data for this old filename
3302 // have to normalize filename - since Jmol and jalview do
3304 // translation differently.
3305 Object[] filedat = oldFiles.get(new File(oldfilenam));
3306 newFileLoc.append(Platform.escapeString((String) filedat[0]));
3307 pdbfilenames.add((String) filedat[0]);
3308 pdbids.add((String) filedat[1]);
3309 seqmaps.add(((Vector<SequenceI>) filedat[2])
3310 .toArray(new SequenceI[0]));
3311 newFileLoc.append("\"");
3312 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3313 // look for next file statement.
3314 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3318 // just append rest of state
3319 newFileLoc.append(state.substring(cp));
3323 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3324 newFileLoc = new StringBuilder(state);
3325 newFileLoc.append("; load append ");
3326 for (File id : oldFiles.keySet())
3328 // add this and any other pdb files that should be present in
3330 Object[] filedat = oldFiles.get(id);
3332 newFileLoc.append(((String) filedat[0]));
3333 pdbfilenames.add((String) filedat[0]);
3334 pdbids.add((String) filedat[1]);
3335 seqmaps.add(((Vector<SequenceI>) filedat[2])
3336 .toArray(new SequenceI[0]));
3337 newFileLoc.append(" \"");
3338 newFileLoc.append((String) filedat[0]);
3339 newFileLoc.append("\"");
3342 newFileLoc.append(";");
3345 if (newFileLoc.length() > 0)
3347 int histbug = newFileLoc.indexOf("history = ");
3349 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3350 String val = (diff == -1) ? null : newFileLoc
3351 .substring(histbug, diff);
3352 if (val != null && val.length() >= 4)
3354 if (val.contains("e"))
3356 if (val.trim().equals("true"))
3364 newFileLoc.replace(histbug, diff, val);
3368 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3370 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3371 final SequenceI[][] sq = seqmaps
3372 .toArray(new SequenceI[seqmaps.size()][]);
3373 final String fileloc = newFileLoc.toString();
3374 final String sviewid = viewerData.getKey();
3375 final AlignFrame alf = af;
3376 final java.awt.Rectangle rect = new java.awt.Rectangle(svattrib.x,
3377 svattrib.y, svattrib.width, svattrib.height);
3380 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3385 JalviewStructureDisplayI sview = null;
3388 // JAL-1333 note - we probably can't migrate Jmol views to UCSF
3390 sview = new StructureViewer(alf.alignPanel
3391 .getStructureSelectionManager()).createView(
3392 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3393 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3394 addNewStructureViewer(sview);
3395 } catch (OutOfMemoryError ex)
3397 new OOMWarning("restoring structure view for PDB id " + id,
3398 (OutOfMemoryError) ex.getCause());
3399 if (sview != null && sview.isVisible())
3401 sview.closeViewer();
3402 sview.setVisible(false);
3408 } catch (InvocationTargetException ex)
3410 warn("Unexpected error when opening Jmol view.", ex);
3412 } catch (InterruptedException e)
3414 // e.printStackTrace();
3420 * Returns any open frame that matches given structure viewer data. The match
3421 * is based on the unique viewId, or (for older project versions) the frame's
3427 protected StructureViewerBase findMatchingViewer(
3428 Entry<String, ViewerData> viewerData)
3430 final String sviewid = viewerData.getKey();
3431 final ViewerData svattrib = viewerData.getValue();
3432 StructureViewerBase comp = null;
3433 JInternalFrame[] frames = getAllFrames();
3434 for (JInternalFrame frame : frames)
3436 if (frame instanceof StructureViewerBase)
3439 * Post jalview 2.4 schema includes structure view id
3442 && ((StructureViewerBase) frame).getViewId().equals(
3445 comp = (AppJmol) frame;
3449 * Otherwise test for matching position and size of viewer frame
3451 else if (frame.getX() == svattrib.x && frame.getY() == svattrib.y
3452 && frame.getHeight() == svattrib.height
3453 && frame.getWidth() == svattrib.width)
3455 comp = (AppJmol) frame;
3464 * Link an AlignmentPanel to an existing structure viewer.
3469 * @param useinViewerSuperpos
3470 * @param usetoColourbyseq
3471 * @param viewerColouring
3473 protected void linkStructureViewer(AlignmentPanel ap,
3474 StructureViewerBase viewer, ViewerData svattrib)
3476 // NOTE: if the jalview project is part of a shared session then
3477 // view synchronization should/could be done here.
3479 final boolean useinViewerSuperpos = svattrib.alignWithPanel;
3480 final boolean usetoColourbyseq = svattrib.colourWithAlignPanel;
3481 final boolean viewerColouring = svattrib.colourByViewer;
3482 Map<File, Object[]> oldFiles = svattrib.fileData;
3485 * Add mapping for sequences in this view to an already open viewer
3487 final AAStructureBindingModel binding = viewer.getBinding();
3488 for (File id : oldFiles.keySet())
3490 // add this and any other pdb files that should be present in the
3492 Object[] filedat = oldFiles.get(id);
3493 String pdbFile = (String) filedat[0];
3494 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3495 .toArray(new SequenceI[0]);
3498 .setMapping(seq, null, pdbFile,
3499 jalview.io.AppletFormatAdapter.FILE);
3500 binding.addSequenceForStructFile(pdbFile, seq);
3502 // and add the AlignmentPanel's reference to the view panel
3503 viewer.addAlignmentPanel(ap);
3504 if (useinViewerSuperpos)
3506 viewer.useAlignmentPanelForSuperposition(ap);
3510 viewer.excludeAlignmentPanelForSuperposition(ap);
3512 if (usetoColourbyseq)
3514 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3518 viewer.excludeAlignmentPanelForColourbyseq(ap);
3523 * Get all frames within the Desktop.
3527 protected JInternalFrame[] getAllFrames()
3529 JInternalFrame[] frames = null;
3530 // TODO is this necessary - is it safe - risk of hanging?
3535 frames = Desktop.desktop.getAllFrames();
3536 } catch (ArrayIndexOutOfBoundsException e)
3538 // occasional No such child exceptions are thrown here...
3542 } catch (InterruptedException f)
3546 } while (frames == null);
3553 * - minimum version we are comparing against
3555 * - version of data being processsed.
3556 * @return true if version is development/null or evaluates to the same or
3557 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3559 private boolean isVersionStringLaterThan(String supported, String version)
3561 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3562 || version.equalsIgnoreCase("Test")
3563 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3565 System.err.println("Assuming project file with "
3566 + (version == null ? "null" : version)
3567 + " is compatible with Jalview version " + supported);
3572 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3574 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3576 // convert b to decimal to catch bugfix releases within a series
3577 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3578 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3581 if (Float.valueOf(curT) > Float.valueOf(fileT))
3583 // current version is newer than the version that wrote the file
3586 } catch (NumberFormatException nfe)
3589 .println("** WARNING: Version comparison failed for tokens ("
3593 + ")\n** Current: '"
3594 + supported + "' and Version: '" + version + "'");
3597 if (currentV.hasMoreElements())
3599 // fileV has no minor version but identical series to current
3606 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3608 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3610 if (newStructureViewers != null)
3612 sview.getBinding().setFinishedLoadingFromArchive(false);
3613 newStructureViewers.add(sview);
3617 protected void setLoadingFinishedForNewStructureViewers()
3619 if (newStructureViewers != null)
3621 for (JalviewStructureDisplayI sview : newStructureViewers)
3623 sview.getBinding().setFinishedLoadingFromArchive(true);
3625 newStructureViewers.clear();
3626 newStructureViewers = null;
3630 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3631 Alignment al, JalviewModelSequence jms, Viewport view,
3632 String uniqueSeqSetId, String viewId,
3633 ArrayList<JvAnnotRow> autoAlan)
3635 AlignFrame af = null;
3636 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3637 uniqueSeqSetId, viewId);
3639 af.setFileName(file, "Jalview");
3641 for (int i = 0; i < JSEQ.length; i++)
3643 af.viewport.setSequenceColour(af.viewport.getAlignment()
3644 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3647 af.viewport.gatherViewsHere = view.getGatheredViews();
3649 if (view.getSequenceSetId() != null)
3651 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3652 .get(uniqueSeqSetId);
3654 af.viewport.setSequenceSetId(uniqueSeqSetId);
3657 // propagate shared settings to this new view
3658 af.viewport.historyList = av.historyList;
3659 af.viewport.redoList = av.redoList;
3663 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3665 // TODO: check if this method can be called repeatedly without
3666 // side-effects if alignpanel already registered.
3667 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3669 // apply Hidden regions to view.
3670 if (hiddenSeqs != null)
3672 for (int s = 0; s < JSEQ.length; s++)
3674 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3676 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3679 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3681 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3684 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3687 for (int s = 0; s < hiddenSeqs.size(); s++)
3689 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3692 af.viewport.hideSequence(hseqs);
3695 // recover view properties and display parameters
3696 if (view.getViewName() != null)
3698 af.viewport.viewName = view.getViewName();
3699 af.setInitialTabVisible();
3701 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3704 af.viewport.setShowAnnotation(view.getShowAnnotation());
3705 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3707 af.viewport.setColourText(view.getShowColourText());
3709 af.viewport.setConservationSelected(view.getConservationSelected());
3710 af.viewport.setShowJVSuffix(view.getShowFullId());
3711 af.viewport.setRightAlignIds(view.getRightAlignIds());
3712 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3713 .getFontStyle(), view.getFontSize()));
3714 af.alignPanel.fontChanged();
3715 af.viewport.setRenderGaps(view.getRenderGaps());
3716 af.viewport.setWrapAlignment(view.getWrapAlignment());
3717 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3718 af.viewport.setShowAnnotation(view.getShowAnnotation());
3719 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3721 af.viewport.setShowBoxes(view.getShowBoxes());
3723 af.viewport.setShowText(view.getShowText());
3725 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3726 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3727 af.viewport.thresholdTextColour = view.getTextColThreshold();
3728 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3729 .isShowUnconserved() : false);
3730 af.viewport.setStartRes(view.getStartRes());
3731 af.viewport.setStartSeq(view.getStartSeq());
3733 ColourSchemeI cs = null;
3734 // apply colourschemes
3735 if (view.getBgColour() != null)
3737 if (view.getBgColour().startsWith("ucs"))
3739 cs = getUserColourScheme(jms, view.getBgColour());
3741 else if (view.getBgColour().startsWith("Annotation"))
3743 AnnotationColours viewAnnColour = view.getAnnotationColours();
3744 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3751 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3756 cs.setThreshold(view.getPidThreshold(), true);
3757 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3761 af.viewport.setGlobalColourScheme(cs);
3762 af.viewport.setColourAppliesToAllGroups(false);
3764 if (view.getConservationSelected() && cs != null)
3766 cs.setConservationInc(view.getConsThreshold());
3769 af.changeColour(cs);
3771 af.viewport.setColourAppliesToAllGroups(true);
3773 if (view.getShowSequenceFeatures())
3775 af.viewport.showSequenceFeatures = true;
3777 if (view.hasCentreColumnLabels())
3779 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3781 if (view.hasIgnoreGapsinConsensus())
3783 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3786 if (view.hasFollowHighlight())
3788 af.viewport.followHighlight = view.getFollowHighlight();
3790 if (view.hasFollowSelection())
3792 af.viewport.followSelection = view.getFollowSelection();
3794 if (view.hasShowConsensusHistogram())
3796 af.viewport.setShowConsensusHistogram(view
3797 .getShowConsensusHistogram());
3801 af.viewport.setShowConsensusHistogram(true);
3803 if (view.hasShowSequenceLogo())
3805 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3809 af.viewport.setShowSequenceLogo(false);
3811 if (view.hasNormaliseSequenceLogo())
3813 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3815 if (view.hasShowDbRefTooltip())
3817 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3819 if (view.hasShowNPfeatureTooltip())
3821 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3823 if (view.hasShowGroupConsensus())
3825 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3829 af.viewport.setShowGroupConsensus(false);
3831 if (view.hasShowGroupConservation())
3833 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3837 af.viewport.setShowGroupConservation(false);
3840 // recover featre settings
3841 if (jms.getFeatureSettings() != null)
3843 af.viewport.setFeaturesDisplayed(new Hashtable());
3844 String[] renderOrder = new String[jms.getFeatureSettings()
3845 .getSettingCount()];
3846 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3848 Setting setting = jms.getFeatureSettings().getSetting(fs);
3849 if (setting.hasMincolour())
3851 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3852 new java.awt.Color(setting.getMincolour()),
3853 new java.awt.Color(setting.getColour()),
3854 setting.getMin(), setting.getMax()) : new GraduatedColor(
3855 new java.awt.Color(setting.getMincolour()),
3856 new java.awt.Color(setting.getColour()), 0, 1);
3857 if (setting.hasThreshold())
3859 gc.setThresh(setting.getThreshold());
3860 gc.setThreshType(setting.getThreshstate());
3862 gc.setAutoScaled(true); // default
3863 if (setting.hasAutoScale())
3865 gc.setAutoScaled(setting.getAutoScale());
3867 if (setting.hasColourByLabel())
3869 gc.setColourByLabel(setting.getColourByLabel());
3871 // and put in the feature colour table.
3872 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3873 setting.getType(), gc);
3877 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3879 new java.awt.Color(setting.getColour()));
3881 renderOrder[fs] = setting.getType();
3882 if (setting.hasOrder())
3884 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3885 setting.getType(), setting.getOrder());
3889 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3891 fs / jms.getFeatureSettings().getSettingCount());
3893 if (setting.getDisplay())
3895 af.viewport.getFeaturesDisplayed().put(setting.getType(), new Integer(
3896 setting.getColour()));
3899 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3901 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3902 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3904 Group grp = jms.getFeatureSettings().getGroup(gs);
3905 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3909 if (view.getHiddenColumnsCount() > 0)
3911 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3913 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3914 .getHiddenColumns(c).getEnd() // +1
3918 if (view.getCalcIdParam() != null)
3920 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3922 if (calcIdParam != null)
3924 if (recoverCalcIdParam(calcIdParam, af.viewport))
3929 warn("Couldn't recover parameters for "
3930 + calcIdParam.getCalcId());
3935 af.setMenusFromViewport(af.viewport);
3936 // TODO: we don't need to do this if the viewport is aready visible.
3937 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3939 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3940 reorderAutoannotation(af, al, autoAlan);
3941 af.alignPanel.alignmentChanged();
3945 private ColourSchemeI constructAnnotationColour(
3946 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3947 JalviewModelSequence jms, boolean checkGroupAnnColour)
3949 boolean propagateAnnColour = false;
3950 ColourSchemeI cs = null;
3951 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3952 if (checkGroupAnnColour && al.getGroups() != null
3953 && al.getGroups().size() > 0)
3955 // pre 2.8.1 behaviour
3956 // check to see if we should transfer annotation colours
3957 propagateAnnColour = true;
3958 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3960 if (sg.cs instanceof AnnotationColourGradient)
3962 propagateAnnColour = false;
3966 // int find annotation
3967 if (annAlignment.getAlignmentAnnotation() != null)
3969 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3971 if (annAlignment.getAlignmentAnnotation()[i].label
3972 .equals(viewAnnColour.getAnnotation()))
3974 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3976 annAlignment.getAlignmentAnnotation()[i]
3977 .setThreshold(new jalview.datamodel.GraphLine(
3978 viewAnnColour.getThreshold(), "Threshold",
3979 java.awt.Color.black)
3984 if (viewAnnColour.getColourScheme().equals("None"))
3986 cs = new AnnotationColourGradient(
3987 annAlignment.getAlignmentAnnotation()[i],
3988 new java.awt.Color(viewAnnColour.getMinColour()),
3989 new java.awt.Color(viewAnnColour.getMaxColour()),
3990 viewAnnColour.getAboveThreshold());
3992 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3994 cs = new AnnotationColourGradient(
3995 annAlignment.getAlignmentAnnotation()[i],
3996 getUserColourScheme(jms,
3997 viewAnnColour.getColourScheme()),
3998 viewAnnColour.getAboveThreshold());
4002 cs = new AnnotationColourGradient(
4003 annAlignment.getAlignmentAnnotation()[i],
4004 ColourSchemeProperty.getColour(al,
4005 viewAnnColour.getColourScheme()),
4006 viewAnnColour.getAboveThreshold());
4008 if (viewAnnColour.hasPerSequence())
4010 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4013 if (viewAnnColour.hasPredefinedColours())
4015 ((AnnotationColourGradient) cs)
4016 .setPredefinedColours(viewAnnColour
4017 .isPredefinedColours());
4019 if (propagateAnnColour && al.getGroups() != null)
4021 // Also use these settings for all the groups
4022 for (int g = 0; g < al.getGroups().size(); g++)
4024 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4032 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4033 * new AnnotationColourGradient(
4034 * annAlignment.getAlignmentAnnotation()[i], new
4035 * java.awt.Color(viewAnnColour. getMinColour()), new
4036 * java.awt.Color(viewAnnColour. getMaxColour()),
4037 * viewAnnColour.getAboveThreshold()); } else
4040 sg.cs = new AnnotationColourGradient(
4041 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4042 viewAnnColour.getAboveThreshold());
4043 if (cs instanceof AnnotationColourGradient)
4045 if (viewAnnColour.hasPerSequence())
4047 ((AnnotationColourGradient) cs)
4048 .setSeqAssociated(viewAnnColour.isPerSequence());
4050 if (viewAnnColour.hasPredefinedColours())
4052 ((AnnotationColourGradient) cs)
4053 .setPredefinedColours(viewAnnColour
4054 .isPredefinedColours());
4070 private void reorderAutoannotation(AlignFrame af, Alignment al,
4071 ArrayList<JvAnnotRow> autoAlan)
4073 // copy over visualization settings for autocalculated annotation in the
4075 if (al.getAlignmentAnnotation() != null)
4078 * Kludge for magic autoannotation names (see JAL-811)
4080 String[] magicNames = new String[]
4081 { "Consensus", "Quality", "Conservation" };
4082 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4083 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4084 for (String nm : magicNames)
4086 visan.put(nm, nullAnnot);
4088 for (JvAnnotRow auan : autoAlan)
4090 visan.put(auan.template.label
4091 + (auan.template.getCalcId() == null ? "" : "\t"
4092 + auan.template.getCalcId()), auan);
4094 int hSize = al.getAlignmentAnnotation().length;
4095 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4096 // work through any autoCalculated annotation already on the view
4097 // removing it if it should be placed in a different location on the
4098 // annotation panel.
4099 List<String> remains = new ArrayList(visan.keySet());
4100 for (int h = 0; h < hSize; h++)
4102 jalview.datamodel.AlignmentAnnotation jalan = al
4103 .getAlignmentAnnotation()[h];
4104 if (jalan.autoCalculated)
4107 JvAnnotRow valan = visan.get(k = jalan.label);
4108 if (jalan.getCalcId() != null)
4110 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4115 // delete the auto calculated row from the alignment
4116 al.deleteAnnotation(jalan, false);
4120 if (valan != nullAnnot)
4122 if (jalan != valan.template)
4124 // newly created autoannotation row instance
4125 // so keep a reference to the visible annotation row
4126 // and copy over all relevant attributes
4127 if (valan.template.graphHeight >= 0)
4130 jalan.graphHeight = valan.template.graphHeight;
4132 jalan.visible = valan.template.visible;
4134 reorder.add(new JvAnnotRow(valan.order, jalan));
4139 // Add any (possibly stale) autocalculated rows that were not appended to
4140 // the view during construction
4141 for (String other : remains)
4143 JvAnnotRow othera = visan.get(other);
4144 if (othera != nullAnnot && othera.template.getCalcId() != null
4145 && othera.template.getCalcId().length() > 0)
4147 reorder.add(othera);
4150 // now put the automatic annotation in its correct place
4151 int s = 0, srt[] = new int[reorder.size()];
4152 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4153 for (JvAnnotRow jvar : reorder)
4156 srt[s++] = jvar.order;
4159 jalview.util.QuickSort.sort(srt, rws);
4160 // and re-insert the annotation at its correct position
4161 for (JvAnnotRow jvar : rws)
4163 al.addAnnotation(jvar.template, jvar.order);
4165 af.alignPanel.adjustAnnotationHeight();
4169 Hashtable skipList = null;
4172 * TODO remove this method
4175 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4176 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4177 * throw new Error("Implementation Error. No skipList defined for this
4178 * Jalview2XML instance."); } return (AlignFrame)
4179 * skipList.get(view.getSequenceSetId()); }
4183 * Check if the Jalview view contained in object should be skipped or not.
4186 * @return true if view's sequenceSetId is a key in skipList
4188 private boolean skipViewport(JalviewModel object)
4190 if (skipList == null)
4195 if (skipList.containsKey(id = object.getJalviewModelSequence()
4196 .getViewport()[0].getSequenceSetId()))
4198 if (Cache.log != null && Cache.log.isDebugEnabled())
4200 Cache.log.debug("Skipping seuqence set id " + id);
4207 public void addToSkipList(AlignFrame af)
4209 if (skipList == null)
4211 skipList = new Hashtable();
4213 skipList.put(af.getViewport().getSequenceSetId(), af);
4216 public void clearSkipList()
4218 if (skipList != null)
4225 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4226 boolean ignoreUnrefed)
4228 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4229 Vector dseqs = null;
4232 // create a list of new dataset sequences
4233 dseqs = new Vector();
4235 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4237 Sequence vamsasSeq = vamsasSet.getSequence(i);
4238 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4240 // create a new dataset
4243 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4244 dseqs.copyInto(dsseqs);
4245 ds = new jalview.datamodel.Alignment(dsseqs);
4246 debug("Created new dataset " + vamsasSet.getDatasetId()
4247 + " for alignment " + System.identityHashCode(al));
4248 addDatasetRef(vamsasSet.getDatasetId(), ds);
4250 // set the dataset for the newly imported alignment.
4251 if (al.getDataset() == null && !ignoreUnrefed)
4260 * sequence definition to create/merge dataset sequence for
4264 * vector to add new dataset sequence to
4266 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4267 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4269 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4271 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4272 .get(vamsasSeq.getId());
4273 jalview.datamodel.SequenceI dsq = null;
4274 if (sq != null && sq.getDatasetSequence() != null)
4276 dsq = sq.getDatasetSequence();
4278 if (sq == null && ignoreUnrefed)
4282 String sqid = vamsasSeq.getDsseqid();
4285 // need to create or add a new dataset sequence reference to this sequence
4288 dsq = seqRefIds.get(sqid);
4293 // make a new dataset sequence
4294 dsq = sq.createDatasetSequence();
4297 // make up a new dataset reference for this sequence
4298 sqid = seqHash(dsq);
4300 dsq.setVamsasId(uniqueSetSuffix + sqid);
4301 seqRefIds.put(sqid, dsq);
4306 dseqs.addElement(dsq);
4311 ds.addSequence(dsq);
4317 { // make this dataset sequence sq's dataset sequence
4318 sq.setDatasetSequence(dsq);
4319 // and update the current dataset alignment
4324 if (!dseqs.contains(dsq))
4331 if (ds.findIndex(dsq) < 0)
4333 ds.addSequence(dsq);
4340 // TODO: refactor this as a merge dataset sequence function
4341 // now check that sq (the dataset sequence) sequence really is the union of
4342 // all references to it
4343 // boolean pre = sq.getStart() < dsq.getStart();
4344 // boolean post = sq.getEnd() > dsq.getEnd();
4348 StringBuffer sb = new StringBuffer();
4349 String newres = jalview.analysis.AlignSeq.extractGaps(
4350 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4351 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4352 && newres.length() > dsq.getLength())
4354 // Update with the longer sequence.
4358 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4359 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4360 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4361 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4363 dsq.setSequence(newres);
4365 // TODO: merges will never happen if we 'know' we have the real dataset
4366 // sequence - this should be detected when id==dssid
4368 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4369 // + (pre ? "prepended" : "") + " "
4370 // + (post ? "appended" : ""));
4375 java.util.Hashtable datasetIds = null;
4377 java.util.IdentityHashMap dataset2Ids = null;
4379 private Alignment getDatasetFor(String datasetId)
4381 if (datasetIds == null)
4383 datasetIds = new Hashtable();
4386 if (datasetIds.containsKey(datasetId))
4388 return (Alignment) datasetIds.get(datasetId);
4393 private void addDatasetRef(String datasetId, Alignment dataset)
4395 if (datasetIds == null)
4397 datasetIds = new Hashtable();
4399 datasetIds.put(datasetId, dataset);
4403 * make a new dataset ID for this jalview dataset alignment
4408 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4410 if (dataset.getDataset() != null)
4412 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4414 String datasetId = makeHashCode(dataset, null);
4415 if (datasetId == null)
4417 // make a new datasetId and record it
4418 if (dataset2Ids == null)
4420 dataset2Ids = new IdentityHashMap();
4424 datasetId = (String) dataset2Ids.get(dataset);
4426 if (datasetId == null)
4428 datasetId = "ds" + dataset2Ids.size() + 1;
4429 dataset2Ids.put(dataset, datasetId);
4435 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4437 for (int d = 0; d < sequence.getDBRefCount(); d++)
4439 DBRef dr = sequence.getDBRef(d);
4440 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4441 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4442 .getVersion(), sequence.getDBRef(d).getAccessionId());
4443 if (dr.getMapping() != null)
4445 entry.setMap(addMapping(dr.getMapping()));
4447 datasetSequence.addDBRef(entry);
4451 private jalview.datamodel.Mapping addMapping(Mapping m)
4453 SequenceI dsto = null;
4454 // Mapping m = dr.getMapping();
4455 int fr[] = new int[m.getMapListFromCount() * 2];
4456 Enumeration f = m.enumerateMapListFrom();
4457 for (int _i = 0; f.hasMoreElements(); _i += 2)
4459 MapListFrom mf = (MapListFrom) f.nextElement();
4460 fr[_i] = mf.getStart();
4461 fr[_i + 1] = mf.getEnd();
4463 int fto[] = new int[m.getMapListToCount() * 2];
4464 f = m.enumerateMapListTo();
4465 for (int _i = 0; f.hasMoreElements(); _i += 2)
4467 MapListTo mf = (MapListTo) f.nextElement();
4468 fto[_i] = mf.getStart();
4469 fto[_i + 1] = mf.getEnd();
4471 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4472 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4473 if (m.getMappingChoice() != null)
4475 MappingChoice mc = m.getMappingChoice();
4476 if (mc.getDseqFor() != null)
4478 String dsfor = "" + mc.getDseqFor();
4479 if (seqRefIds.containsKey(dsfor))
4484 jmap.setTo(seqRefIds.get(dsfor));
4488 frefedSequence.add(new Object[]
4495 * local sequence definition
4497 Sequence ms = mc.getSequence();
4498 jalview.datamodel.Sequence djs = null;
4499 String sqid = ms.getDsseqid();
4500 if (sqid != null && sqid.length() > 0)
4503 * recover dataset sequence
4505 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4510 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4511 sqid = ((Object) ms).toString(); // make up a new hascode for
4512 // undefined dataset sequence hash
4513 // (unlikely to happen)
4519 * make a new dataset sequence and add it to refIds hash
4521 djs = new jalview.datamodel.Sequence(ms.getName(),
4523 djs.setStart(jmap.getMap().getToLowest());
4524 djs.setEnd(jmap.getMap().getToHighest());
4525 djs.setVamsasId(uniqueSetSuffix + sqid);
4527 seqRefIds.put(sqid, djs);
4530 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4539 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4540 boolean keepSeqRefs)
4543 jalview.schemabinding.version2.JalviewModel jm = saveState(ap, null,
4549 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4553 uniqueSetSuffix = "";
4554 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4559 if (this.frefedSequence == null)
4561 frefedSequence = new Vector();
4564 viewportsAdded = new Hashtable();
4566 AlignFrame af = loadFromObject(jm, null, false, null);
4567 af.alignPanels.clear();
4568 af.closeMenuItem_actionPerformed(true);
4571 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4572 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4573 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4574 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4575 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4578 return af.alignPanel;
4582 * flag indicating if hashtables should be cleared on finalization TODO this
4583 * flag may not be necessary
4585 private final boolean _cleartables = true;
4587 private Hashtable jvids2vobj;
4592 * @see java.lang.Object#finalize()
4595 protected void finalize() throws Throwable
4597 // really make sure we have no buried refs left.
4602 this.seqRefIds = null;
4603 this.seqsToIds = null;
4607 private void warn(String msg)
4612 private void warn(String msg, Exception e)
4614 if (Cache.log != null)
4618 Cache.log.warn(msg, e);
4622 Cache.log.warn(msg);
4627 System.err.println("Warning: " + msg);
4630 e.printStackTrace();
4635 private void debug(String string)
4637 debug(string, null);
4640 private void debug(String msg, Exception e)
4642 if (Cache.log != null)
4646 Cache.log.debug(msg, e);
4650 Cache.log.debug(msg);
4655 System.err.println("Warning: " + msg);
4658 e.printStackTrace();
4664 * set the object to ID mapping tables used to write/recover objects and XML
4665 * ID strings for the jalview project. If external tables are provided then
4666 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4667 * object goes out of scope. - also populates the datasetIds hashtable with
4668 * alignment objects containing dataset sequences
4671 * Map from ID strings to jalview datamodel
4673 * Map from jalview datamodel to ID strings
4677 public void setObjectMappingTables(Hashtable vobj2jv,
4678 IdentityHashMap jv2vobj)
4680 this.jv2vobj = jv2vobj;
4681 this.vobj2jv = vobj2jv;
4682 Iterator ds = jv2vobj.keySet().iterator();
4684 while (ds.hasNext())
4686 Object jvobj = ds.next();
4687 id = jv2vobj.get(jvobj).toString();
4688 if (jvobj instanceof jalview.datamodel.Alignment)
4690 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4692 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4695 else if (jvobj instanceof jalview.datamodel.Sequence)
4697 // register sequence object so the XML parser can recover it.
4698 if (seqRefIds == null)
4700 seqRefIds = new HashMap<String, SequenceI>();
4702 if (seqsToIds == null)
4704 seqsToIds = new IdentityHashMap<SequenceI, String>();
4706 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4707 seqsToIds.put((SequenceI) jvobj, id);
4709 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4711 if (annotationIds == null)
4713 annotationIds = new Hashtable();
4716 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4717 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4718 if (jvann.annotationId == null)
4720 jvann.annotationId = anid;
4722 if (!jvann.annotationId.equals(anid))
4724 // TODO verify that this is the correct behaviour
4725 this.warn("Overriding Annotation ID for " + anid
4726 + " from different id : " + jvann.annotationId);
4727 jvann.annotationId = anid;
4730 else if (jvobj instanceof String)
4732 if (jvids2vobj == null)
4734 jvids2vobj = new Hashtable();
4735 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4740 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4746 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4747 * objects created from the project archive. If string is null (default for
4748 * construction) then suffix will be set automatically.
4752 public void setUniqueSetSuffix(String string)
4754 uniqueSetSuffix = string;
4759 * uses skipList2 as the skipList for skipping views on sequence sets
4760 * associated with keys in the skipList
4764 public void setSkipList(Hashtable skipList2)
4766 skipList = skipList2;