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.AlignedCodonFrame;
26 import jalview.datamodel.Alignment;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.SequenceI;
30 import jalview.schemabinding.version2.AlcodMap;
31 import jalview.schemabinding.version2.AlcodonFrame;
32 import jalview.schemabinding.version2.Annotation;
33 import jalview.schemabinding.version2.AnnotationColours;
34 import jalview.schemabinding.version2.AnnotationElement;
35 import jalview.schemabinding.version2.CalcIdParam;
36 import jalview.schemabinding.version2.DBRef;
37 import jalview.schemabinding.version2.Features;
38 import jalview.schemabinding.version2.Group;
39 import jalview.schemabinding.version2.HiddenColumns;
40 import jalview.schemabinding.version2.JGroup;
41 import jalview.schemabinding.version2.JSeq;
42 import jalview.schemabinding.version2.JalviewModel;
43 import jalview.schemabinding.version2.JalviewModelSequence;
44 import jalview.schemabinding.version2.MapListFrom;
45 import jalview.schemabinding.version2.MapListTo;
46 import jalview.schemabinding.version2.Mapping;
47 import jalview.schemabinding.version2.MappingChoice;
48 import jalview.schemabinding.version2.OtherData;
49 import jalview.schemabinding.version2.PdbentryItem;
50 import jalview.schemabinding.version2.Pdbids;
51 import jalview.schemabinding.version2.Property;
52 import jalview.schemabinding.version2.Sequence;
53 import jalview.schemabinding.version2.SequenceSet;
54 import jalview.schemabinding.version2.SequenceSetProperties;
55 import jalview.schemabinding.version2.Setting;
56 import jalview.schemabinding.version2.StructureState;
57 import jalview.schemabinding.version2.ThresholdLine;
58 import jalview.schemabinding.version2.Tree;
59 import jalview.schemabinding.version2.UserColours;
60 import jalview.schemabinding.version2.Viewport;
61 import jalview.schemes.AnnotationColourGradient;
62 import jalview.schemes.ColourSchemeI;
63 import jalview.schemes.ColourSchemeProperty;
64 import jalview.schemes.GraduatedColor;
65 import jalview.schemes.ResidueColourScheme;
66 import jalview.schemes.ResidueProperties;
67 import jalview.structure.StructureSelectionManager;
68 import jalview.util.MessageManager;
69 import jalview.util.Platform;
70 import jalview.util.jarInputStreamProvider;
71 import jalview.viewmodel.AlignmentViewport;
72 import jalview.ws.jws2.Jws2Discoverer;
73 import jalview.ws.jws2.dm.AAConSettings;
74 import jalview.ws.jws2.jabaws2.Jws2Instance;
75 import jalview.ws.params.ArgumentI;
76 import jalview.ws.params.AutoCalcSetting;
77 import jalview.ws.params.WsParamSetI;
79 import java.awt.Rectangle;
80 import java.io.BufferedReader;
81 import java.io.DataInputStream;
82 import java.io.DataOutputStream;
84 import java.io.FileInputStream;
85 import java.io.FileOutputStream;
86 import java.io.IOException;
87 import java.io.InputStreamReader;
88 import java.io.OutputStreamWriter;
89 import java.io.PrintWriter;
90 import java.lang.reflect.InvocationTargetException;
91 import java.net.MalformedURLException;
93 import java.util.ArrayList;
94 import java.util.Enumeration;
95 import java.util.HashSet;
96 import java.util.Hashtable;
97 import java.util.IdentityHashMap;
98 import java.util.Iterator;
99 import java.util.List;
100 import java.util.Map.Entry;
101 import java.util.Set;
102 import java.util.StringTokenizer;
103 import java.util.Vector;
104 import java.util.jar.JarEntry;
105 import java.util.jar.JarInputStream;
106 import java.util.jar.JarOutputStream;
108 import javax.swing.JInternalFrame;
109 import javax.swing.JOptionPane;
110 import javax.swing.SwingUtilities;
112 import org.exolab.castor.xml.Unmarshaller;
115 * Write out the current jalview desktop state as a Jalview XML stream.
117 * Note: the vamsas objects referred to here are primitive versions of the
118 * VAMSAS project schema elements - they are not the same and most likely never
122 * @version $Revision: 1.134 $
124 public class Jalview2XML
127 * create/return unique hash string for sq
130 * @return new or existing unique string for sq
132 String seqHash(SequenceI sq)
134 if (seqsToIds == null)
138 if (seqsToIds.containsKey(sq))
140 return (String) seqsToIds.get(sq);
144 // create sequential key
145 String key = "sq" + (seqsToIds.size() + 1);
146 key = makeHashCode(sq, key); // check we don't have an external reference
148 seqsToIds.put(sq, key);
157 if (seqRefIds != null)
161 if (seqsToIds != null)
171 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
172 // seqRefIds = new Hashtable();
173 // seqsToIds = new IdentityHashMap();
179 if (seqsToIds == null)
181 seqsToIds = new IdentityHashMap();
183 if (seqRefIds == null)
185 seqRefIds = new Hashtable();
190 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
191 * of sequence objects are created.
193 java.util.IdentityHashMap seqsToIds = null;
196 * jalview XML Sequence ID to jalview sequence object reference (both dataset
197 * and alignment sequences. Populated as XML reps of sequence objects are
200 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
202 Vector frefedSequence = null;
204 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
210 public Jalview2XML(boolean raiseGUI)
212 this.raiseGUI = raiseGUI;
215 public void resolveFrefedSequences()
217 if (frefedSequence.size() > 0)
219 int r = 0, rSize = frefedSequence.size();
222 Object[] ref = (Object[]) frefedSequence.elementAt(r);
225 String sref = (String) ref[0];
226 if (seqRefIds.containsKey(sref))
228 if (ref[1] instanceof jalview.datamodel.Mapping)
230 SequenceI seq = (SequenceI) seqRefIds.get(sref);
231 while (seq.getDatasetSequence() != null)
233 seq = seq.getDatasetSequence();
235 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
239 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
241 SequenceI seq = (SequenceI) seqRefIds.get(sref);
242 while (seq.getDatasetSequence() != null)
244 seq = seq.getDatasetSequence();
247 && ref[2] instanceof jalview.datamodel.Mapping)
249 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
250 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
251 seq, mp.getTo(), mp.getMap());
256 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
257 + ref[2].getClass() + " type objects.");
263 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
264 + ref[1].getClass() + " type objects.");
267 frefedSequence.remove(r);
273 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
275 + " with objecttype "
276 + ref[1].getClass());
283 frefedSequence.remove(r);
291 * This maintains a list of viewports, the key being the seqSetId. Important
292 * to set historyItem and redoList for multiple views
294 Hashtable viewportsAdded;
296 Hashtable annotationIds = new Hashtable();
298 String uniqueSetSuffix = "";
301 * List of pdbfiles added to Jar
303 Vector pdbfiles = null;
305 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
306 public void SaveState(File statefile)
310 FileOutputStream fos = new FileOutputStream(statefile);
311 JarOutputStream jout = new JarOutputStream(fos);
314 } catch (Exception e)
316 // TODO: inform user of the problem - they need to know if their data was
318 if (errorMessage == null)
320 errorMessage = "Couldn't write Jalview Archive to output file '"
321 + statefile + "' - See console error log for details";
325 errorMessage += "(output file was '" + statefile + "')";
333 * Writes a jalview project archive to the given Jar output stream.
337 public void SaveState(JarOutputStream jout)
339 AlignFrame[] frames = Desktop.getAlignFrames(); // Desktop.desktop.getAllFrames();
346 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
351 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
352 // //////////////////////////////////////////////////
353 // NOTE ALSO new PrintWriter must be used for each new JarEntry
354 PrintWriter out = null;
356 List<String> shortNames = new ArrayList<String>();
359 for (int i = frames.length - 1; i > -1; i--)
361 AlignFrame af = frames[i];
365 .containsKey(af.getViewport().getSequenceSetId()))
370 String shortName = af.getTitle();
372 if (shortName.indexOf(File.separatorChar) > -1)
374 shortName = shortName.substring(shortName
375 .lastIndexOf(File.separatorChar) + 1);
380 while (shortNames.contains(shortName))
382 if (shortName.endsWith("_" + (count - 1)))
384 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
387 shortName = shortName.concat("_" + count);
391 shortNames.add(shortName);
393 if (!shortName.endsWith(".xml"))
395 shortName = shortName + ".xml";
398 int apSize = af.alignPanels.size();
400 for (int ap = 0; ap < apSize; ap++)
402 AlignmentPanel apanel = af.alignPanels.get(ap);
403 String fileName = apSize == 1 ? shortName : ap + shortName;
404 if (!fileName.endsWith(".xml"))
406 fileName = fileName + ".xml";
409 SaveState(apanel, fileName, jout);
411 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
413 if (!dsses.containsKey(dssid))
415 dsses.put(dssid, af);
420 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
426 } catch (Exception foo)
431 } catch (Exception ex)
433 // TODO: inform user of the problem - they need to know if their data was
435 if (errorMessage == null)
437 errorMessage = "Couldn't write Jalview Archive - see error output for details";
439 ex.printStackTrace();
443 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
444 public boolean SaveAlignment(AlignFrame af, String jarFile,
449 int ap, apSize = af.alignPanels.size();
450 FileOutputStream fos = new FileOutputStream(jarFile);
451 JarOutputStream jout = new JarOutputStream(fos);
452 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
453 for (ap = 0; ap < apSize; ap++)
455 AlignmentPanel apanel = af.alignPanels
457 String jfileName = apSize == 1 ? fileName : fileName + ap;
458 if (!jfileName.endsWith(".xml"))
460 jfileName = jfileName + ".xml";
462 SaveState(apanel, jfileName, jout);
463 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
465 if (!dsses.containsKey(dssid))
467 dsses.put(dssid, af);
470 writeDatasetFor(dsses, fileName, jout);
474 } catch (Exception foo)
480 } catch (Exception ex)
482 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
483 ex.printStackTrace();
488 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
489 String fileName, JarOutputStream jout)
492 for (String dssids : dsses.keySet())
494 AlignFrame _af = dsses.get(dssids);
495 String jfileName = fileName + " Dataset for " + _af.getTitle();
496 if (!jfileName.endsWith(".xml"))
498 jfileName = jfileName + ".xml";
500 SaveState(_af.alignPanel, jfileName, true, jout);
505 * create a JalviewModel from an algnment view and marshall it to a
509 * panel to create jalview model for
511 * name of alignment panel written to output stream
517 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
518 JarOutputStream jout)
520 return SaveState(ap, fileName, false, jout);
524 * create a JalviewModel from an algnment view and marshall it to a
528 * panel to create jalview model for
530 * name of alignment panel written to output stream
532 * when true, only write the dataset for the alignment, not the data
533 * associated with the view.
539 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
540 boolean storeDS, JarOutputStream jout)
543 Vector jmolViewIds = new Vector(); //
544 Vector userColours = new Vector();
546 AlignViewport av = ap.av;
548 JalviewModel object = new JalviewModel();
549 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
551 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
552 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
553 "Development Build"));
555 jalview.datamodel.AlignmentI jal = av.getAlignment();
557 if (av.hasHiddenRows())
559 jal = jal.getHiddenSequences().getFullAlignment();
562 SequenceSet vamsasSet = new SequenceSet();
564 JalviewModelSequence jms = new JalviewModelSequence();
566 vamsasSet.setGapChar(jal.getGapCharacter() + "");
568 if (jal.getDataset() != null)
570 // dataset id is the dataset's hashcode
571 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
574 // switch jal and the dataset
575 jal = jal.getDataset();
578 if (jal.getProperties() != null)
580 Enumeration en = jal.getProperties().keys();
581 while (en.hasMoreElements())
583 String key = en.nextElement().toString();
584 SequenceSetProperties ssp = new SequenceSetProperties();
586 ssp.setValue(jal.getProperties().get(key).toString());
587 vamsasSet.addSequenceSetProperties(ssp);
592 Set<String> calcIdSet = new HashSet<String>();
596 jalview.datamodel.SequenceI jds, jdatasq;
597 for (int i = 0; i < jal.getHeight(); i++)
599 jds = jal.getSequenceAt(i);
600 jdatasq = jds.getDatasetSequence() == null ? jds : jds
601 .getDatasetSequence();
604 if (seqRefIds.get(id) != null)
606 // This happens for two reasons: 1. multiple views are being serialised.
607 // 2. the hashCode has collided with another sequence's code. This DOES
608 // HAPPEN! (PF00072.15.stk does this)
609 // JBPNote: Uncomment to debug writing out of files that do not read
610 // back in due to ArrayOutOfBoundExceptions.
611 // System.err.println("vamsasSeq backref: "+id+"");
612 // System.err.println(jds.getName()+"
613 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
614 // System.err.println("Hashcode: "+seqHash(jds));
615 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
616 // System.err.println(rsq.getName()+"
617 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
618 // System.err.println("Hashcode: "+seqHash(rsq));
622 vamsasSeq = createVamsasSequence(id, jds);
623 vamsasSet.addSequence(vamsasSeq);
624 seqRefIds.put(id, jds);
628 jseq.setStart(jds.getStart());
629 jseq.setEnd(jds.getEnd());
630 jseq.setColour(av.getSequenceColour(jds).getRGB());
632 jseq.setId(id); // jseq id should be a string not a number
635 // Store any sequences this sequence represents
636 if (av.hasHiddenRows())
638 jseq.setHidden(av.getAlignment().getHiddenSequences()
641 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
643 jalview.datamodel.SequenceI[] reps = av
644 .getRepresentedSequences(jal.getSequenceAt(i))
645 .getSequencesInOrder(jal);
647 for (int h = 0; h < reps.length; h++)
649 if (reps[h] != jal.getSequenceAt(i))
651 jseq.addHiddenSequences(jal.findIndex(reps[h]));
658 if (jdatasq.getSequenceFeatures() != null)
660 jalview.datamodel.SequenceFeature[] sf = jdatasq
661 .getSequenceFeatures();
663 while (index < sf.length)
665 Features features = new Features();
667 features.setBegin(sf[index].getBegin());
668 features.setEnd(sf[index].getEnd());
669 features.setDescription(sf[index].getDescription());
670 features.setType(sf[index].getType());
671 features.setFeatureGroup(sf[index].getFeatureGroup());
672 features.setScore(sf[index].getScore());
673 if (sf[index].links != null)
675 for (int l = 0; l < sf[index].links.size(); l++)
677 OtherData keyValue = new OtherData();
678 keyValue.setKey("LINK_" + l);
679 keyValue.setValue(sf[index].links.elementAt(l).toString());
680 features.addOtherData(keyValue);
683 if (sf[index].otherDetails != null)
686 Enumeration keys = sf[index].otherDetails.keys();
687 while (keys.hasMoreElements())
689 key = keys.nextElement().toString();
690 OtherData keyValue = new OtherData();
691 keyValue.setKey(key);
692 keyValue.setValue(sf[index].otherDetails.get(key).toString());
693 features.addOtherData(keyValue);
697 jseq.addFeatures(features);
702 if (jdatasq.getPDBId() != null)
704 Enumeration en = jdatasq.getPDBId().elements();
705 while (en.hasMoreElements())
707 Pdbids pdb = new Pdbids();
708 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
711 pdb.setId(entry.getId());
712 pdb.setType(entry.getType());
714 // store any JMol views associated with this seqeunce
715 // this section copes with duplicate entries in the project, so a
716 // dataset only view *should* be coped with sensibly
718 // This must have been loaded, is it still visible?
719 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
720 String matchedFile = null;
721 for (int f = frames.length - 1; f > -1; f--)
723 if (frames[f] instanceof AppJmol)
725 jmol = (AppJmol) frames[f];
726 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
728 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
729 && !(entry.getId().length() > 4 && entry
733 jmol.jmb.pdbentry[peid].getId()
738 if (matchedFile == null)
740 matchedFile = jmol.jmb.pdbentry[peid].getFile();
742 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
746 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
747 + jmol.jmb.pdbentry[peid].getFile());
751 // can get at it if the ID
752 // match is ambiguous (e.g.
754 String statestring = jmol.jmb.viewer.getStateInfo();
756 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
758 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
759 if (jds == jmol.jmb.sequence[peid][smap])
761 StructureState state = new StructureState();
762 state.setVisible(true);
763 state.setXpos(jmol.getX());
764 state.setYpos(jmol.getY());
765 state.setWidth(jmol.getWidth());
766 state.setHeight(jmol.getHeight());
767 state.setViewId(jmol.getViewId());
768 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
769 state.setColourwithAlignPanel(jmol
770 .isUsedforcolourby(ap));
771 state.setColourByJmol(jmol.isColouredByJmol());
772 if (!jmolViewIds.contains(state.getViewId()))
774 // Make sure we only store a Jmol state once in each XML
776 jmolViewIds.addElement(state.getViewId());
777 state.setContent(statestring.replaceAll("\n", ""));
781 state.setContent("# duplicate state");
783 pdb.addStructureState(state);
791 if (matchedFile != null || entry.getFile() != null)
793 if (entry.getFile() != null)
796 matchedFile = entry.getFile();
798 pdb.setFile(matchedFile); // entry.getFile());
799 if (pdbfiles == null)
801 pdbfiles = new Vector();
804 if (!pdbfiles.contains(entry.getId()))
806 pdbfiles.addElement(entry.getId());
809 File file = new File(matchedFile);
810 if (file.exists() && jout != null)
812 byte[] data = new byte[(int) file.length()];
813 jout.putNextEntry(new JarEntry(entry.getId()));
814 DataInputStream dis = new DataInputStream(
815 new FileInputStream(file));
818 DataOutputStream dout = new DataOutputStream(jout);
819 dout.write(data, 0, data.length);
823 } catch (Exception ex)
825 ex.printStackTrace();
831 if (entry.getProperty() != null)
833 PdbentryItem item = new PdbentryItem();
834 Hashtable properties = entry.getProperty();
835 Enumeration en2 = properties.keys();
836 while (en2.hasMoreElements())
838 Property prop = new Property();
839 String key = en2.nextElement().toString();
841 prop.setValue(properties.get(key).toString());
842 item.addProperty(prop);
844 pdb.addPdbentryItem(item);
854 if (!storeDS && av.hasHiddenRows())
856 jal = av.getAlignment();
859 Set<AlignedCodonFrame> jac = jal.getCodonFrames();
862 for (AlignedCodonFrame acf : jac)
864 AlcodonFrame alc = new AlcodonFrame();
865 vamsasSet.addAlcodonFrame(alc);
866 if (acf.getProtMappings() != null
867 && acf.getProtMappings().length > 0)
869 SequenceI[] dnas = acf.getdnaSeqs();
870 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
871 for (int m = 0; m < pmaps.length; m++)
873 AlcodMap alcmap = new AlcodMap();
874 alcmap.setDnasq(seqHash(dnas[m]));
875 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
877 alc.addAlcodMap(alcmap);
884 // /////////////////////////////////
885 if (!storeDS && av.currentTree != null)
887 // FIND ANY ASSOCIATED TREES
888 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
889 if (Desktop.desktop != null)
891 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
893 for (int t = 0; t < frames.length; t++)
895 if (frames[t] instanceof TreePanel)
897 TreePanel tp = (TreePanel) frames[t];
899 if (tp.treeCanvas.av.getAlignment() == jal)
901 Tree tree = new Tree();
902 tree.setTitle(tp.getTitle());
903 tree.setCurrentTree((av.currentTree == tp.getTree()));
904 tree.setNewick(tp.getTree().toString());
905 tree.setThreshold(tp.treeCanvas.threshold);
907 tree.setFitToWindow(tp.fitToWindow.getState());
908 tree.setFontName(tp.getTreeFont().getName());
909 tree.setFontSize(tp.getTreeFont().getSize());
910 tree.setFontStyle(tp.getTreeFont().getStyle());
911 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
913 tree.setShowBootstrap(tp.bootstrapMenu.getState());
914 tree.setShowDistances(tp.distanceMenu.getState());
916 tree.setHeight(tp.getHeight());
917 tree.setWidth(tp.getWidth());
918 tree.setXpos(tp.getX());
919 tree.setYpos(tp.getY());
920 tree.setId(makeHashCode(tp, null));
929 * store forward refs from an annotationRow to any groups
931 IdentityHashMap groupRefs = new IdentityHashMap();
934 for (SequenceI sq : jal.getSequences())
936 // Store annotation on dataset sequences only
937 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
938 if (aa != null && aa.length > 0)
940 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
947 if (jal.getAlignmentAnnotation() != null)
949 // Store the annotation shown on the alignment.
950 jalview.datamodel.AlignmentAnnotation[] aa = jal
951 .getAlignmentAnnotation();
952 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
957 if (jal.getGroups() != null)
959 JGroup[] groups = new JGroup[jal.getGroups().size()];
961 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
963 groups[++i] = new JGroup();
965 groups[i].setStart(sg.getStartRes());
966 groups[i].setEnd(sg.getEndRes());
967 groups[i].setName(sg.getName());
968 if (groupRefs.containsKey(sg))
970 // group has references so set it's ID field
971 groups[i].setId(groupRefs.get(sg).toString());
975 if (sg.cs.conservationApplied())
977 groups[i].setConsThreshold(sg.cs.getConservationInc());
979 if (sg.cs instanceof jalview.schemes.UserColourScheme)
981 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
987 .setColour(ColourSchemeProperty.getColourName(sg.cs));
990 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
992 groups[i].setColour("AnnotationColourGradient");
993 groups[i].setAnnotationColours(constructAnnotationColours(
994 (jalview.schemes.AnnotationColourGradient) sg.cs,
997 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1000 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
1004 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1007 groups[i].setPidThreshold(sg.cs.getThreshold());
1010 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1011 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1012 groups[i].setDisplayText(sg.getDisplayText());
1013 groups[i].setColourText(sg.getColourText());
1014 groups[i].setTextCol1(sg.textColour.getRGB());
1015 groups[i].setTextCol2(sg.textColour2.getRGB());
1016 groups[i].setTextColThreshold(sg.thresholdTextColour);
1017 groups[i].setShowUnconserved(sg.getShowNonconserved());
1018 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1019 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1020 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1021 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1022 for (int s = 0; s < sg.getSize(); s++)
1024 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1026 groups[i].addSeq(seqHash(seq));
1030 jms.setJGroup(groups);
1034 // /////////SAVE VIEWPORT
1035 Viewport view = new Viewport();
1036 view.setTitle(ap.alignFrame.getTitle());
1037 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1038 av.getSequenceSetId()));
1039 view.setId(av.getViewId());
1040 view.setViewName(av.viewName);
1041 view.setGatheredViews(av.gatherViewsHere);
1043 if (ap.av.explodedPosition != null)
1045 view.setXpos(av.explodedPosition.x);
1046 view.setYpos(av.explodedPosition.y);
1047 view.setWidth(av.explodedPosition.width);
1048 view.setHeight(av.explodedPosition.height);
1052 view.setXpos(ap.alignFrame.getBounds().x);
1053 view.setYpos(ap.alignFrame.getBounds().y);
1054 view.setWidth(ap.alignFrame.getBounds().width);
1055 view.setHeight(ap.alignFrame.getBounds().height);
1058 view.setStartRes(av.startRes);
1059 view.setStartSeq(av.startSeq);
1061 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1063 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1066 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1068 AnnotationColours ac = constructAnnotationColours(
1069 (jalview.schemes.AnnotationColourGradient) av
1070 .getGlobalColourScheme(),
1073 view.setAnnotationColours(ac);
1074 view.setBgColour("AnnotationColourGradient");
1078 view.setBgColour(ColourSchemeProperty.getColourName(av
1079 .getGlobalColourScheme()));
1082 ColourSchemeI cs = av.getGlobalColourScheme();
1086 if (cs.conservationApplied())
1088 view.setConsThreshold(cs.getConservationInc());
1089 if (cs instanceof jalview.schemes.UserColourScheme)
1091 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1095 if (cs instanceof ResidueColourScheme)
1097 view.setPidThreshold(cs.getThreshold());
1101 view.setConservationSelected(av.getConservationSelected());
1102 view.setPidSelected(av.getAbovePIDThreshold());
1103 view.setFontName(av.font.getName());
1104 view.setFontSize(av.font.getSize());
1105 view.setFontStyle(av.font.getStyle());
1106 view.setRenderGaps(av.renderGaps);
1107 view.setShowAnnotation(av.getShowAnnotation());
1108 view.setShowBoxes(av.getShowBoxes());
1109 view.setShowColourText(av.getColourText());
1110 view.setShowFullId(av.getShowJVSuffix());
1111 view.setRightAlignIds(av.rightAlignIds);
1112 view.setShowSequenceFeatures(av.showSequenceFeatures);
1113 view.setShowText(av.getShowText());
1114 view.setShowUnconserved(av.getShowUnconserved());
1115 view.setWrapAlignment(av.getWrapAlignment());
1116 view.setTextCol1(av.textColour.getRGB());
1117 view.setTextCol2(av.textColour2.getRGB());
1118 view.setTextColThreshold(av.thresholdTextColour);
1119 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1120 view.setShowSequenceLogo(av.isShowSequenceLogo());
1121 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1122 view.setShowGroupConsensus(av.isShowGroupConsensus());
1123 view.setShowGroupConservation(av.isShowGroupConservation());
1124 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1125 view.setShowDbRefTooltip(av.isShowDbRefs());
1126 view.setFollowHighlight(av.followHighlight);
1127 view.setFollowSelection(av.followSelection);
1128 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1129 if (av.featuresDisplayed != null)
1131 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1133 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1135 Vector settingsAdded = new Vector();
1136 Object gstyle = null;
1137 GraduatedColor gcol = null;
1138 if (renderOrder != null)
1140 for (int ro = 0; ro < renderOrder.length; ro++)
1142 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1143 .getFeatureStyle(renderOrder[ro]);
1144 Setting setting = new Setting();
1145 setting.setType(renderOrder[ro]);
1146 if (gstyle instanceof GraduatedColor)
1148 gcol = (GraduatedColor) gstyle;
1149 setting.setColour(gcol.getMaxColor().getRGB());
1150 setting.setMincolour(gcol.getMinColor().getRGB());
1151 setting.setMin(gcol.getMin());
1152 setting.setMax(gcol.getMax());
1153 setting.setColourByLabel(gcol.isColourByLabel());
1154 setting.setAutoScale(gcol.isAutoScale());
1155 setting.setThreshold(gcol.getThresh());
1156 setting.setThreshstate(gcol.getThreshType());
1160 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1161 .getColour(renderOrder[ro]).getRGB());
1164 setting.setDisplay(av.featuresDisplayed
1165 .containsKey(renderOrder[ro]));
1166 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1167 .getOrder(renderOrder[ro]);
1170 setting.setOrder(rorder);
1172 fs.addSetting(setting);
1173 settingsAdded.addElement(renderOrder[ro]);
1177 // Make sure we save none displayed feature settings
1178 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1179 .keySet().iterator();
1180 while (en.hasNext())
1182 String key = en.next().toString();
1183 if (settingsAdded.contains(key))
1188 Setting setting = new Setting();
1189 setting.setType(key);
1190 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1191 .getColour(key).getRGB());
1193 setting.setDisplay(false);
1194 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1198 setting.setOrder(rorder);
1200 fs.addSetting(setting);
1201 settingsAdded.addElement(key);
1203 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1204 .keySet().iterator();
1205 Vector groupsAdded = new Vector();
1206 while (en.hasNext())
1208 String grp = en.next().toString();
1209 if (groupsAdded.contains(grp))
1213 Group g = new Group();
1215 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas
1216 .getFeatureRenderer().featureGroups.get(grp))
1219 groupsAdded.addElement(grp);
1221 jms.setFeatureSettings(fs);
1225 if (av.hasHiddenColumns())
1227 if (av.getColumnSelection() == null
1228 || av.getColumnSelection().getHiddenColumns() == null)
1230 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1234 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1237 int[] region = av.getColumnSelection().getHiddenColumns()
1239 HiddenColumns hc = new HiddenColumns();
1240 hc.setStart(region[0]);
1241 hc.setEnd(region[1]);
1242 view.addHiddenColumns(hc);
1246 if (calcIdSet.size() > 0)
1248 for (String calcId : calcIdSet)
1250 if (calcId.trim().length() > 0)
1252 CalcIdParam cidp = createCalcIdParam(calcId, av);
1253 // Some calcIds have no parameters.
1256 view.addCalcIdParam(cidp);
1262 jms.addViewport(view);
1264 object.setJalviewModelSequence(jms);
1265 object.getVamsasModel().addSequenceSet(vamsasSet);
1267 if (jout != null && fileName != null)
1269 // We may not want to write the object to disk,
1270 // eg we can copy the alignViewport to a new view object
1271 // using save and then load
1274 JarEntry entry = new JarEntry(fileName);
1275 jout.putNextEntry(entry);
1276 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1278 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1280 marshaller.marshal(object);
1283 } catch (Exception ex)
1285 // TODO: raise error in GUI if marshalling failed.
1286 ex.printStackTrace();
1292 private AnnotationColours constructAnnotationColours(
1293 AnnotationColourGradient acg, Vector userColours,
1294 JalviewModelSequence jms)
1296 AnnotationColours ac = new AnnotationColours();
1297 ac.setAboveThreshold(acg.getAboveThreshold());
1298 ac.setThreshold(acg.getAnnotationThreshold());
1299 ac.setAnnotation(acg.getAnnotation());
1300 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1302 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1307 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1311 ac.setMaxColour(acg.getMaxColour().getRGB());
1312 ac.setMinColour(acg.getMinColour().getRGB());
1313 ac.setPerSequence(acg.isSeqAssociated());
1314 ac.setPredefinedColours(acg.isPredefinedColours());
1318 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1319 IdentityHashMap groupRefs, AlignmentViewport av,
1320 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1323 for (int i = 0; i < aa.length; i++)
1325 Annotation an = new Annotation();
1327 if (aa[i].annotationId != null)
1329 annotationIds.put(aa[i].annotationId, aa[i]);
1332 an.setId(aa[i].annotationId);
1334 an.setVisible(aa[i].visible);
1336 an.setDescription(aa[i].description);
1338 if (aa[i].sequenceRef != null)
1340 // TODO later annotation sequenceRef should be the XML ID of the
1341 // sequence rather than its display name
1342 an.setSequenceRef(aa[i].sequenceRef.getName());
1344 if (aa[i].groupRef != null)
1346 Object groupIdr = groupRefs.get(aa[i].groupRef);
1347 if (groupIdr == null)
1349 // make a locally unique String
1350 groupRefs.put(aa[i].groupRef,
1351 groupIdr = ("" + System.currentTimeMillis()
1352 + aa[i].groupRef.getName() + groupRefs.size()));
1354 an.setGroupRef(groupIdr.toString());
1357 // store all visualization attributes for annotation
1358 an.setGraphHeight(aa[i].graphHeight);
1359 an.setCentreColLabels(aa[i].centreColLabels);
1360 an.setScaleColLabels(aa[i].scaleColLabel);
1361 an.setShowAllColLabels(aa[i].showAllColLabels);
1362 an.setBelowAlignment(aa[i].belowAlignment);
1364 if (aa[i].graph > 0)
1367 an.setGraphType(aa[i].graph);
1368 an.setGraphGroup(aa[i].graphGroup);
1369 if (aa[i].getThreshold() != null)
1371 ThresholdLine line = new ThresholdLine();
1372 line.setLabel(aa[i].getThreshold().label);
1373 line.setValue(aa[i].getThreshold().value);
1374 line.setColour(aa[i].getThreshold().colour.getRGB());
1375 an.setThresholdLine(line);
1383 an.setLabel(aa[i].label);
1385 if (aa[i] == av.getAlignmentQualityAnnot()
1386 || aa[i] == av.getAlignmentConservationAnnotation()
1387 || aa[i] == av.getAlignmentConsensusAnnotation()
1388 || aa[i].autoCalculated)
1390 // new way of indicating autocalculated annotation -
1391 an.setAutoCalculated(aa[i].autoCalculated);
1393 if (aa[i].hasScore())
1395 an.setScore(aa[i].getScore());
1398 if (aa[i].getCalcId() != null)
1400 calcIdSet.add(aa[i].getCalcId());
1401 an.setCalcId(aa[i].getCalcId());
1403 if (aa[i].hasProperties())
1405 for (String pr : aa[i].getProperties())
1407 Property prop = new Property();
1409 prop.setValue(aa[i].getProperty(pr));
1410 an.addProperty(prop);
1413 AnnotationElement ae;
1414 if (aa[i].annotations != null)
1416 an.setScoreOnly(false);
1417 for (int a = 0; a < aa[i].annotations.length; a++)
1419 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1424 ae = new AnnotationElement();
1425 if (aa[i].annotations[a].description != null)
1427 ae.setDescription(aa[i].annotations[a].description);
1429 if (aa[i].annotations[a].displayCharacter != null)
1431 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1434 if (!Float.isNaN(aa[i].annotations[a].value))
1436 ae.setValue(aa[i].annotations[a].value);
1440 if (aa[i].annotations[a].secondaryStructure > ' ')
1442 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1446 if (aa[i].annotations[a].colour != null
1447 && aa[i].annotations[a].colour != java.awt.Color.black)
1449 ae.setColour(aa[i].annotations[a].colour.getRGB());
1452 an.addAnnotationElement(ae);
1453 if (aa[i].autoCalculated)
1455 // only write one non-null entry into the annotation row -
1456 // sufficient to get the visualization attributes necessary to
1464 an.setScoreOnly(true);
1466 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1468 // skip autocalculated annotation - these are only provided for
1470 vamsasSet.addAnnotation(an);
1476 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1478 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1479 if (settings != null)
1481 CalcIdParam vCalcIdParam = new CalcIdParam();
1482 vCalcIdParam.setCalcId(calcId);
1483 vCalcIdParam.addServiceURL(settings.getServiceURI());
1484 // generic URI allowing a third party to resolve another instance of the
1485 // service used for this calculation
1486 for (String urls : settings.getServiceURLs())
1488 vCalcIdParam.addServiceURL(urls);
1490 vCalcIdParam.setVersion("1.0");
1491 if (settings.getPreset() != null)
1493 WsParamSetI setting = settings.getPreset();
1494 vCalcIdParam.setName(setting.getName());
1495 vCalcIdParam.setDescription(setting.getDescription());
1499 vCalcIdParam.setName("");
1500 vCalcIdParam.setDescription("Last used parameters");
1502 // need to be able to recover 1) settings 2) user-defined presets or
1503 // recreate settings from preset 3) predefined settings provided by
1504 // service - or settings that can be transferred (or discarded)
1505 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1507 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1508 // todo - decide if updateImmediately is needed for any projects.
1510 return vCalcIdParam;
1515 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1518 if (calcIdParam.getVersion().equals("1.0"))
1520 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1521 .getPreferredServiceFor(calcIdParam.getServiceURL());
1522 if (service != null)
1524 WsParamSetI parmSet = null;
1527 parmSet = service.getParamStore().parseServiceParameterFile(
1528 calcIdParam.getName(), calcIdParam.getDescription(),
1529 calcIdParam.getServiceURL(),
1530 calcIdParam.getParameters().replace("|\\n|", "\n"));
1531 } catch (IOException x)
1533 warn("Couldn't parse parameter data for "
1534 + calcIdParam.getCalcId(), x);
1537 List<ArgumentI> argList = null;
1538 if (calcIdParam.getName().length() > 0)
1540 parmSet = service.getParamStore()
1541 .getPreset(calcIdParam.getName());
1542 if (parmSet != null)
1544 // TODO : check we have a good match with settings in AACon -
1545 // otherwise we'll need to create a new preset
1550 argList = parmSet.getArguments();
1553 AAConSettings settings = new AAConSettings(
1554 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1555 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1556 calcIdParam.isNeedsUpdate());
1561 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1565 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1569 * External mapping between jalview objects and objects yielding a valid and
1570 * unique object ID string. This is null for normal Jalview project IO, but
1571 * non-null when a jalview project is being read or written as part of a
1574 IdentityHashMap jv2vobj = null;
1577 * Construct a unique ID for jvobj using either existing bindings or if none
1578 * exist, the result of the hashcode call for the object.
1581 * jalview data object
1582 * @return unique ID for referring to jvobj
1584 private String makeHashCode(Object jvobj, String altCode)
1586 if (jv2vobj != null)
1588 Object id = jv2vobj.get(jvobj);
1591 return id.toString();
1593 // check string ID mappings
1594 if (jvids2vobj != null && jvobj instanceof String)
1596 id = jvids2vobj.get(jvobj);
1600 return id.toString();
1602 // give up and warn that something has gone wrong
1603 warn("Cannot find ID for object in external mapping : " + jvobj);
1609 * return local jalview object mapped to ID, if it exists
1613 * @return null or object bound to idcode
1615 private Object retrieveExistingObj(String idcode)
1617 if (idcode != null && vobj2jv != null)
1619 return vobj2jv.get(idcode);
1625 * binding from ID strings from external mapping table to jalview data model
1628 private Hashtable vobj2jv;
1630 private Sequence createVamsasSequence(String id, SequenceI jds)
1632 return createVamsasSequence(true, id, jds, null);
1635 private Sequence createVamsasSequence(boolean recurse, String id,
1636 SequenceI jds, SequenceI parentseq)
1638 Sequence vamsasSeq = new Sequence();
1639 vamsasSeq.setId(id);
1640 vamsasSeq.setName(jds.getName());
1641 vamsasSeq.setSequence(jds.getSequenceAsString());
1642 vamsasSeq.setDescription(jds.getDescription());
1643 jalview.datamodel.DBRefEntry[] dbrefs = null;
1644 if (jds.getDatasetSequence() != null)
1646 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1647 if (jds.getDatasetSequence().getDBRef() != null)
1649 dbrefs = jds.getDatasetSequence().getDBRef();
1654 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1655 // dataset sequences only
1656 dbrefs = jds.getDBRef();
1660 for (int d = 0; d < dbrefs.length; d++)
1662 DBRef dbref = new DBRef();
1663 dbref.setSource(dbrefs[d].getSource());
1664 dbref.setVersion(dbrefs[d].getVersion());
1665 dbref.setAccessionId(dbrefs[d].getAccessionId());
1666 if (dbrefs[d].hasMap())
1668 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1670 dbref.setMapping(mp);
1672 vamsasSeq.addDBRef(dbref);
1678 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1679 SequenceI parentseq, SequenceI jds, boolean recurse)
1682 if (jmp.getMap() != null)
1686 jalview.util.MapList mlst = jmp.getMap();
1687 int r[] = mlst.getFromRanges();
1688 for (int s = 0; s < r.length; s += 2)
1690 MapListFrom mfrom = new MapListFrom();
1691 mfrom.setStart(r[s]);
1692 mfrom.setEnd(r[s + 1]);
1693 mp.addMapListFrom(mfrom);
1695 r = mlst.getToRanges();
1696 for (int s = 0; s < r.length; s += 2)
1698 MapListTo mto = new MapListTo();
1700 mto.setEnd(r[s + 1]);
1701 mp.addMapListTo(mto);
1703 mp.setMapFromUnit(mlst.getFromRatio());
1704 mp.setMapToUnit(mlst.getToRatio());
1705 if (jmp.getTo() != null)
1707 MappingChoice mpc = new MappingChoice();
1709 && (parentseq != jmp.getTo() || parentseq
1710 .getDatasetSequence() != jmp.getTo()))
1712 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1718 SequenceI ps = null;
1719 if (parentseq != jmp.getTo()
1720 && parentseq.getDatasetSequence() != jmp.getTo())
1722 // chaining dbref rather than a handshaking one
1723 jmpid = seqHash(ps = jmp.getTo());
1727 jmpid = seqHash(ps = parentseq);
1729 mpc.setDseqFor(jmpid);
1730 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1732 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1733 seqRefIds.put(mpc.getDseqFor(), ps);
1737 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1740 mp.setMappingChoice(mpc);
1746 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1747 Vector userColours, JalviewModelSequence jms)
1750 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1751 boolean newucs = false;
1752 if (!userColours.contains(ucs))
1754 userColours.add(ucs);
1757 id = "ucs" + userColours.indexOf(ucs);
1760 // actually create the scheme's entry in the XML model
1761 java.awt.Color[] colours = ucs.getColours();
1762 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1763 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1765 for (int i = 0; i < colours.length; i++)
1767 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1768 col.setName(ResidueProperties.aa[i]);
1769 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1770 jbucs.addColour(col);
1772 if (ucs.getLowerCaseColours() != null)
1774 colours = ucs.getLowerCaseColours();
1775 for (int i = 0; i < colours.length; i++)
1777 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1778 col.setName(ResidueProperties.aa[i].toLowerCase());
1779 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1780 jbucs.addColour(col);
1785 uc.setUserColourScheme(jbucs);
1786 jms.addUserColours(uc);
1792 jalview.schemes.UserColourScheme GetUserColourScheme(
1793 JalviewModelSequence jms, String id)
1795 UserColours[] uc = jms.getUserColours();
1796 UserColours colours = null;
1798 for (int i = 0; i < uc.length; i++)
1800 if (uc[i].getId().equals(id))
1808 java.awt.Color[] newColours = new java.awt.Color[24];
1810 for (int i = 0; i < 24; i++)
1812 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1813 .getUserColourScheme().getColour(i).getRGB(), 16));
1816 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1819 if (colours.getUserColourScheme().getColourCount() > 24)
1821 newColours = new java.awt.Color[23];
1822 for (int i = 0; i < 23; i++)
1824 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1825 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1827 ucs.setLowerCaseColours(newColours);
1834 * contains last error message (if any) encountered by XML loader.
1836 String errorMessage = null;
1839 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1840 * exceptions are raised during project XML parsing
1842 public boolean attemptversion1parse = true;
1845 * Load a jalview project archive from a jar file
1848 * - HTTP URL or filename
1850 public AlignFrame LoadJalviewAlign(final String file)
1853 jalview.gui.AlignFrame af = null;
1857 // create list to store references for any new Jmol viewers created
1858 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1859 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1860 // Workaround is to make sure caller implements the JarInputStreamProvider
1862 // so we can re-open the jar input stream for each entry.
1864 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1865 af = LoadJalviewAlign(jprovider);
1867 } catch (MalformedURLException e)
1869 errorMessage = "Invalid URL format for '" + file + "'";
1875 SwingUtilities.invokeAndWait(new Runnable()
1879 setLoadingFinishedForNewStructureViewers();
1882 } catch (Exception x)
1890 private jarInputStreamProvider createjarInputStreamProvider(
1891 final String file) throws MalformedURLException
1894 errorMessage = null;
1895 uniqueSetSuffix = null;
1897 viewportsAdded = null;
1898 frefedSequence = null;
1900 if (file.startsWith("http://"))
1902 url = new URL(file);
1904 final URL _url = url;
1905 return new jarInputStreamProvider()
1909 public JarInputStream getJarInputStream() throws IOException
1913 return new JarInputStream(_url.openStream());
1917 return new JarInputStream(new FileInputStream(file));
1922 public String getFilename()
1930 * Recover jalview session from a jalview project archive. Caller may
1931 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1932 * themselves. Any null fields will be initialised with default values,
1933 * non-null fields are left alone.
1938 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1940 errorMessage = null;
1941 if (uniqueSetSuffix == null)
1943 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1945 if (seqRefIds == null)
1947 seqRefIds = new Hashtable();
1949 if (viewportsAdded == null)
1951 viewportsAdded = new Hashtable();
1953 if (frefedSequence == null)
1955 frefedSequence = new Vector();
1958 jalview.gui.AlignFrame af = null, _af = null;
1959 Hashtable gatherToThisFrame = new Hashtable();
1960 final String file = jprovider.getFilename();
1963 JarInputStream jin = null;
1964 JarEntry jarentry = null;
1969 jin = jprovider.getJarInputStream();
1970 for (int i = 0; i < entryCount; i++)
1972 jarentry = jin.getNextJarEntry();
1975 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1977 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1978 JalviewModel object = new JalviewModel();
1980 Unmarshaller unmar = new Unmarshaller(object);
1981 unmar.setValidation(false);
1982 object = (JalviewModel) unmar.unmarshal(in);
1983 if (true) // !skipViewport(object))
1985 _af = LoadFromObject(object, file, true, jprovider);
1986 if (object.getJalviewModelSequence().getViewportCount() > 0)
1989 if (af.viewport.gatherViewsHere)
1991 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1997 else if (jarentry != null)
1999 // Some other file here.
2002 } while (jarentry != null);
2003 resolveFrefedSequences();
2004 } catch (java.io.FileNotFoundException ex)
2006 ex.printStackTrace();
2007 errorMessage = "Couldn't locate Jalview XML file : " + file;
2008 System.err.println("Exception whilst loading jalview XML file : "
2010 } catch (java.net.UnknownHostException ex)
2012 ex.printStackTrace();
2013 errorMessage = "Couldn't locate Jalview XML file : " + file;
2014 System.err.println("Exception whilst loading jalview XML file : "
2016 } catch (Exception ex)
2018 System.err.println("Parsing as Jalview Version 2 file failed.");
2019 ex.printStackTrace(System.err);
2020 if (attemptversion1parse)
2022 // Is Version 1 Jar file?
2025 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2026 } catch (Exception ex2)
2028 System.err.println("Exception whilst loading as jalviewXMLV1:");
2029 ex2.printStackTrace();
2033 if (Desktop.instance != null)
2035 Desktop.instance.stopLoading();
2039 System.out.println("Successfully loaded archive file");
2042 ex.printStackTrace();
2044 System.err.println("Exception whilst loading jalview XML file : "
2046 } catch (OutOfMemoryError e)
2048 // Don't use the OOM Window here
2049 errorMessage = "Out of memory loading jalview XML file";
2050 System.err.println("Out of memory whilst loading jalview XML file");
2051 e.printStackTrace();
2054 if (Desktop.instance != null)
2056 Desktop.instance.stopLoading();
2059 Enumeration en = gatherToThisFrame.elements();
2060 while (en.hasMoreElements())
2062 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2064 if (errorMessage != null)
2072 * check errorMessage for a valid error message and raise an error box in the
2073 * GUI or write the current errorMessage to stderr and then clear the error
2076 protected void reportErrors()
2078 reportErrors(false);
2081 protected void reportErrors(final boolean saving)
2083 if (errorMessage != null)
2085 final String finalErrorMessage = errorMessage;
2088 javax.swing.SwingUtilities.invokeLater(new Runnable()
2093 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2094 finalErrorMessage, "Error "
2095 + (saving ? "saving" : "loading")
2096 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2102 System.err.println("Problem loading Jalview file: " + errorMessage);
2105 errorMessage = null;
2108 Hashtable<String, String> alreadyLoadedPDB;
2111 * when set, local views will be updated from view stored in JalviewXML
2112 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2113 * sync if this is set to true.
2115 private final boolean updateLocalViews = false;
2117 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2119 if (alreadyLoadedPDB == null)
2121 alreadyLoadedPDB = new Hashtable();
2124 if (alreadyLoadedPDB.containsKey(pdbId))
2126 return alreadyLoadedPDB.get(pdbId).toString();
2131 JarInputStream jin = jprovider.getJarInputStream();
2133 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2134 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2135 * FileInputStream(jprovider)); }
2138 JarEntry entry = null;
2141 entry = jin.getNextJarEntry();
2142 } while (entry != null && !entry.getName().equals(pdbId));
2145 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2146 File outFile = File.createTempFile("jalview_pdb", ".txt");
2147 outFile.deleteOnExit();
2148 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2151 while ((data = in.readLine()) != null)
2158 } catch (Exception foo)
2163 String t = outFile.getAbsolutePath();
2164 alreadyLoadedPDB.put(pdbId, t);
2169 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2171 } catch (Exception ex)
2173 ex.printStackTrace();
2179 private class JvAnnotRow
2181 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2188 * persisted version of annotation row from which to take vis properties
2190 public jalview.datamodel.AlignmentAnnotation template;
2193 * original position of the annotation row in the alignment
2199 * Load alignment frame from jalview XML DOM object
2204 * filename source string
2205 * @param loadTreesAndStructures
2206 * when false only create Viewport
2208 * data source provider
2209 * @return alignment frame created from view stored in DOM
2211 AlignFrame LoadFromObject(JalviewModel object, String file,
2212 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2214 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2215 Sequence[] vamsasSeq = vamsasSet.getSequence();
2217 JalviewModelSequence jms = object.getJalviewModelSequence();
2219 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2222 // ////////////////////////////////
2225 Vector hiddenSeqs = null;
2226 jalview.datamodel.Sequence jseq;
2228 ArrayList tmpseqs = new ArrayList();
2230 boolean multipleView = false;
2232 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2233 int vi = 0; // counter in vamsasSeq array
2234 for (int i = 0; i < JSEQ.length; i++)
2236 String seqId = JSEQ[i].getId();
2238 if (seqRefIds.get(seqId) != null)
2240 tmpseqs.add(seqRefIds.get(seqId));
2241 multipleView = true;
2245 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2246 vamsasSeq[vi].getSequence());
2247 jseq.setDescription(vamsasSeq[vi].getDescription());
2248 jseq.setStart(JSEQ[i].getStart());
2249 jseq.setEnd(JSEQ[i].getEnd());
2250 jseq.setVamsasId(uniqueSetSuffix + seqId);
2251 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2256 if (JSEQ[i].getHidden())
2258 if (hiddenSeqs == null)
2260 hiddenSeqs = new Vector();
2263 hiddenSeqs.addElement(seqRefIds.get(seqId));
2269 // Create the alignment object from the sequence set
2270 // ///////////////////////////////
2271 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2274 tmpseqs.toArray(orderedSeqs);
2276 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2279 // / Add the alignment properties
2280 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2282 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2283 al.setProperty(ssp.getKey(), ssp.getValue());
2287 // SequenceFeatures are added to the DatasetSequence,
2288 // so we must create or recover the dataset before loading features
2289 // ///////////////////////////////
2290 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2292 // older jalview projects do not have a dataset id.
2293 al.setDataset(null);
2297 // recover dataset - passing on flag indicating if this a 'viewless'
2298 // sequence set (a.k.a. a stored dataset for the project)
2299 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2300 .getViewportCount() == 0);
2302 // ///////////////////////////////
2304 Hashtable pdbloaded = new Hashtable();
2307 // load sequence features, database references and any associated PDB
2308 // structures for the alignment
2309 for (int i = 0; i < vamsasSeq.length; i++)
2311 if (JSEQ[i].getFeaturesCount() > 0)
2313 Features[] features = JSEQ[i].getFeatures();
2314 for (int f = 0; f < features.length; f++)
2316 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2317 features[f].getType(), features[f].getDescription(),
2318 features[f].getStatus(), features[f].getBegin(),
2319 features[f].getEnd(), features[f].getFeatureGroup());
2321 sf.setScore(features[f].getScore());
2322 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2324 OtherData keyValue = features[f].getOtherData(od);
2325 if (keyValue.getKey().startsWith("LINK"))
2327 sf.addLink(keyValue.getValue());
2331 sf.setValue(keyValue.getKey(), keyValue.getValue());
2336 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2339 if (vamsasSeq[i].getDBRefCount() > 0)
2341 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2343 if (JSEQ[i].getPdbidsCount() > 0)
2345 Pdbids[] ids = JSEQ[i].getPdbids();
2346 for (int p = 0; p < ids.length; p++)
2348 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2349 entry.setId(ids[p].getId());
2350 entry.setType(ids[p].getType());
2351 if (ids[p].getFile() != null)
2353 if (!pdbloaded.containsKey(ids[p].getFile()))
2355 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2359 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2362 StructureSelectionManager.getStructureSelectionManager(
2364 .registerPDBEntry(entry);
2365 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2369 } // end !multipleview
2371 // ///////////////////////////////
2372 // LOAD SEQUENCE MAPPINGS
2374 if (vamsasSet.getAlcodonFrameCount() > 0)
2376 // TODO Potentially this should only be done once for all views of an
2378 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2379 for (int i = 0; i < alc.length; i++)
2381 AlignedCodonFrame cf = new AlignedCodonFrame();
2382 if (alc[i].getAlcodMapCount() > 0)
2384 AlcodMap[] maps = alc[i].getAlcodMap();
2385 for (int m = 0; m < maps.length; m++)
2387 SequenceI dnaseq = (SequenceI) seqRefIds
2388 .get(maps[m].getDnasq());
2390 jalview.datamodel.Mapping mapping = null;
2391 // attach to dna sequence reference.
2392 if (maps[m].getMapping() != null)
2394 mapping = addMapping(maps[m].getMapping());
2398 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2403 frefedSequence.add(new Object[]
2404 { maps[m].getDnasq(), cf, mapping });
2408 al.addCodonFrame(cf);
2413 // ////////////////////////////////
2415 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2417 * store any annotations which forward reference a group's ID
2419 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2421 if (vamsasSet.getAnnotationCount() > 0)
2423 Annotation[] an = vamsasSet.getAnnotation();
2425 for (int i = 0; i < an.length; i++)
2428 * test if annotation is automatically calculated for this view only
2430 boolean autoForView = false;
2431 if (an[i].getLabel().equals("Quality")
2432 || an[i].getLabel().equals("Conservation")
2433 || an[i].getLabel().equals("Consensus"))
2435 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2437 if (!an[i].hasAutoCalculated())
2439 an[i].setAutoCalculated(true);
2443 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2445 // remove ID - we don't recover annotation from other views for
2446 // view-specific annotation
2450 // set visiblity for other annotation in this view
2451 if (an[i].getId() != null
2452 && annotationIds.containsKey(an[i].getId()))
2454 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2455 .get(an[i].getId());
2456 // in principle Visible should always be true for annotation displayed
2457 // in multiple views
2458 if (an[i].hasVisible())
2460 jda.visible = an[i].getVisible();
2463 al.addAnnotation(jda);
2467 // Construct new annotation from model.
2468 AnnotationElement[] ae = an[i].getAnnotationElement();
2469 jalview.datamodel.Annotation[] anot = null;
2470 java.awt.Color firstColour = null;
2472 if (!an[i].getScoreOnly())
2474 anot = new jalview.datamodel.Annotation[al.getWidth()];
2475 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2477 anpos = ae[aa].getPosition();
2479 if (anpos >= anot.length)
2484 anot[anpos] = new jalview.datamodel.Annotation(
2486 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2487 (ae[aa].getSecondaryStructure() == null || ae[aa]
2488 .getSecondaryStructure().length() == 0) ? ' '
2489 : ae[aa].getSecondaryStructure().charAt(0),
2493 // JBPNote: Consider verifying dataflow for IO of secondary
2494 // structure annotation read from Stockholm files
2495 // this was added to try to ensure that
2496 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2498 // anot[ae[aa].getPosition()].displayCharacter = "";
2500 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2501 if (firstColour == null)
2503 firstColour = anot[anpos].colour;
2507 jalview.datamodel.AlignmentAnnotation jaa = null;
2509 if (an[i].getGraph())
2511 float llim = 0, hlim = 0;
2512 // if (autoForView || an[i].isAutoCalculated()) {
2515 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2516 an[i].getDescription(), anot, llim, hlim,
2517 an[i].getGraphType());
2519 jaa.graphGroup = an[i].getGraphGroup();
2520 jaa._linecolour = firstColour;
2521 if (an[i].getThresholdLine() != null)
2523 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2524 .getThresholdLine().getValue(), an[i]
2525 .getThresholdLine().getLabel(), new java.awt.Color(
2526 an[i].getThresholdLine().getColour())));
2529 if (autoForView || an[i].isAutoCalculated())
2531 // Hardwire the symbol display line to ensure that labels for
2532 // histograms are displayed
2538 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2539 an[i].getDescription(), anot);
2540 jaa._linecolour = firstColour;
2542 // register new annotation
2543 if (an[i].getId() != null)
2545 annotationIds.put(an[i].getId(), jaa);
2546 jaa.annotationId = an[i].getId();
2548 // recover sequence association
2549 if (an[i].getSequenceRef() != null)
2551 if (al.findName(an[i].getSequenceRef()) != null)
2553 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2555 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2558 // and make a note of any group association
2559 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2561 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2562 .get(an[i].getGroupRef());
2565 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2566 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2571 if (an[i].hasScore())
2573 jaa.setScore(an[i].getScore());
2575 if (an[i].hasVisible())
2577 jaa.visible = an[i].getVisible();
2580 if (an[i].hasCentreColLabels())
2582 jaa.centreColLabels = an[i].getCentreColLabels();
2585 if (an[i].hasScaleColLabels())
2587 jaa.scaleColLabel = an[i].getScaleColLabels();
2589 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2591 // newer files have an 'autoCalculated' flag and store calculation
2592 // state in viewport properties
2593 jaa.autoCalculated = true; // means annotation will be marked for
2594 // update at end of load.
2596 if (an[i].hasGraphHeight())
2598 jaa.graphHeight = an[i].getGraphHeight();
2600 if (an[i].hasBelowAlignment())
2602 jaa.belowAlignment = an[i].isBelowAlignment();
2604 jaa.setCalcId(an[i].getCalcId());
2605 if (an[i].getPropertyCount() > 0)
2607 for (jalview.schemabinding.version2.Property prop : an[i]
2610 jaa.setProperty(prop.getName(), prop.getValue());
2613 if (jaa.autoCalculated)
2615 autoAlan.add(new JvAnnotRow(i, jaa));
2618 // if (!autoForView)
2620 // add autocalculated group annotation and any user created annotation
2622 al.addAnnotation(jaa);
2626 // ///////////////////////
2628 // Create alignment markup and styles for this view
2629 if (jms.getJGroupCount() > 0)
2631 JGroup[] groups = jms.getJGroup();
2632 boolean addAnnotSchemeGroup = false;
2633 for (int i = 0; i < groups.length; i++)
2635 ColourSchemeI cs = null;
2637 if (groups[i].getColour() != null)
2639 if (groups[i].getColour().startsWith("ucs"))
2641 cs = GetUserColourScheme(jms, groups[i].getColour());
2643 else if (groups[i].getColour().equals("AnnotationColourGradient")
2644 && groups[i].getAnnotationColours() != null)
2646 addAnnotSchemeGroup = true;
2651 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2656 cs.setThreshold(groups[i].getPidThreshold(), true);
2660 Vector seqs = new Vector();
2662 for (int s = 0; s < groups[i].getSeqCount(); s++)
2664 String seqId = groups[i].getSeq(s) + "";
2665 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2670 seqs.addElement(ts);
2674 if (seqs.size() < 1)
2679 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2680 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2681 groups[i].getDisplayText(), groups[i].getColourText(),
2682 groups[i].getStart(), groups[i].getEnd());
2684 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2686 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2687 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2688 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2689 .isShowUnconserved() : false);
2690 sg.thresholdTextColour = groups[i].getTextColThreshold();
2691 if (groups[i].hasShowConsensusHistogram())
2693 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2696 if (groups[i].hasShowSequenceLogo())
2698 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2700 if (groups[i].hasNormaliseSequenceLogo())
2702 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2704 if (groups[i].hasIgnoreGapsinConsensus())
2706 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2708 if (groups[i].getConsThreshold() != 0)
2710 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2711 "All", ResidueProperties.propHash, 3,
2712 sg.getSequences(null), 0, sg.getWidth() - 1);
2714 c.verdict(false, 25);
2715 sg.cs.setConservation(c);
2718 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2720 // re-instate unique group/annotation row reference
2721 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2722 .get(groups[i].getId());
2725 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2728 if (jaa.autoCalculated)
2730 // match up and try to set group autocalc alignment row for this
2732 if (jaa.label.startsWith("Consensus for "))
2734 sg.setConsensus(jaa);
2736 // match up and try to set group autocalc alignment row for this
2738 if (jaa.label.startsWith("Conservation for "))
2740 sg.setConservationRow(jaa);
2747 if (addAnnotSchemeGroup)
2749 // reconstruct the annotation colourscheme
2750 sg.cs = constructAnnotationColour(
2751 groups[i].getAnnotationColours(), null, al, jms, false);
2757 // only dataset in this model, so just return.
2760 // ///////////////////////////////
2763 // If we just load in the same jar file again, the sequenceSetId
2764 // will be the same, and we end up with multiple references
2765 // to the same sequenceSet. We must modify this id on load
2766 // so that each load of the file gives a unique id
2767 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2768 String viewId = (view.getId() == null ? null : view.getId()
2770 AlignFrame af = null;
2771 AlignViewport av = null;
2772 // now check to see if we really need to create a new viewport.
2773 if (multipleView && viewportsAdded.size() == 0)
2775 // We recovered an alignment for which a viewport already exists.
2776 // TODO: fix up any settings necessary for overlaying stored state onto
2777 // state recovered from another document. (may not be necessary).
2778 // we may need a binding from a viewport in memory to one recovered from
2780 // and then recover its containing af to allow the settings to be applied.
2781 // TODO: fix for vamsas demo
2783 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2785 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2786 if (seqsetobj != null)
2788 if (seqsetobj instanceof String)
2790 uniqueSeqSetId = (String) seqsetobj;
2792 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2798 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2804 * indicate that annotation colours are applied across all groups (pre
2805 * Jalview 2.8.1 behaviour)
2807 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2808 object.getVersion());
2810 AlignmentPanel ap = null;
2811 boolean isnewview = true;
2814 // Check to see if this alignment already has a view id == viewId
2815 jalview.gui.AlignmentPanel views[] = Desktop
2816 .getAlignmentPanels(uniqueSeqSetId);
2817 if (views != null && views.length > 0)
2819 for (int v = 0; v < views.length; v++)
2821 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2823 // recover the existing alignpanel, alignframe, viewport
2824 af = views[v].alignFrame;
2827 // TODO: could even skip resetting view settings if we don't want to
2828 // change the local settings from other jalview processes
2837 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2838 uniqueSeqSetId, viewId, autoAlan);
2843 // /////////////////////////////////////
2844 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2848 for (int t = 0; t < jms.getTreeCount(); t++)
2851 Tree tree = jms.getTree(t);
2853 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2856 tp = af.ShowNewickTree(
2857 new jalview.io.NewickFile(tree.getNewick()),
2858 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2859 tree.getXpos(), tree.getYpos());
2860 if (tree.getId() != null)
2862 // perhaps bind the tree id to something ?
2867 // update local tree attributes ?
2868 // TODO: should check if tp has been manipulated by user - if so its
2869 // settings shouldn't be modified
2870 tp.setTitle(tree.getTitle());
2871 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2872 .getWidth(), tree.getHeight()));
2873 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2876 tp.treeCanvas.av = av; // af.viewport;
2877 tp.treeCanvas.ap = ap; // af.alignPanel;
2882 warn("There was a problem recovering stored Newick tree: \n"
2883 + tree.getNewick());
2887 tp.fitToWindow.setState(tree.getFitToWindow());
2888 tp.fitToWindow_actionPerformed(null);
2890 if (tree.getFontName() != null)
2892 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2893 .getFontStyle(), tree.getFontSize()));
2897 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2898 .getFontStyle(), tree.getFontSize()));
2901 tp.showPlaceholders(tree.getMarkUnlinked());
2902 tp.showBootstrap(tree.getShowBootstrap());
2903 tp.showDistances(tree.getShowDistances());
2905 tp.treeCanvas.threshold = tree.getThreshold();
2907 if (tree.getCurrentTree())
2909 af.viewport.setCurrentTree(tp.getTree());
2913 } catch (Exception ex)
2915 ex.printStackTrace();
2919 // //LOAD STRUCTURES
2920 if (loadTreesAndStructures)
2922 // run through all PDB ids on the alignment, and collect mappings between
2923 // jmol view ids and all sequences referring to it
2924 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2926 for (int i = 0; i < JSEQ.length; i++)
2928 if (JSEQ[i].getPdbidsCount() > 0)
2930 Pdbids[] ids = JSEQ[i].getPdbids();
2931 for (int p = 0; p < ids.length; p++)
2933 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2935 // check to see if we haven't already created this structure view
2936 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2937 : ids[p].getStructureState(s).getViewId()
2939 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2940 // Originally : ids[p].getFile()
2941 // : TODO: verify external PDB file recovery still works in normal
2942 // jalview project load
2943 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2944 jpdb.setId(ids[p].getId());
2946 int x = ids[p].getStructureState(s).getXpos();
2947 int y = ids[p].getStructureState(s).getYpos();
2948 int width = ids[p].getStructureState(s).getWidth();
2949 int height = ids[p].getStructureState(s).getHeight();
2951 // Probably don't need to do this anymore...
2952 // Desktop.desktop.getComponentAt(x, y);
2953 // TODO: NOW: check that this recovers the PDB file correctly.
2954 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2955 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2956 .get(JSEQ[i].getId() + "");
2957 if (sviewid == null)
2959 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2962 if (!jmolViewIds.containsKey(sviewid))
2964 jmolViewIds.put(sviewid, new Object[]
2966 { x, y, width, height }, "",
2967 new Hashtable<String, Object[]>(), new boolean[]
2968 { false, false, true } });
2969 // Legacy pre-2.7 conversion JAL-823 :
2970 // do not assume any view has to be linked for colour by
2974 // assemble String[] { pdb files }, String[] { id for each
2975 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2976 // seqs_file 2}, boolean[] {
2977 // linkAlignPanel,superposeWithAlignpanel}} from hash
2978 Object[] jmoldat = jmolViewIds.get(sviewid);
2979 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2980 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2981 s).getAlignwithAlignPanel() : false;
2982 // never colour by linked panel if not specified
2983 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2984 .hasColourwithAlignPanel() ? ids[p]
2985 .getStructureState(s).getColourwithAlignPanel()
2987 // default for pre-2.7 projects is that Jmol colouring is enabled
2988 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2989 .hasColourByJmol() ? ids[p].getStructureState(s)
2990 .getColourByJmol() : true;
2992 if (((String) jmoldat[1]).length() < ids[p]
2993 .getStructureState(s).getContent().length())
2996 jmoldat[1] = ids[p].getStructureState(s).getContent();
2999 if (ids[p].getFile() != null)
3001 File mapkey = new File(ids[p].getFile());
3002 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3004 if (seqstrmaps == null)
3006 ((Hashtable) jmoldat[2]).put(mapkey,
3007 seqstrmaps = new Object[]
3008 { pdbFile, ids[p].getId(), new Vector(),
3011 if (!((Vector) seqstrmaps[2]).contains(seq))
3013 ((Vector) seqstrmaps[2]).addElement(seq);
3014 // ((Vector)seqstrmaps[3]).addElement(n) :
3015 // in principle, chains
3016 // should be stored here : do we need to
3017 // TODO: store and recover seq/pdb_id :
3023 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");
3032 // Instantiate the associated Jmol views
3033 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3035 String sviewid = entry.getKey();
3036 Object[] svattrib = entry.getValue();
3037 int[] geom = (int[]) svattrib[0];
3038 String state = (String) svattrib[1];
3039 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3040 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3041 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3042 // collate the pdbfile -> sequence mappings from this view
3043 Vector<String> pdbfilenames = new Vector<String>();
3044 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3045 Vector<String> pdbids = new Vector<String>();
3047 // Search to see if we've already created this Jmol view
3048 AppJmol comp = null;
3049 JInternalFrame[] frames = null;
3054 frames = Desktop.desktop.getAllFrames();
3055 } catch (ArrayIndexOutOfBoundsException e)
3057 // occasional No such child exceptions are thrown here...
3062 } catch (Exception f)
3067 } while (frames == null);
3068 // search for any Jmol windows already open from other
3069 // alignment views that exactly match the stored structure state
3070 for (int f = 0; comp == null && f < frames.length; f++)
3072 if (frames[f] instanceof AppJmol)
3075 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3077 // post jalview 2.4 schema includes structure view id
3078 comp = (AppJmol) frames[f];
3080 else if (frames[f].getX() == x && frames[f].getY() == y
3081 && frames[f].getHeight() == height
3082 && frames[f].getWidth() == width)
3084 comp = (AppJmol) frames[f];
3091 // create a new Jmol window.
3092 // First parse the Jmol state to translate filenames loaded into the
3093 // view, and record the order in which files are shown in the Jmol
3094 // view, so we can add the sequence mappings in same order.
3095 StringBuffer newFileLoc = null;
3096 int cp = 0, ncp, ecp;
3097 while ((ncp = state.indexOf("load ", cp)) > -1)
3099 if (newFileLoc == null)
3101 newFileLoc = new StringBuffer();
3105 // look for next filename in load statement
3106 newFileLoc.append(state.substring(cp,
3107 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3108 String oldfilenam = state.substring(ncp,
3109 ecp = state.indexOf("\"", ncp));
3110 // recover the new mapping data for this old filename
3111 // have to normalize filename - since Jmol and jalview do
3113 // translation differently.
3114 Object[] filedat = oldFiles.get(new File(oldfilenam));
3115 newFileLoc.append(Platform
3116 .escapeString((String) filedat[0]));
3117 pdbfilenames.addElement((String) filedat[0]);
3118 pdbids.addElement((String) filedat[1]);
3119 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3120 .toArray(new SequenceI[0]));
3121 newFileLoc.append("\"");
3122 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3123 // look for next file statement.
3124 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3128 // just append rest of state
3129 newFileLoc.append(state.substring(cp));
3134 .print("Ignoring incomplete Jmol state for PDB ids: ");
3135 newFileLoc = new StringBuffer(state);
3136 newFileLoc.append("; load append ");
3137 for (File id : oldFiles.keySet())
3139 // add this and any other pdb files that should be present in
3141 Object[] filedat = oldFiles.get(id);
3143 newFileLoc.append(((String) filedat[0]));
3144 pdbfilenames.addElement((String) filedat[0]);
3145 pdbids.addElement((String) filedat[1]);
3146 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3147 .toArray(new SequenceI[0]));
3148 newFileLoc.append(" \"");
3149 newFileLoc.append((String) filedat[0]);
3150 newFileLoc.append("\"");
3153 newFileLoc.append(";");
3156 if (newFileLoc != null)
3158 int histbug = newFileLoc.indexOf("history = ");
3160 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3162 String val = (diff == -1) ? null : newFileLoc.substring(
3164 if (val != null && val.length() >= 4)
3166 if (val.contains("e"))
3168 if (val.trim().equals("true"))
3176 newFileLoc.replace(histbug, diff, val);
3179 // TODO: assemble String[] { pdb files }, String[] { id for each
3180 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3181 // seqs_file 2}} from hash
3182 final String[] pdbf = pdbfilenames
3183 .toArray(new String[pdbfilenames.size()]), id = pdbids
3184 .toArray(new String[pdbids.size()]);
3185 final SequenceI[][] sq = seqmaps
3186 .toArray(new SequenceI[seqmaps.size()][]);
3187 final String fileloc = newFileLoc.toString(), vid = sviewid;
3188 final AlignFrame alf = af;
3189 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3193 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3198 JalviewStructureDisplayI sview = null;
3201 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3202 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3203 useinJmolsuperpos, usetoColourbyseq,
3204 jmolColouring, fileloc, rect, vid);
3205 addNewStructureViewer(sview);
3206 } catch (OutOfMemoryError ex)
3208 new OOMWarning("restoring structure view for PDB id "
3209 + id, (OutOfMemoryError) ex.getCause());
3210 if (sview != null && sview.isVisible())
3212 sview.closeViewer();
3213 sview.setVisible(false);
3219 } catch (InvocationTargetException ex)
3221 warn("Unexpected error when opening Jmol view.", ex);
3223 } catch (InterruptedException e)
3225 // e.printStackTrace();
3231 // if (comp != null)
3233 // NOTE: if the jalview project is part of a shared session then
3234 // view synchronization should/could be done here.
3236 // add mapping for sequences in this view to an already open Jmol
3238 for (File id : oldFiles.keySet())
3240 // add this and any other pdb files that should be present in the
3242 Object[] filedat = oldFiles.get(id);
3243 String pdbFile = (String) filedat[0];
3244 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3245 .toArray(new SequenceI[0]);
3246 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3247 jalview.io.AppletFormatAdapter.FILE);
3248 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3250 // and add the AlignmentPanel's reference to the Jmol view
3251 comp.addAlignmentPanel(ap);
3252 if (useinJmolsuperpos)
3254 comp.useAlignmentPanelForSuperposition(ap);
3258 comp.excludeAlignmentPanelForSuperposition(ap);
3260 if (usetoColourbyseq)
3262 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3266 comp.excludeAlignmentPanelForColourbyseq(ap);
3272 // and finally return.
3279 * - minimum version we are comparing against
3281 * - version of data being processsed.
3282 * @return true if version is development/null or evaluates to the same or
3283 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3285 private boolean isVersionStringLaterThan(String supported, String version)
3287 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3288 || version.equalsIgnoreCase("Test")
3289 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3291 System.err.println("Assuming project file with "
3292 + (version == null ? "null" : version)
3293 + " is compatible with Jalview version " + supported);
3298 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3300 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3302 // convert b to decimal to catch bugfix releases within a series
3303 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3304 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3307 if (Float.valueOf(curT) > Float.valueOf(fileT))
3309 // current version is newer than the version that wrote the file
3312 } catch (NumberFormatException nfe)
3315 .println("** WARNING: Version comparison failed for tokens ("
3319 + ")\n** Current: '"
3320 + supported + "' and Version: '" + version + "'");
3323 if (currentV.hasMoreElements())
3325 // fileV has no minor version but identical series to current
3332 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3334 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3336 if (newStructureViewers != null)
3338 sview.getBinding().setFinishedLoadingFromArchive(false);
3339 newStructureViewers.add(sview);
3343 protected void setLoadingFinishedForNewStructureViewers()
3345 if (newStructureViewers != null)
3347 for (JalviewStructureDisplayI sview : newStructureViewers)
3349 sview.getBinding().setFinishedLoadingFromArchive(true);
3351 newStructureViewers.clear();
3352 newStructureViewers = null;
3356 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3357 Alignment al, JalviewModelSequence jms, Viewport view,
3358 String uniqueSeqSetId, String viewId,
3359 ArrayList<JvAnnotRow> autoAlan)
3361 AlignFrame af = null;
3362 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3363 uniqueSeqSetId, viewId);
3365 af.setFileName(file, "Jalview");
3367 for (int i = 0; i < JSEQ.length; i++)
3369 af.viewport.setSequenceColour(af.viewport.getAlignment()
3370 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3373 af.viewport.gatherViewsHere = view.getGatheredViews();
3375 if (view.getSequenceSetId() != null)
3377 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3378 .get(uniqueSeqSetId);
3380 af.viewport.setSequenceSetId(uniqueSeqSetId);
3383 // propagate shared settings to this new view
3384 af.viewport.setHistoryList(av.getHistoryList());
3385 af.viewport.setRedoList(av.getRedoList());
3389 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3391 // TODO: check if this method can be called repeatedly without
3392 // side-effects if alignpanel already registered.
3393 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3395 // apply Hidden regions to view.
3396 if (hiddenSeqs != null)
3398 for (int s = 0; s < JSEQ.length; s++)
3400 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3402 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3405 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3407 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3410 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3413 for (int s = 0; s < hiddenSeqs.size(); s++)
3415 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3418 af.viewport.hideSequence(hseqs);
3421 // recover view properties and display parameters
3422 if (view.getViewName() != null)
3424 af.viewport.viewName = view.getViewName();
3425 af.setInitialTabVisible();
3427 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3430 af.viewport.setShowAnnotation(view.getShowAnnotation());
3431 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3433 af.viewport.setColourText(view.getShowColourText());
3435 af.viewport.setConservationSelected(view.getConservationSelected());
3436 af.viewport.setShowJVSuffix(view.getShowFullId());
3437 af.viewport.rightAlignIds = view.getRightAlignIds();
3438 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3439 .getFontStyle(), view.getFontSize()));
3440 af.alignPanel.fontChanged();
3441 af.viewport.setRenderGaps(view.getRenderGaps());
3442 af.viewport.setWrapAlignment(view.getWrapAlignment());
3443 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3444 af.viewport.setShowAnnotation(view.getShowAnnotation());
3445 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3447 af.viewport.setShowBoxes(view.getShowBoxes());
3449 af.viewport.setShowText(view.getShowText());
3451 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3452 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3453 af.viewport.thresholdTextColour = view.getTextColThreshold();
3454 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3455 .isShowUnconserved() : false);
3456 af.viewport.setStartRes(view.getStartRes());
3457 af.viewport.setStartSeq(view.getStartSeq());
3459 ColourSchemeI cs = null;
3460 // apply colourschemes
3461 if (view.getBgColour() != null)
3463 if (view.getBgColour().startsWith("ucs"))
3465 cs = GetUserColourScheme(jms, view.getBgColour());
3467 else if (view.getBgColour().startsWith("Annotation"))
3469 AnnotationColours viewAnnColour = view.getAnnotationColours();
3470 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3477 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3482 cs.setThreshold(view.getPidThreshold(), true);
3483 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3487 af.viewport.setGlobalColourScheme(cs);
3488 af.viewport.setColourAppliesToAllGroups(false);
3490 if (view.getConservationSelected() && cs != null)
3492 cs.setConservationInc(view.getConsThreshold());
3495 af.changeColour(cs);
3497 af.viewport.setColourAppliesToAllGroups(true);
3499 if (view.getShowSequenceFeatures())
3501 af.viewport.showSequenceFeatures = true;
3503 if (view.hasCentreColumnLabels())
3505 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3507 if (view.hasIgnoreGapsinConsensus())
3509 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3512 if (view.hasFollowHighlight())
3514 af.viewport.followHighlight = view.getFollowHighlight();
3516 if (view.hasFollowSelection())
3518 af.viewport.followSelection = view.getFollowSelection();
3520 if (view.hasShowConsensusHistogram())
3522 af.viewport.setShowConsensusHistogram(view
3523 .getShowConsensusHistogram());
3527 af.viewport.setShowConsensusHistogram(true);
3529 if (view.hasShowSequenceLogo())
3531 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3535 af.viewport.setShowSequenceLogo(false);
3537 if (view.hasNormaliseSequenceLogo())
3539 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3541 if (view.hasShowDbRefTooltip())
3543 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3545 if (view.hasShowNPfeatureTooltip())
3547 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3549 if (view.hasShowGroupConsensus())
3551 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3555 af.viewport.setShowGroupConsensus(false);
3557 if (view.hasShowGroupConservation())
3559 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3563 af.viewport.setShowGroupConservation(false);
3566 // recover featre settings
3567 if (jms.getFeatureSettings() != null)
3569 af.viewport.featuresDisplayed = new Hashtable();
3570 String[] renderOrder = new String[jms.getFeatureSettings()
3571 .getSettingCount()];
3572 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3574 Setting setting = jms.getFeatureSettings().getSetting(fs);
3575 if (setting.hasMincolour())
3577 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3578 new java.awt.Color(setting.getMincolour()),
3579 new java.awt.Color(setting.getColour()),
3580 setting.getMin(), setting.getMax()) : new GraduatedColor(
3581 new java.awt.Color(setting.getMincolour()),
3582 new java.awt.Color(setting.getColour()), 0, 1);
3583 if (setting.hasThreshold())
3585 gc.setThresh(setting.getThreshold());
3586 gc.setThreshType(setting.getThreshstate());
3588 gc.setAutoScaled(true); // default
3589 if (setting.hasAutoScale())
3591 gc.setAutoScaled(setting.getAutoScale());
3593 if (setting.hasColourByLabel())
3595 gc.setColourByLabel(setting.getColourByLabel());
3597 // and put in the feature colour table.
3598 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3599 setting.getType(), gc);
3603 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3605 new java.awt.Color(setting.getColour()));
3607 renderOrder[fs] = setting.getType();
3608 if (setting.hasOrder())
3610 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3611 setting.getType(), setting.getOrder());
3615 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3617 fs / jms.getFeatureSettings().getSettingCount());
3619 if (setting.getDisplay())
3621 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3622 setting.getColour()));
3625 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3627 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3628 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3630 Group grp = jms.getFeatureSettings().getGroup(gs);
3631 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3635 if (view.getHiddenColumnsCount() > 0)
3637 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3639 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3640 .getHiddenColumns(c).getEnd() // +1
3644 if (view.getCalcIdParam() != null)
3646 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3648 if (calcIdParam != null)
3650 if (recoverCalcIdParam(calcIdParam, af.viewport))
3655 warn("Couldn't recover parameters for "
3656 + calcIdParam.getCalcId());
3661 af.setMenusFromViewport(af.viewport);
3662 // TODO: we don't need to do this if the viewport is aready visible.
3663 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3665 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3666 reorderAutoannotation(af, al, autoAlan);
3667 af.alignPanel.alignmentChanged();
3671 private ColourSchemeI constructAnnotationColour(
3672 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3673 JalviewModelSequence jms, boolean checkGroupAnnColour)
3675 boolean propagateAnnColour = false;
3676 ColourSchemeI cs = null;
3677 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3678 if (checkGroupAnnColour && al.getGroups() != null
3679 && al.getGroups().size() > 0)
3681 // pre 2.8.1 behaviour
3682 // check to see if we should transfer annotation colours
3683 propagateAnnColour = true;
3684 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3686 if (sg.cs instanceof AnnotationColourGradient)
3688 propagateAnnColour = false;
3692 // int find annotation
3693 if (annAlignment.getAlignmentAnnotation() != null)
3695 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3697 if (annAlignment.getAlignmentAnnotation()[i].label
3698 .equals(viewAnnColour.getAnnotation()))
3700 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3702 annAlignment.getAlignmentAnnotation()[i]
3703 .setThreshold(new jalview.datamodel.GraphLine(
3704 viewAnnColour.getThreshold(), "Threshold",
3705 java.awt.Color.black)
3710 if (viewAnnColour.getColourScheme().equals("None"))
3712 cs = new AnnotationColourGradient(
3713 annAlignment.getAlignmentAnnotation()[i],
3714 new java.awt.Color(viewAnnColour.getMinColour()),
3715 new java.awt.Color(viewAnnColour.getMaxColour()),
3716 viewAnnColour.getAboveThreshold());
3718 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3720 cs = new AnnotationColourGradient(
3721 annAlignment.getAlignmentAnnotation()[i],
3722 GetUserColourScheme(jms,
3723 viewAnnColour.getColourScheme()),
3724 viewAnnColour.getAboveThreshold());
3728 cs = new AnnotationColourGradient(
3729 annAlignment.getAlignmentAnnotation()[i],
3730 ColourSchemeProperty.getColour(al,
3731 viewAnnColour.getColourScheme()),
3732 viewAnnColour.getAboveThreshold());
3734 if (viewAnnColour.hasPerSequence())
3736 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3739 if (viewAnnColour.hasPredefinedColours())
3741 ((AnnotationColourGradient) cs)
3742 .setPredefinedColours(viewAnnColour
3743 .isPredefinedColours());
3745 if (propagateAnnColour && al.getGroups() != null)
3747 // Also use these settings for all the groups
3748 for (int g = 0; g < al.getGroups().size(); g++)
3750 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3758 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3759 * new AnnotationColourGradient(
3760 * annAlignment.getAlignmentAnnotation()[i], new
3761 * java.awt.Color(viewAnnColour. getMinColour()), new
3762 * java.awt.Color(viewAnnColour. getMaxColour()),
3763 * viewAnnColour.getAboveThreshold()); } else
3766 sg.cs = new AnnotationColourGradient(
3767 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3768 viewAnnColour.getAboveThreshold());
3769 if (cs instanceof AnnotationColourGradient)
3771 if (viewAnnColour.hasPerSequence())
3773 ((AnnotationColourGradient) cs)
3774 .setSeqAssociated(viewAnnColour.isPerSequence());
3776 if (viewAnnColour.hasPredefinedColours())
3778 ((AnnotationColourGradient) cs)
3779 .setPredefinedColours(viewAnnColour
3780 .isPredefinedColours());
3796 private void reorderAutoannotation(AlignFrame af, Alignment al,
3797 ArrayList<JvAnnotRow> autoAlan)
3799 // copy over visualization settings for autocalculated annotation in the
3801 if (al.getAlignmentAnnotation() != null)
3804 * Kludge for magic autoannotation names (see JAL-811)
3806 String[] magicNames = new String[]
3807 { "Consensus", "Quality", "Conservation" };
3808 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3809 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3810 for (String nm : magicNames)
3812 visan.put(nm, nullAnnot);
3814 for (JvAnnotRow auan : autoAlan)
3816 visan.put(auan.template.label
3817 + (auan.template.getCalcId() == null ? "" : "\t"
3818 + auan.template.getCalcId()), auan);
3820 int hSize = al.getAlignmentAnnotation().length;
3821 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3822 // work through any autoCalculated annotation already on the view
3823 // removing it if it should be placed in a different location on the
3824 // annotation panel.
3825 List<String> remains = new ArrayList(visan.keySet());
3826 for (int h = 0; h < hSize; h++)
3828 jalview.datamodel.AlignmentAnnotation jalan = al
3829 .getAlignmentAnnotation()[h];
3830 if (jalan.autoCalculated)
3833 JvAnnotRow valan = visan.get(k = jalan.label);
3834 if (jalan.getCalcId() != null)
3836 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3841 // delete the auto calculated row from the alignment
3842 al.deleteAnnotation(jalan, false);
3846 if (valan != nullAnnot)
3848 if (jalan != valan.template)
3850 // newly created autoannotation row instance
3851 // so keep a reference to the visible annotation row
3852 // and copy over all relevant attributes
3853 if (valan.template.graphHeight >= 0)
3856 jalan.graphHeight = valan.template.graphHeight;
3858 jalan.visible = valan.template.visible;
3860 reorder.add(new JvAnnotRow(valan.order, jalan));
3865 // Add any (possibly stale) autocalculated rows that were not appended to
3866 // the view during construction
3867 for (String other : remains)
3869 JvAnnotRow othera = visan.get(other);
3870 if (othera != nullAnnot && othera.template.getCalcId() != null
3871 && othera.template.getCalcId().length() > 0)
3873 reorder.add(othera);
3876 // now put the automatic annotation in its correct place
3877 int s = 0, srt[] = new int[reorder.size()];
3878 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3879 for (JvAnnotRow jvar : reorder)
3882 srt[s++] = jvar.order;
3885 jalview.util.QuickSort.sort(srt, rws);
3886 // and re-insert the annotation at its correct position
3887 for (JvAnnotRow jvar : rws)
3889 al.addAnnotation(jvar.template, jvar.order);
3891 af.alignPanel.adjustAnnotationHeight();
3895 Hashtable skipList = null;
3898 * TODO remove this method
3901 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3902 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3903 * throw new Error("Implementation Error. No skipList defined for this
3904 * Jalview2XML instance."); } return (AlignFrame)
3905 * skipList.get(view.getSequenceSetId()); }
3909 * Check if the Jalview view contained in object should be skipped or not.
3912 * @return true if view's sequenceSetId is a key in skipList
3914 private boolean skipViewport(JalviewModel object)
3916 if (skipList == null)
3921 if (skipList.containsKey(id = object.getJalviewModelSequence()
3922 .getViewport()[0].getSequenceSetId()))
3924 if (Cache.log != null && Cache.log.isDebugEnabled())
3926 Cache.log.debug("Skipping seuqence set id " + id);
3933 public void AddToSkipList(AlignFrame af)
3935 if (skipList == null)
3937 skipList = new Hashtable();
3939 skipList.put(af.getViewport().getSequenceSetId(), af);
3942 public void clearSkipList()
3944 if (skipList != null)
3951 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
3952 boolean ignoreUnrefed)
3954 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3955 Vector dseqs = null;
3958 // create a list of new dataset sequences
3959 dseqs = new Vector();
3961 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3963 Sequence vamsasSeq = vamsasSet.getSequence(i);
3964 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
3966 // create a new dataset
3969 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3970 dseqs.copyInto(dsseqs);
3971 ds = new jalview.datamodel.Alignment(dsseqs);
3972 debug("Created new dataset " + vamsasSet.getDatasetId()
3973 + " for alignment " + System.identityHashCode(al));
3974 addDatasetRef(vamsasSet.getDatasetId(), ds);
3976 // set the dataset for the newly imported alignment.
3977 if (al.getDataset() == null && !ignoreUnrefed)
3986 * sequence definition to create/merge dataset sequence for
3990 * vector to add new dataset sequence to
3992 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3993 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
3995 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3997 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3998 .get(vamsasSeq.getId());
3999 jalview.datamodel.SequenceI dsq = null;
4000 if (sq != null && sq.getDatasetSequence() != null)
4002 dsq = sq.getDatasetSequence();
4004 if (sq == null && ignoreUnrefed)
4008 String sqid = vamsasSeq.getDsseqid();
4011 // need to create or add a new dataset sequence reference to this sequence
4014 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
4019 // make a new dataset sequence
4020 dsq = sq.createDatasetSequence();
4023 // make up a new dataset reference for this sequence
4024 sqid = seqHash(dsq);
4026 dsq.setVamsasId(uniqueSetSuffix + sqid);
4027 seqRefIds.put(sqid, dsq);
4032 dseqs.addElement(dsq);
4037 ds.addSequence(dsq);
4043 { // make this dataset sequence sq's dataset sequence
4044 sq.setDatasetSequence(dsq);
4045 // and update the current dataset alignment
4050 if (!dseqs.contains(dsq))
4057 if (ds.findIndex(dsq) < 0)
4059 ds.addSequence(dsq);
4066 // TODO: refactor this as a merge dataset sequence function
4067 // now check that sq (the dataset sequence) sequence really is the union of
4068 // all references to it
4069 // boolean pre = sq.getStart() < dsq.getStart();
4070 // boolean post = sq.getEnd() > dsq.getEnd();
4074 StringBuffer sb = new StringBuffer();
4075 String newres = jalview.analysis.AlignSeq.extractGaps(
4076 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4077 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4078 && newres.length() > dsq.getLength())
4080 // Update with the longer sequence.
4084 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4085 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4086 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4087 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4089 dsq.setSequence(newres);
4091 // TODO: merges will never happen if we 'know' we have the real dataset
4092 // sequence - this should be detected when id==dssid
4094 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4095 // + (pre ? "prepended" : "") + " "
4096 // + (post ? "appended" : ""));
4101 java.util.Hashtable datasetIds = null;
4103 java.util.IdentityHashMap dataset2Ids = null;
4105 private Alignment getDatasetFor(String datasetId)
4107 if (datasetIds == null)
4109 datasetIds = new Hashtable();
4112 if (datasetIds.containsKey(datasetId))
4114 return (Alignment) datasetIds.get(datasetId);
4119 private void addDatasetRef(String datasetId, Alignment dataset)
4121 if (datasetIds == null)
4123 datasetIds = new Hashtable();
4125 datasetIds.put(datasetId, dataset);
4129 * make a new dataset ID for this jalview dataset alignment
4134 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4136 if (dataset.getDataset() != null)
4138 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4140 String datasetId = makeHashCode(dataset, null);
4141 if (datasetId == null)
4143 // make a new datasetId and record it
4144 if (dataset2Ids == null)
4146 dataset2Ids = new IdentityHashMap();
4150 datasetId = (String) dataset2Ids.get(dataset);
4152 if (datasetId == null)
4154 datasetId = "ds" + dataset2Ids.size() + 1;
4155 dataset2Ids.put(dataset, datasetId);
4161 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4163 for (int d = 0; d < sequence.getDBRefCount(); d++)
4165 DBRef dr = sequence.getDBRef(d);
4166 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4167 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4168 .getVersion(), sequence.getDBRef(d).getAccessionId());
4169 if (dr.getMapping() != null)
4171 entry.setMap(addMapping(dr.getMapping()));
4173 datasetSequence.addDBRef(entry);
4177 private jalview.datamodel.Mapping addMapping(Mapping m)
4179 SequenceI dsto = null;
4180 // Mapping m = dr.getMapping();
4181 int fr[] = new int[m.getMapListFromCount() * 2];
4182 Enumeration f = m.enumerateMapListFrom();
4183 for (int _i = 0; f.hasMoreElements(); _i += 2)
4185 MapListFrom mf = (MapListFrom) f.nextElement();
4186 fr[_i] = mf.getStart();
4187 fr[_i + 1] = mf.getEnd();
4189 int fto[] = new int[m.getMapListToCount() * 2];
4190 f = m.enumerateMapListTo();
4191 for (int _i = 0; f.hasMoreElements(); _i += 2)
4193 MapListTo mf = (MapListTo) f.nextElement();
4194 fto[_i] = mf.getStart();
4195 fto[_i + 1] = mf.getEnd();
4197 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4198 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4199 if (m.getMappingChoice() != null)
4201 MappingChoice mc = m.getMappingChoice();
4202 if (mc.getDseqFor() != null)
4204 String dsfor = "" + mc.getDseqFor();
4205 if (seqRefIds.containsKey(dsfor))
4210 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4214 frefedSequence.add(new Object[]
4221 * local sequence definition
4223 Sequence ms = mc.getSequence();
4224 jalview.datamodel.Sequence djs = null;
4225 String sqid = ms.getDsseqid();
4226 if (sqid != null && sqid.length() > 0)
4229 * recover dataset sequence
4231 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4236 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4237 sqid = ((Object) ms).toString(); // make up a new hascode for
4238 // undefined dataset sequence hash
4239 // (unlikely to happen)
4245 * make a new dataset sequence and add it to refIds hash
4247 djs = new jalview.datamodel.Sequence(ms.getName(),
4249 djs.setStart(jmap.getMap().getToLowest());
4250 djs.setEnd(jmap.getMap().getToHighest());
4251 djs.setVamsasId(uniqueSetSuffix + sqid);
4253 seqRefIds.put(sqid, djs);
4256 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4265 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4266 boolean keepSeqRefs)
4269 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4275 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4279 uniqueSetSuffix = "";
4280 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4285 if (this.frefedSequence == null)
4287 frefedSequence = new Vector();
4290 viewportsAdded = new Hashtable();
4292 AlignFrame af = LoadFromObject(jm, null, false, null);
4293 af.alignPanels.clear();
4294 af.closeMenuItem_actionPerformed(true);
4297 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4298 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4299 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4300 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4301 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4304 return af.alignPanel;
4308 * flag indicating if hashtables should be cleared on finalization TODO this
4309 * flag may not be necessary
4311 private final boolean _cleartables = true;
4313 private Hashtable jvids2vobj;
4318 * @see java.lang.Object#finalize()
4321 protected void finalize() throws Throwable
4323 // really make sure we have no buried refs left.
4328 this.seqRefIds = null;
4329 this.seqsToIds = null;
4333 private void warn(String msg)
4338 private void warn(String msg, Exception e)
4340 if (Cache.log != null)
4344 Cache.log.warn(msg, e);
4348 Cache.log.warn(msg);
4353 System.err.println("Warning: " + msg);
4356 e.printStackTrace();
4361 private void debug(String string)
4363 debug(string, null);
4366 private void debug(String msg, Exception e)
4368 if (Cache.log != null)
4372 Cache.log.debug(msg, e);
4376 Cache.log.debug(msg);
4381 System.err.println("Warning: " + msg);
4384 e.printStackTrace();
4390 * set the object to ID mapping tables used to write/recover objects and XML
4391 * ID strings for the jalview project. If external tables are provided then
4392 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4393 * object goes out of scope. - also populates the datasetIds hashtable with
4394 * alignment objects containing dataset sequences
4397 * Map from ID strings to jalview datamodel
4399 * Map from jalview datamodel to ID strings
4403 public void setObjectMappingTables(Hashtable vobj2jv,
4404 IdentityHashMap jv2vobj)
4406 this.jv2vobj = jv2vobj;
4407 this.vobj2jv = vobj2jv;
4408 Iterator ds = jv2vobj.keySet().iterator();
4410 while (ds.hasNext())
4412 Object jvobj = ds.next();
4413 id = jv2vobj.get(jvobj).toString();
4414 if (jvobj instanceof jalview.datamodel.Alignment)
4416 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4418 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4421 else if (jvobj instanceof jalview.datamodel.Sequence)
4423 // register sequence object so the XML parser can recover it.
4424 if (seqRefIds == null)
4426 seqRefIds = new Hashtable();
4428 if (seqsToIds == null)
4430 seqsToIds = new IdentityHashMap();
4432 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4433 seqsToIds.put(jvobj, id);
4435 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4437 if (annotationIds == null)
4439 annotationIds = new Hashtable();
4442 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4443 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4444 if (jvann.annotationId == null)
4446 jvann.annotationId = anid;
4448 if (!jvann.annotationId.equals(anid))
4450 // TODO verify that this is the correct behaviour
4451 this.warn("Overriding Annotation ID for " + anid
4452 + " from different id : " + jvann.annotationId);
4453 jvann.annotationId = anid;
4456 else if (jvobj instanceof String)
4458 if (jvids2vobj == null)
4460 jvids2vobj = new Hashtable();
4461 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4466 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4472 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4473 * objects created from the project archive. If string is null (default for
4474 * construction) then suffix will be set automatically.
4478 public void setUniqueSetSuffix(String string)
4480 uniqueSetSuffix = string;
4485 * uses skipList2 as the skipList for skipping views on sequence sets
4486 * associated with keys in the skipList
4490 public void setSkipList(Hashtable skipList2)
4492 skipList = skipList2;