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 svattrib = viewerData.getValue();
3235 ChimeraViewFrame cvf = new ChimeraViewFrame(svattrib, af);
3239 * Create a new Jmol window. First parse the Jmol state to translate filenames
3240 * loaded into the view, and record the order in which files are shown in the
3241 * Jmol view, so we can add the sequence mappings in same order.
3246 protected void createJmolViewer(
3247 final Entry<String, ViewerData> viewerData, AlignFrame af)
3249 final ViewerData svattrib = viewerData.getValue();
3250 String state = svattrib.stateData;
3251 List<String> pdbfilenames = new ArrayList<String>();
3252 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3253 List<String> pdbids = new ArrayList<String>();
3254 StringBuilder newFileLoc = new StringBuilder(64);
3255 int cp = 0, ncp, ecp;
3256 Map<File, Object[]> oldFiles = svattrib.fileData;
3257 while ((ncp = state.indexOf("load ", cp)) > -1)
3261 // look for next filename in load statement
3262 newFileLoc.append(state.substring(cp,
3263 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3264 String oldfilenam = state.substring(ncp,
3265 ecp = state.indexOf("\"", ncp));
3266 // recover the new mapping data for this old filename
3267 // have to normalize filename - since Jmol and jalview do
3269 // translation differently.
3270 Object[] filedat = oldFiles.get(new File(oldfilenam));
3271 newFileLoc.append(Platform.escapeString((String) filedat[0]));
3272 pdbfilenames.add((String) filedat[0]);
3273 pdbids.add((String) filedat[1]);
3274 seqmaps.add(((Vector<SequenceI>) filedat[2])
3275 .toArray(new SequenceI[0]));
3276 newFileLoc.append("\"");
3277 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3278 // look for next file statement.
3279 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3283 // just append rest of state
3284 newFileLoc.append(state.substring(cp));
3288 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3289 newFileLoc = new StringBuilder(state);
3290 newFileLoc.append("; load append ");
3291 for (File id : oldFiles.keySet())
3293 // add this and any other pdb files that should be present in
3295 Object[] filedat = oldFiles.get(id);
3297 newFileLoc.append(((String) filedat[0]));
3298 pdbfilenames.add((String) filedat[0]);
3299 pdbids.add((String) filedat[1]);
3300 seqmaps.add(((Vector<SequenceI>) filedat[2])
3301 .toArray(new SequenceI[0]));
3302 newFileLoc.append(" \"");
3303 newFileLoc.append((String) filedat[0]);
3304 newFileLoc.append("\"");
3307 newFileLoc.append(";");
3310 if (newFileLoc.length() > 0)
3312 int histbug = newFileLoc.indexOf("history = ");
3314 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3315 String val = (diff == -1) ? null : newFileLoc
3316 .substring(histbug, diff);
3317 if (val != null && val.length() >= 4)
3319 if (val.contains("e"))
3321 if (val.trim().equals("true"))
3329 newFileLoc.replace(histbug, diff, val);
3333 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3335 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3336 final SequenceI[][] sq = seqmaps
3337 .toArray(new SequenceI[seqmaps.size()][]);
3338 final String fileloc = newFileLoc.toString();
3339 final String sviewid = viewerData.getKey();
3340 final AlignFrame alf = af;
3341 final java.awt.Rectangle rect = new java.awt.Rectangle(svattrib.x,
3342 svattrib.y, svattrib.width, svattrib.height);
3345 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3350 JalviewStructureDisplayI sview = null;
3353 // JAL-1333 note - we probably can't migrate Jmol views to UCSF
3355 sview = new StructureViewer(alf.alignPanel
3356 .getStructureSelectionManager()).createView(
3357 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3358 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3359 addNewStructureViewer(sview);
3360 } catch (OutOfMemoryError ex)
3362 new OOMWarning("restoring structure view for PDB id " + id,
3363 (OutOfMemoryError) ex.getCause());
3364 if (sview != null && sview.isVisible())
3366 sview.closeViewer();
3367 sview.setVisible(false);
3373 } catch (InvocationTargetException ex)
3375 warn("Unexpected error when opening Jmol view.", ex);
3377 } catch (InterruptedException e)
3379 // e.printStackTrace();
3385 * Returns any open frame that matches given structure viewer data. The match
3386 * is based on the unique viewId, or (for older project versions) the frame's
3392 protected StructureViewerBase findMatchingViewer(
3393 Entry<String, ViewerData> viewerData)
3395 final String sviewid = viewerData.getKey();
3396 final ViewerData svattrib = viewerData.getValue();
3397 StructureViewerBase comp = null;
3398 JInternalFrame[] frames = getAllFrames();
3399 for (JInternalFrame frame : frames)
3401 if (frame instanceof StructureViewerBase)
3404 * Post jalview 2.4 schema includes structure view id
3407 && ((StructureViewerBase) frame).getViewId().equals(
3410 comp = (AppJmol) frame;
3414 * Otherwise test for matching position and size of viewer frame
3416 else if (frame.getX() == svattrib.x && frame.getY() == svattrib.y
3417 && frame.getHeight() == svattrib.height
3418 && frame.getWidth() == svattrib.width)
3420 comp = (AppJmol) frame;
3429 * Link an AlignmentPanel to an existing structure viewer.
3434 * @param useinViewerSuperpos
3435 * @param usetoColourbyseq
3436 * @param viewerColouring
3438 protected void linkStructureViewer(AlignmentPanel ap,
3439 StructureViewerBase viewer, ViewerData svattrib)
3441 // NOTE: if the jalview project is part of a shared session then
3442 // view synchronization should/could be done here.
3444 final boolean useinViewerSuperpos = svattrib.alignWithPanel;
3445 final boolean usetoColourbyseq = svattrib.colourWithAlignPanel;
3446 final boolean viewerColouring = svattrib.colourByViewer;
3447 Map<File, Object[]> oldFiles = svattrib.fileData;
3450 * Add mapping for sequences in this view to an already open viewer
3452 final AAStructureBindingModel binding = viewer.getBinding();
3453 for (File id : oldFiles.keySet())
3455 // add this and any other pdb files that should be present in the
3457 Object[] filedat = oldFiles.get(id);
3458 String pdbFile = (String) filedat[0];
3459 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3460 .toArray(new SequenceI[0]);
3463 .setMapping(seq, null, pdbFile,
3464 jalview.io.AppletFormatAdapter.FILE);
3465 binding.addSequenceForStructFile(pdbFile, seq);
3467 // and add the AlignmentPanel's reference to the view panel
3468 viewer.addAlignmentPanel(ap);
3469 if (useinViewerSuperpos)
3471 viewer.useAlignmentPanelForSuperposition(ap);
3475 viewer.excludeAlignmentPanelForSuperposition(ap);
3477 if (usetoColourbyseq)
3479 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3483 viewer.excludeAlignmentPanelForColourbyseq(ap);
3488 * Get all frames within the Desktop.
3492 protected JInternalFrame[] getAllFrames()
3494 JInternalFrame[] frames = null;
3495 // TODO is this necessary - is it safe - risk of hanging?
3500 frames = Desktop.desktop.getAllFrames();
3501 } catch (ArrayIndexOutOfBoundsException e)
3503 // occasional No such child exceptions are thrown here...
3507 } catch (InterruptedException f)
3511 } while (frames == null);
3518 * - minimum version we are comparing against
3520 * - version of data being processsed.
3521 * @return true if version is development/null or evaluates to the same or
3522 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3524 private boolean isVersionStringLaterThan(String supported, String version)
3526 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3527 || version.equalsIgnoreCase("Test")
3528 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3530 System.err.println("Assuming project file with "
3531 + (version == null ? "null" : version)
3532 + " is compatible with Jalview version " + supported);
3537 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3539 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3541 // convert b to decimal to catch bugfix releases within a series
3542 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3543 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3546 if (Float.valueOf(curT) > Float.valueOf(fileT))
3548 // current version is newer than the version that wrote the file
3551 } catch (NumberFormatException nfe)
3554 .println("** WARNING: Version comparison failed for tokens ("
3558 + ")\n** Current: '"
3559 + supported + "' and Version: '" + version + "'");
3562 if (currentV.hasMoreElements())
3564 // fileV has no minor version but identical series to current
3571 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3573 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3575 if (newStructureViewers != null)
3577 sview.getBinding().setFinishedLoadingFromArchive(false);
3578 newStructureViewers.add(sview);
3582 protected void setLoadingFinishedForNewStructureViewers()
3584 if (newStructureViewers != null)
3586 for (JalviewStructureDisplayI sview : newStructureViewers)
3588 sview.getBinding().setFinishedLoadingFromArchive(true);
3590 newStructureViewers.clear();
3591 newStructureViewers = null;
3595 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3596 Alignment al, JalviewModelSequence jms, Viewport view,
3597 String uniqueSeqSetId, String viewId,
3598 ArrayList<JvAnnotRow> autoAlan)
3600 AlignFrame af = null;
3601 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3602 uniqueSeqSetId, viewId);
3604 af.setFileName(file, "Jalview");
3606 for (int i = 0; i < JSEQ.length; i++)
3608 af.viewport.setSequenceColour(af.viewport.getAlignment()
3609 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3612 af.viewport.gatherViewsHere = view.getGatheredViews();
3614 if (view.getSequenceSetId() != null)
3616 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3617 .get(uniqueSeqSetId);
3619 af.viewport.setSequenceSetId(uniqueSeqSetId);
3622 // propagate shared settings to this new view
3623 af.viewport.historyList = av.historyList;
3624 af.viewport.redoList = av.redoList;
3628 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3630 // TODO: check if this method can be called repeatedly without
3631 // side-effects if alignpanel already registered.
3632 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3634 // apply Hidden regions to view.
3635 if (hiddenSeqs != null)
3637 for (int s = 0; s < JSEQ.length; s++)
3639 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3641 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3644 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3646 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3649 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3652 for (int s = 0; s < hiddenSeqs.size(); s++)
3654 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3657 af.viewport.hideSequence(hseqs);
3660 // recover view properties and display parameters
3661 if (view.getViewName() != null)
3663 af.viewport.viewName = view.getViewName();
3664 af.setInitialTabVisible();
3666 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3669 af.viewport.setShowAnnotation(view.getShowAnnotation());
3670 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3672 af.viewport.setColourText(view.getShowColourText());
3674 af.viewport.setConservationSelected(view.getConservationSelected());
3675 af.viewport.setShowJVSuffix(view.getShowFullId());
3676 af.viewport.setRightAlignIds(view.getRightAlignIds());
3677 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3678 .getFontStyle(), view.getFontSize()));
3679 af.alignPanel.fontChanged();
3680 af.viewport.setRenderGaps(view.getRenderGaps());
3681 af.viewport.setWrapAlignment(view.getWrapAlignment());
3682 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3683 af.viewport.setShowAnnotation(view.getShowAnnotation());
3684 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3686 af.viewport.setShowBoxes(view.getShowBoxes());
3688 af.viewport.setShowText(view.getShowText());
3690 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3691 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3692 af.viewport.thresholdTextColour = view.getTextColThreshold();
3693 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3694 .isShowUnconserved() : false);
3695 af.viewport.setStartRes(view.getStartRes());
3696 af.viewport.setStartSeq(view.getStartSeq());
3698 ColourSchemeI cs = null;
3699 // apply colourschemes
3700 if (view.getBgColour() != null)
3702 if (view.getBgColour().startsWith("ucs"))
3704 cs = getUserColourScheme(jms, view.getBgColour());
3706 else if (view.getBgColour().startsWith("Annotation"))
3708 AnnotationColours viewAnnColour = view.getAnnotationColours();
3709 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3716 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3721 cs.setThreshold(view.getPidThreshold(), true);
3722 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3726 af.viewport.setGlobalColourScheme(cs);
3727 af.viewport.setColourAppliesToAllGroups(false);
3729 if (view.getConservationSelected() && cs != null)
3731 cs.setConservationInc(view.getConsThreshold());
3734 af.changeColour(cs);
3736 af.viewport.setColourAppliesToAllGroups(true);
3738 if (view.getShowSequenceFeatures())
3740 af.viewport.showSequenceFeatures = true;
3742 if (view.hasCentreColumnLabels())
3744 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3746 if (view.hasIgnoreGapsinConsensus())
3748 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3751 if (view.hasFollowHighlight())
3753 af.viewport.followHighlight = view.getFollowHighlight();
3755 if (view.hasFollowSelection())
3757 af.viewport.followSelection = view.getFollowSelection();
3759 if (view.hasShowConsensusHistogram())
3761 af.viewport.setShowConsensusHistogram(view
3762 .getShowConsensusHistogram());
3766 af.viewport.setShowConsensusHistogram(true);
3768 if (view.hasShowSequenceLogo())
3770 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3774 af.viewport.setShowSequenceLogo(false);
3776 if (view.hasNormaliseSequenceLogo())
3778 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3780 if (view.hasShowDbRefTooltip())
3782 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3784 if (view.hasShowNPfeatureTooltip())
3786 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3788 if (view.hasShowGroupConsensus())
3790 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3794 af.viewport.setShowGroupConsensus(false);
3796 if (view.hasShowGroupConservation())
3798 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3802 af.viewport.setShowGroupConservation(false);
3805 // recover featre settings
3806 if (jms.getFeatureSettings() != null)
3808 af.viewport.setFeaturesDisplayed(new Hashtable());
3809 String[] renderOrder = new String[jms.getFeatureSettings()
3810 .getSettingCount()];
3811 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3813 Setting setting = jms.getFeatureSettings().getSetting(fs);
3814 if (setting.hasMincolour())
3816 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3817 new java.awt.Color(setting.getMincolour()),
3818 new java.awt.Color(setting.getColour()),
3819 setting.getMin(), setting.getMax()) : new GraduatedColor(
3820 new java.awt.Color(setting.getMincolour()),
3821 new java.awt.Color(setting.getColour()), 0, 1);
3822 if (setting.hasThreshold())
3824 gc.setThresh(setting.getThreshold());
3825 gc.setThreshType(setting.getThreshstate());
3827 gc.setAutoScaled(true); // default
3828 if (setting.hasAutoScale())
3830 gc.setAutoScaled(setting.getAutoScale());
3832 if (setting.hasColourByLabel())
3834 gc.setColourByLabel(setting.getColourByLabel());
3836 // and put in the feature colour table.
3837 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3838 setting.getType(), gc);
3842 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3844 new java.awt.Color(setting.getColour()));
3846 renderOrder[fs] = setting.getType();
3847 if (setting.hasOrder())
3849 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3850 setting.getType(), setting.getOrder());
3854 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3856 fs / jms.getFeatureSettings().getSettingCount());
3858 if (setting.getDisplay())
3860 af.viewport.getFeaturesDisplayed().put(setting.getType(), new Integer(
3861 setting.getColour()));
3864 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3866 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3867 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3869 Group grp = jms.getFeatureSettings().getGroup(gs);
3870 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3874 if (view.getHiddenColumnsCount() > 0)
3876 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3878 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3879 .getHiddenColumns(c).getEnd() // +1
3883 if (view.getCalcIdParam() != null)
3885 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3887 if (calcIdParam != null)
3889 if (recoverCalcIdParam(calcIdParam, af.viewport))
3894 warn("Couldn't recover parameters for "
3895 + calcIdParam.getCalcId());
3900 af.setMenusFromViewport(af.viewport);
3901 // TODO: we don't need to do this if the viewport is aready visible.
3902 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3904 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3905 reorderAutoannotation(af, al, autoAlan);
3906 af.alignPanel.alignmentChanged();
3910 private ColourSchemeI constructAnnotationColour(
3911 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3912 JalviewModelSequence jms, boolean checkGroupAnnColour)
3914 boolean propagateAnnColour = false;
3915 ColourSchemeI cs = null;
3916 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3917 if (checkGroupAnnColour && al.getGroups() != null
3918 && al.getGroups().size() > 0)
3920 // pre 2.8.1 behaviour
3921 // check to see if we should transfer annotation colours
3922 propagateAnnColour = true;
3923 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3925 if (sg.cs instanceof AnnotationColourGradient)
3927 propagateAnnColour = false;
3931 // int find annotation
3932 if (annAlignment.getAlignmentAnnotation() != null)
3934 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3936 if (annAlignment.getAlignmentAnnotation()[i].label
3937 .equals(viewAnnColour.getAnnotation()))
3939 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3941 annAlignment.getAlignmentAnnotation()[i]
3942 .setThreshold(new jalview.datamodel.GraphLine(
3943 viewAnnColour.getThreshold(), "Threshold",
3944 java.awt.Color.black)
3949 if (viewAnnColour.getColourScheme().equals("None"))
3951 cs = new AnnotationColourGradient(
3952 annAlignment.getAlignmentAnnotation()[i],
3953 new java.awt.Color(viewAnnColour.getMinColour()),
3954 new java.awt.Color(viewAnnColour.getMaxColour()),
3955 viewAnnColour.getAboveThreshold());
3957 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3959 cs = new AnnotationColourGradient(
3960 annAlignment.getAlignmentAnnotation()[i],
3961 getUserColourScheme(jms,
3962 viewAnnColour.getColourScheme()),
3963 viewAnnColour.getAboveThreshold());
3967 cs = new AnnotationColourGradient(
3968 annAlignment.getAlignmentAnnotation()[i],
3969 ColourSchemeProperty.getColour(al,
3970 viewAnnColour.getColourScheme()),
3971 viewAnnColour.getAboveThreshold());
3973 if (viewAnnColour.hasPerSequence())
3975 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3978 if (viewAnnColour.hasPredefinedColours())
3980 ((AnnotationColourGradient) cs)
3981 .setPredefinedColours(viewAnnColour
3982 .isPredefinedColours());
3984 if (propagateAnnColour && al.getGroups() != null)
3986 // Also use these settings for all the groups
3987 for (int g = 0; g < al.getGroups().size(); g++)
3989 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3997 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3998 * new AnnotationColourGradient(
3999 * annAlignment.getAlignmentAnnotation()[i], new
4000 * java.awt.Color(viewAnnColour. getMinColour()), new
4001 * java.awt.Color(viewAnnColour. getMaxColour()),
4002 * viewAnnColour.getAboveThreshold()); } else
4005 sg.cs = new AnnotationColourGradient(
4006 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4007 viewAnnColour.getAboveThreshold());
4008 if (cs instanceof AnnotationColourGradient)
4010 if (viewAnnColour.hasPerSequence())
4012 ((AnnotationColourGradient) cs)
4013 .setSeqAssociated(viewAnnColour.isPerSequence());
4015 if (viewAnnColour.hasPredefinedColours())
4017 ((AnnotationColourGradient) cs)
4018 .setPredefinedColours(viewAnnColour
4019 .isPredefinedColours());
4035 private void reorderAutoannotation(AlignFrame af, Alignment al,
4036 ArrayList<JvAnnotRow> autoAlan)
4038 // copy over visualization settings for autocalculated annotation in the
4040 if (al.getAlignmentAnnotation() != null)
4043 * Kludge for magic autoannotation names (see JAL-811)
4045 String[] magicNames = new String[]
4046 { "Consensus", "Quality", "Conservation" };
4047 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4048 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4049 for (String nm : magicNames)
4051 visan.put(nm, nullAnnot);
4053 for (JvAnnotRow auan : autoAlan)
4055 visan.put(auan.template.label
4056 + (auan.template.getCalcId() == null ? "" : "\t"
4057 + auan.template.getCalcId()), auan);
4059 int hSize = al.getAlignmentAnnotation().length;
4060 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4061 // work through any autoCalculated annotation already on the view
4062 // removing it if it should be placed in a different location on the
4063 // annotation panel.
4064 List<String> remains = new ArrayList(visan.keySet());
4065 for (int h = 0; h < hSize; h++)
4067 jalview.datamodel.AlignmentAnnotation jalan = al
4068 .getAlignmentAnnotation()[h];
4069 if (jalan.autoCalculated)
4072 JvAnnotRow valan = visan.get(k = jalan.label);
4073 if (jalan.getCalcId() != null)
4075 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4080 // delete the auto calculated row from the alignment
4081 al.deleteAnnotation(jalan, false);
4085 if (valan != nullAnnot)
4087 if (jalan != valan.template)
4089 // newly created autoannotation row instance
4090 // so keep a reference to the visible annotation row
4091 // and copy over all relevant attributes
4092 if (valan.template.graphHeight >= 0)
4095 jalan.graphHeight = valan.template.graphHeight;
4097 jalan.visible = valan.template.visible;
4099 reorder.add(new JvAnnotRow(valan.order, jalan));
4104 // Add any (possibly stale) autocalculated rows that were not appended to
4105 // the view during construction
4106 for (String other : remains)
4108 JvAnnotRow othera = visan.get(other);
4109 if (othera != nullAnnot && othera.template.getCalcId() != null
4110 && othera.template.getCalcId().length() > 0)
4112 reorder.add(othera);
4115 // now put the automatic annotation in its correct place
4116 int s = 0, srt[] = new int[reorder.size()];
4117 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4118 for (JvAnnotRow jvar : reorder)
4121 srt[s++] = jvar.order;
4124 jalview.util.QuickSort.sort(srt, rws);
4125 // and re-insert the annotation at its correct position
4126 for (JvAnnotRow jvar : rws)
4128 al.addAnnotation(jvar.template, jvar.order);
4130 af.alignPanel.adjustAnnotationHeight();
4134 Hashtable skipList = null;
4137 * TODO remove this method
4140 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4141 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4142 * throw new Error("Implementation Error. No skipList defined for this
4143 * Jalview2XML instance."); } return (AlignFrame)
4144 * skipList.get(view.getSequenceSetId()); }
4148 * Check if the Jalview view contained in object should be skipped or not.
4151 * @return true if view's sequenceSetId is a key in skipList
4153 private boolean skipViewport(JalviewModel object)
4155 if (skipList == null)
4160 if (skipList.containsKey(id = object.getJalviewModelSequence()
4161 .getViewport()[0].getSequenceSetId()))
4163 if (Cache.log != null && Cache.log.isDebugEnabled())
4165 Cache.log.debug("Skipping seuqence set id " + id);
4172 public void addToSkipList(AlignFrame af)
4174 if (skipList == null)
4176 skipList = new Hashtable();
4178 skipList.put(af.getViewport().getSequenceSetId(), af);
4181 public void clearSkipList()
4183 if (skipList != null)
4190 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4191 boolean ignoreUnrefed)
4193 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4194 Vector dseqs = null;
4197 // create a list of new dataset sequences
4198 dseqs = new Vector();
4200 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4202 Sequence vamsasSeq = vamsasSet.getSequence(i);
4203 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4205 // create a new dataset
4208 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4209 dseqs.copyInto(dsseqs);
4210 ds = new jalview.datamodel.Alignment(dsseqs);
4211 debug("Created new dataset " + vamsasSet.getDatasetId()
4212 + " for alignment " + System.identityHashCode(al));
4213 addDatasetRef(vamsasSet.getDatasetId(), ds);
4215 // set the dataset for the newly imported alignment.
4216 if (al.getDataset() == null && !ignoreUnrefed)
4225 * sequence definition to create/merge dataset sequence for
4229 * vector to add new dataset sequence to
4231 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4232 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4234 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4236 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4237 .get(vamsasSeq.getId());
4238 jalview.datamodel.SequenceI dsq = null;
4239 if (sq != null && sq.getDatasetSequence() != null)
4241 dsq = sq.getDatasetSequence();
4243 if (sq == null && ignoreUnrefed)
4247 String sqid = vamsasSeq.getDsseqid();
4250 // need to create or add a new dataset sequence reference to this sequence
4253 dsq = seqRefIds.get(sqid);
4258 // make a new dataset sequence
4259 dsq = sq.createDatasetSequence();
4262 // make up a new dataset reference for this sequence
4263 sqid = seqHash(dsq);
4265 dsq.setVamsasId(uniqueSetSuffix + sqid);
4266 seqRefIds.put(sqid, dsq);
4271 dseqs.addElement(dsq);
4276 ds.addSequence(dsq);
4282 { // make this dataset sequence sq's dataset sequence
4283 sq.setDatasetSequence(dsq);
4284 // and update the current dataset alignment
4289 if (!dseqs.contains(dsq))
4296 if (ds.findIndex(dsq) < 0)
4298 ds.addSequence(dsq);
4305 // TODO: refactor this as a merge dataset sequence function
4306 // now check that sq (the dataset sequence) sequence really is the union of
4307 // all references to it
4308 // boolean pre = sq.getStart() < dsq.getStart();
4309 // boolean post = sq.getEnd() > dsq.getEnd();
4313 StringBuffer sb = new StringBuffer();
4314 String newres = jalview.analysis.AlignSeq.extractGaps(
4315 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4316 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4317 && newres.length() > dsq.getLength())
4319 // Update with the longer sequence.
4323 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4324 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4325 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4326 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4328 dsq.setSequence(newres);
4330 // TODO: merges will never happen if we 'know' we have the real dataset
4331 // sequence - this should be detected when id==dssid
4333 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4334 // + (pre ? "prepended" : "") + " "
4335 // + (post ? "appended" : ""));
4340 java.util.Hashtable datasetIds = null;
4342 java.util.IdentityHashMap dataset2Ids = null;
4344 private Alignment getDatasetFor(String datasetId)
4346 if (datasetIds == null)
4348 datasetIds = new Hashtable();
4351 if (datasetIds.containsKey(datasetId))
4353 return (Alignment) datasetIds.get(datasetId);
4358 private void addDatasetRef(String datasetId, Alignment dataset)
4360 if (datasetIds == null)
4362 datasetIds = new Hashtable();
4364 datasetIds.put(datasetId, dataset);
4368 * make a new dataset ID for this jalview dataset alignment
4373 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4375 if (dataset.getDataset() != null)
4377 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4379 String datasetId = makeHashCode(dataset, null);
4380 if (datasetId == null)
4382 // make a new datasetId and record it
4383 if (dataset2Ids == null)
4385 dataset2Ids = new IdentityHashMap();
4389 datasetId = (String) dataset2Ids.get(dataset);
4391 if (datasetId == null)
4393 datasetId = "ds" + dataset2Ids.size() + 1;
4394 dataset2Ids.put(dataset, datasetId);
4400 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4402 for (int d = 0; d < sequence.getDBRefCount(); d++)
4404 DBRef dr = sequence.getDBRef(d);
4405 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4406 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4407 .getVersion(), sequence.getDBRef(d).getAccessionId());
4408 if (dr.getMapping() != null)
4410 entry.setMap(addMapping(dr.getMapping()));
4412 datasetSequence.addDBRef(entry);
4416 private jalview.datamodel.Mapping addMapping(Mapping m)
4418 SequenceI dsto = null;
4419 // Mapping m = dr.getMapping();
4420 int fr[] = new int[m.getMapListFromCount() * 2];
4421 Enumeration f = m.enumerateMapListFrom();
4422 for (int _i = 0; f.hasMoreElements(); _i += 2)
4424 MapListFrom mf = (MapListFrom) f.nextElement();
4425 fr[_i] = mf.getStart();
4426 fr[_i + 1] = mf.getEnd();
4428 int fto[] = new int[m.getMapListToCount() * 2];
4429 f = m.enumerateMapListTo();
4430 for (int _i = 0; f.hasMoreElements(); _i += 2)
4432 MapListTo mf = (MapListTo) f.nextElement();
4433 fto[_i] = mf.getStart();
4434 fto[_i + 1] = mf.getEnd();
4436 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4437 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4438 if (m.getMappingChoice() != null)
4440 MappingChoice mc = m.getMappingChoice();
4441 if (mc.getDseqFor() != null)
4443 String dsfor = "" + mc.getDseqFor();
4444 if (seqRefIds.containsKey(dsfor))
4449 jmap.setTo(seqRefIds.get(dsfor));
4453 frefedSequence.add(new Object[]
4460 * local sequence definition
4462 Sequence ms = mc.getSequence();
4463 jalview.datamodel.Sequence djs = null;
4464 String sqid = ms.getDsseqid();
4465 if (sqid != null && sqid.length() > 0)
4468 * recover dataset sequence
4470 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4475 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4476 sqid = ((Object) ms).toString(); // make up a new hascode for
4477 // undefined dataset sequence hash
4478 // (unlikely to happen)
4484 * make a new dataset sequence and add it to refIds hash
4486 djs = new jalview.datamodel.Sequence(ms.getName(),
4488 djs.setStart(jmap.getMap().getToLowest());
4489 djs.setEnd(jmap.getMap().getToHighest());
4490 djs.setVamsasId(uniqueSetSuffix + sqid);
4492 seqRefIds.put(sqid, djs);
4495 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4504 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4505 boolean keepSeqRefs)
4508 jalview.schemabinding.version2.JalviewModel jm = saveState(ap, null,
4514 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4518 uniqueSetSuffix = "";
4519 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4524 if (this.frefedSequence == null)
4526 frefedSequence = new Vector();
4529 viewportsAdded = new Hashtable();
4531 AlignFrame af = loadFromObject(jm, null, false, null);
4532 af.alignPanels.clear();
4533 af.closeMenuItem_actionPerformed(true);
4536 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4537 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4538 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4539 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4540 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4543 return af.alignPanel;
4547 * flag indicating if hashtables should be cleared on finalization TODO this
4548 * flag may not be necessary
4550 private final boolean _cleartables = true;
4552 private Hashtable jvids2vobj;
4557 * @see java.lang.Object#finalize()
4560 protected void finalize() throws Throwable
4562 // really make sure we have no buried refs left.
4567 this.seqRefIds = null;
4568 this.seqsToIds = null;
4572 private void warn(String msg)
4577 private void warn(String msg, Exception e)
4579 if (Cache.log != null)
4583 Cache.log.warn(msg, e);
4587 Cache.log.warn(msg);
4592 System.err.println("Warning: " + msg);
4595 e.printStackTrace();
4600 private void debug(String string)
4602 debug(string, null);
4605 private void debug(String msg, Exception e)
4607 if (Cache.log != null)
4611 Cache.log.debug(msg, e);
4615 Cache.log.debug(msg);
4620 System.err.println("Warning: " + msg);
4623 e.printStackTrace();
4629 * set the object to ID mapping tables used to write/recover objects and XML
4630 * ID strings for the jalview project. If external tables are provided then
4631 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4632 * object goes out of scope. - also populates the datasetIds hashtable with
4633 * alignment objects containing dataset sequences
4636 * Map from ID strings to jalview datamodel
4638 * Map from jalview datamodel to ID strings
4642 public void setObjectMappingTables(Hashtable vobj2jv,
4643 IdentityHashMap jv2vobj)
4645 this.jv2vobj = jv2vobj;
4646 this.vobj2jv = vobj2jv;
4647 Iterator ds = jv2vobj.keySet().iterator();
4649 while (ds.hasNext())
4651 Object jvobj = ds.next();
4652 id = jv2vobj.get(jvobj).toString();
4653 if (jvobj instanceof jalview.datamodel.Alignment)
4655 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4657 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4660 else if (jvobj instanceof jalview.datamodel.Sequence)
4662 // register sequence object so the XML parser can recover it.
4663 if (seqRefIds == null)
4665 seqRefIds = new HashMap<String, SequenceI>();
4667 if (seqsToIds == null)
4669 seqsToIds = new IdentityHashMap<SequenceI, String>();
4671 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4672 seqsToIds.put((SequenceI) jvobj, id);
4674 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4676 if (annotationIds == null)
4678 annotationIds = new Hashtable();
4681 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4682 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4683 if (jvann.annotationId == null)
4685 jvann.annotationId = anid;
4687 if (!jvann.annotationId.equals(anid))
4689 // TODO verify that this is the correct behaviour
4690 this.warn("Overriding Annotation ID for " + anid
4691 + " from different id : " + jvann.annotationId);
4692 jvann.annotationId = anid;
4695 else if (jvobj instanceof String)
4697 if (jvids2vobj == null)
4699 jvids2vobj = new Hashtable();
4700 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4705 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4711 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4712 * objects created from the project archive. If string is null (default for
4713 * construction) then suffix will be set automatically.
4717 public void setUniqueSetSuffix(String string)
4719 uniqueSetSuffix = string;
4724 * uses skipList2 as the skipList for skipping views on sequence sets
4725 * associated with keys in the skipList
4729 public void setSkipList(Hashtable skipList2)
4731 skipList = skipList2;