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.HashMap;
96 import java.util.HashSet;
97 import java.util.Hashtable;
98 import java.util.IdentityHashMap;
99 import java.util.Iterator;
100 import java.util.List;
101 import java.util.Map;
102 import java.util.Map.Entry;
103 import java.util.Set;
104 import java.util.StringTokenizer;
105 import java.util.Vector;
106 import java.util.jar.JarEntry;
107 import java.util.jar.JarInputStream;
108 import java.util.jar.JarOutputStream;
110 import javax.swing.JInternalFrame;
111 import javax.swing.JOptionPane;
112 import javax.swing.SwingUtilities;
114 import org.exolab.castor.xml.Unmarshaller;
117 * Write out the current jalview desktop state as a Jalview XML stream.
119 * Note: the vamsas objects referred to here are primitive versions of the
120 * VAMSAS project schema elements - they are not the same and most likely never
124 * @version $Revision: 1.134 $
126 public class Jalview2XML
129 * create/return unique hash string for sq
132 * @return new or existing unique string for sq
134 String seqHash(SequenceI sq)
136 if (seqsToIds == null)
140 if (seqsToIds.containsKey(sq))
142 return (String) seqsToIds.get(sq);
146 // create sequential key
147 String key = "sq" + (seqsToIds.size() + 1);
148 key = makeHashCode(sq, key); // check we don't have an external reference
150 seqsToIds.put(sq, key);
159 if (seqRefIds != null)
163 if (seqsToIds != null)
173 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
174 // seqRefIds = new Hashtable();
175 // seqsToIds = new IdentityHashMap();
181 if (seqsToIds == null)
183 seqsToIds = new IdentityHashMap();
185 if (seqRefIds == null)
187 seqRefIds = new HashMap<String, SequenceI>();
192 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
193 * of sequence objects are created.
195 java.util.IdentityHashMap seqsToIds = null;
198 * jalview XML Sequence ID to jalview sequence object reference (both dataset
199 * and alignment sequences. Populated as XML reps of sequence objects are
202 Map<String, SequenceI> seqRefIds = null; // key->SequenceI resolution
205 * Forward referenced sequences - a holding place for cross-references pending
208 Vector frefedSequence = null;
210 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
216 public Jalview2XML(boolean raiseGUI)
218 this.raiseGUI = raiseGUI;
221 public void resolveFrefedSequences()
223 if (frefedSequence.size() > 0)
225 int r = 0, rSize = frefedSequence.size();
228 Object[] ref = (Object[]) frefedSequence.elementAt(r);
231 String sref = (String) ref[0];
232 if (seqRefIds.containsKey(sref))
234 if (ref[1] instanceof jalview.datamodel.Mapping)
236 SequenceI seq = seqRefIds.get(sref);
237 while (seq.getDatasetSequence() != null)
239 seq = seq.getDatasetSequence();
241 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
245 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
247 SequenceI seq = seqRefIds.get(sref);
248 while (seq.getDatasetSequence() != null)
250 seq = seq.getDatasetSequence();
253 && ref[2] instanceof jalview.datamodel.Mapping)
255 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
256 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
257 seq, mp.getTo(), mp.getMap());
262 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
263 + ref[2].getClass() + " type objects.");
269 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
270 + ref[1].getClass() + " type objects.");
273 frefedSequence.remove(r);
279 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
281 + " with objecttype "
282 + ref[1].getClass());
289 frefedSequence.remove(r);
297 * This maintains a list of viewports, the key being the seqSetId. Important
298 * to set historyItem and redoList for multiple views
300 Hashtable viewportsAdded;
302 Hashtable annotationIds = new Hashtable();
304 String uniqueSetSuffix = "";
307 * List of pdbfiles added to Jar
309 Vector pdbfiles = null;
311 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
312 public void SaveState(File statefile)
316 FileOutputStream fos = new FileOutputStream(statefile);
317 JarOutputStream jout = new JarOutputStream(fos);
320 } catch (Exception e)
322 // TODO: inform user of the problem - they need to know if their data was
324 if (errorMessage == null)
326 errorMessage = "Couldn't write Jalview Archive to output file '"
327 + statefile + "' - See console error log for details";
331 errorMessage += "(output file was '" + statefile + "')";
339 * Writes a jalview project archive to the given Jar output stream.
343 public void SaveState(JarOutputStream jout)
345 AlignFrame[] frames = Desktop.getAlignFrames(); // Desktop.desktop.getAllFrames();
352 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
357 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
358 // //////////////////////////////////////////////////
359 // NOTE ALSO new PrintWriter must be used for each new JarEntry
360 PrintWriter out = null;
362 List<String> shortNames = new ArrayList<String>();
365 for (int i = frames.length - 1; i > -1; i--)
367 AlignFrame af = frames[i];
371 .containsKey(af.getViewport().getSequenceSetId()))
376 String shortName = af.getTitle();
378 if (shortName.indexOf(File.separatorChar) > -1)
380 shortName = shortName.substring(shortName
381 .lastIndexOf(File.separatorChar) + 1);
386 while (shortNames.contains(shortName))
388 if (shortName.endsWith("_" + (count - 1)))
390 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
393 shortName = shortName.concat("_" + count);
397 shortNames.add(shortName);
399 if (!shortName.endsWith(".xml"))
401 shortName = shortName + ".xml";
404 int apSize = af.alignPanels.size();
406 for (int ap = 0; ap < apSize; ap++)
408 AlignmentPanel apanel = af.alignPanels.get(ap);
409 String fileName = apSize == 1 ? shortName : ap + shortName;
410 if (!fileName.endsWith(".xml"))
412 fileName = fileName + ".xml";
415 SaveState(apanel, fileName, jout);
417 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
419 if (!dsses.containsKey(dssid))
421 dsses.put(dssid, af);
426 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
432 } catch (Exception foo)
437 } catch (Exception ex)
439 // TODO: inform user of the problem - they need to know if their data was
441 if (errorMessage == null)
443 errorMessage = "Couldn't write Jalview Archive - see error output for details";
445 ex.printStackTrace();
449 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
450 public boolean SaveAlignment(AlignFrame af, String jarFile,
455 int ap, apSize = af.alignPanels.size();
456 FileOutputStream fos = new FileOutputStream(jarFile);
457 JarOutputStream jout = new JarOutputStream(fos);
458 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
459 for (ap = 0; ap < apSize; ap++)
461 AlignmentPanel apanel = af.alignPanels
463 String jfileName = apSize == 1 ? fileName : fileName + ap;
464 if (!jfileName.endsWith(".xml"))
466 jfileName = jfileName + ".xml";
468 SaveState(apanel, jfileName, jout);
469 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
471 if (!dsses.containsKey(dssid))
473 dsses.put(dssid, af);
476 writeDatasetFor(dsses, fileName, jout);
480 } catch (Exception foo)
486 } catch (Exception ex)
488 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
489 ex.printStackTrace();
494 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
495 String fileName, JarOutputStream jout)
498 for (String dssids : dsses.keySet())
500 AlignFrame _af = dsses.get(dssids);
501 String jfileName = fileName + " Dataset for " + _af.getTitle();
502 if (!jfileName.endsWith(".xml"))
504 jfileName = jfileName + ".xml";
506 SaveState(_af.alignPanel, jfileName, true, jout);
511 * create a JalviewModel from an algnment view and marshall it to a
515 * panel to create jalview model for
517 * name of alignment panel written to output stream
523 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
524 JarOutputStream jout)
526 return SaveState(ap, fileName, false, jout);
530 * create a JalviewModel from an algnment view and marshall it to a
534 * panel to create jalview model for
536 * name of alignment panel written to output stream
538 * when true, only write the dataset for the alignment, not the data
539 * associated with the view.
545 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
546 boolean storeDS, JarOutputStream jout)
549 Vector jmolViewIds = new Vector(); //
550 Vector userColours = new Vector();
552 AlignViewport av = ap.av;
554 JalviewModel object = new JalviewModel();
555 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
557 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
558 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
559 "Development Build"));
561 jalview.datamodel.AlignmentI jal = av.getAlignment();
563 if (av.hasHiddenRows())
565 jal = jal.getHiddenSequences().getFullAlignment();
568 SequenceSet vamsasSet = new SequenceSet();
570 JalviewModelSequence jms = new JalviewModelSequence();
572 vamsasSet.setGapChar(jal.getGapCharacter() + "");
574 if (jal.getDataset() != null)
576 // dataset id is the dataset's hashcode
577 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
580 // switch jal and the dataset
581 jal = jal.getDataset();
584 if (jal.getProperties() != null)
586 Enumeration en = jal.getProperties().keys();
587 while (en.hasMoreElements())
589 String key = en.nextElement().toString();
590 SequenceSetProperties ssp = new SequenceSetProperties();
592 ssp.setValue(jal.getProperties().get(key).toString());
593 vamsasSet.addSequenceSetProperties(ssp);
598 Set<String> calcIdSet = new HashSet<String>();
602 jalview.datamodel.SequenceI jds, jdatasq;
603 for (int i = 0; i < jal.getHeight(); i++)
605 jds = jal.getSequenceAt(i);
606 jdatasq = jds.getDatasetSequence() == null ? jds : jds
607 .getDatasetSequence();
610 if (seqRefIds.get(id) != null)
612 // This happens for two reasons: 1. multiple views are being serialised.
613 // 2. the hashCode has collided with another sequence's code. This DOES
614 // HAPPEN! (PF00072.15.stk does this)
615 // JBPNote: Uncomment to debug writing out of files that do not read
616 // back in due to ArrayOutOfBoundExceptions.
617 // System.err.println("vamsasSeq backref: "+id+"");
618 // System.err.println(jds.getName()+"
619 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
620 // System.err.println("Hashcode: "+seqHash(jds));
621 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
622 // System.err.println(rsq.getName()+"
623 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
624 // System.err.println("Hashcode: "+seqHash(rsq));
628 vamsasSeq = createVamsasSequence(id, jds);
629 vamsasSet.addSequence(vamsasSeq);
630 seqRefIds.put(id, jds);
634 jseq.setStart(jds.getStart());
635 jseq.setEnd(jds.getEnd());
636 jseq.setColour(av.getSequenceColour(jds).getRGB());
638 jseq.setId(id); // jseq id should be a string not a number
641 // Store any sequences this sequence represents
642 if (av.hasHiddenRows())
644 jseq.setHidden(av.getAlignment().getHiddenSequences()
647 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
649 jalview.datamodel.SequenceI[] reps = av
650 .getRepresentedSequences(jal.getSequenceAt(i))
651 .getSequencesInOrder(jal);
653 for (int h = 0; h < reps.length; h++)
655 if (reps[h] != jal.getSequenceAt(i))
657 jseq.addHiddenSequences(jal.findIndex(reps[h]));
664 if (jdatasq.getSequenceFeatures() != null)
666 jalview.datamodel.SequenceFeature[] sf = jdatasq
667 .getSequenceFeatures();
669 while (index < sf.length)
671 Features features = new Features();
673 features.setBegin(sf[index].getBegin());
674 features.setEnd(sf[index].getEnd());
675 features.setDescription(sf[index].getDescription());
676 features.setType(sf[index].getType());
677 features.setFeatureGroup(sf[index].getFeatureGroup());
678 features.setScore(sf[index].getScore());
679 if (sf[index].links != null)
681 for (int l = 0; l < sf[index].links.size(); l++)
683 OtherData keyValue = new OtherData();
684 keyValue.setKey("LINK_" + l);
685 keyValue.setValue(sf[index].links.elementAt(l).toString());
686 features.addOtherData(keyValue);
689 if (sf[index].otherDetails != null)
692 Enumeration keys = sf[index].otherDetails.keys();
693 while (keys.hasMoreElements())
695 key = keys.nextElement().toString();
696 OtherData keyValue = new OtherData();
697 keyValue.setKey(key);
698 keyValue.setValue(sf[index].otherDetails.get(key).toString());
699 features.addOtherData(keyValue);
703 jseq.addFeatures(features);
708 if (jdatasq.getPDBId() != null)
710 Enumeration en = jdatasq.getPDBId().elements();
711 while (en.hasMoreElements())
713 Pdbids pdb = new Pdbids();
714 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
717 pdb.setId(entry.getId());
718 pdb.setType(entry.getType());
720 // store any JMol views associated with this seqeunce
721 // this section copes with duplicate entries in the project, so a
722 // dataset only view *should* be coped with sensibly
724 // This must have been loaded, is it still visible?
725 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
726 String matchedFile = null;
727 for (int f = frames.length - 1; f > -1; f--)
729 if (frames[f] instanceof AppJmol)
731 jmol = (AppJmol) frames[f];
732 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
734 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
735 && !(entry.getId().length() > 4 && entry
739 jmol.jmb.pdbentry[peid].getId()
744 if (matchedFile == null)
746 matchedFile = jmol.jmb.pdbentry[peid].getFile();
748 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
752 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
753 + jmol.jmb.pdbentry[peid].getFile());
757 // can get at it if the ID
758 // match is ambiguous (e.g.
760 String statestring = jmol.jmb.viewer.getStateInfo();
762 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
764 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
765 if (jds == jmol.jmb.sequence[peid][smap])
767 StructureState state = new StructureState();
768 state.setVisible(true);
769 state.setXpos(jmol.getX());
770 state.setYpos(jmol.getY());
771 state.setWidth(jmol.getWidth());
772 state.setHeight(jmol.getHeight());
773 state.setViewId(jmol.getViewId());
774 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
775 state.setColourwithAlignPanel(jmol
776 .isUsedforcolourby(ap));
777 state.setColourByJmol(jmol.isColouredByJmol());
778 if (!jmolViewIds.contains(state.getViewId()))
780 // Make sure we only store a Jmol state once in each XML
782 jmolViewIds.addElement(state.getViewId());
783 state.setContent(statestring.replaceAll("\n", ""));
787 state.setContent("# duplicate state");
789 pdb.addStructureState(state);
797 if (matchedFile != null || entry.getFile() != null)
799 if (entry.getFile() != null)
802 matchedFile = entry.getFile();
804 pdb.setFile(matchedFile); // entry.getFile());
805 if (pdbfiles == null)
807 pdbfiles = new Vector();
810 if (!pdbfiles.contains(entry.getId()))
812 pdbfiles.addElement(entry.getId());
815 File file = new File(matchedFile);
816 if (file.exists() && jout != null)
818 byte[] data = new byte[(int) file.length()];
819 jout.putNextEntry(new JarEntry(entry.getId()));
820 DataInputStream dis = new DataInputStream(
821 new FileInputStream(file));
824 DataOutputStream dout = new DataOutputStream(jout);
825 dout.write(data, 0, data.length);
829 } catch (Exception ex)
831 ex.printStackTrace();
837 if (entry.getProperty() != null)
839 PdbentryItem item = new PdbentryItem();
840 Hashtable properties = entry.getProperty();
841 Enumeration en2 = properties.keys();
842 while (en2.hasMoreElements())
844 Property prop = new Property();
845 String key = en2.nextElement().toString();
847 prop.setValue(properties.get(key).toString());
848 item.addProperty(prop);
850 pdb.addPdbentryItem(item);
860 if (!storeDS && av.hasHiddenRows())
862 jal = av.getAlignment();
865 Set<AlignedCodonFrame> jac = jal.getCodonFrames();
868 for (AlignedCodonFrame acf : jac)
870 AlcodonFrame alc = new AlcodonFrame();
871 vamsasSet.addAlcodonFrame(alc);
872 if (acf.getProtMappings() != null
873 && acf.getProtMappings().length > 0)
875 SequenceI[] dnas = acf.getdnaSeqs();
876 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
877 for (int m = 0; m < pmaps.length; m++)
879 AlcodMap alcmap = new AlcodMap();
880 alcmap.setDnasq(seqHash(dnas[m]));
881 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
883 alc.addAlcodMap(alcmap);
890 // /////////////////////////////////
891 if (!storeDS && av.currentTree != null)
893 // FIND ANY ASSOCIATED TREES
894 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
895 if (Desktop.desktop != null)
897 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
899 for (int t = 0; t < frames.length; t++)
901 if (frames[t] instanceof TreePanel)
903 TreePanel tp = (TreePanel) frames[t];
905 if (tp.treeCanvas.av.getAlignment() == jal)
907 Tree tree = new Tree();
908 tree.setTitle(tp.getTitle());
909 tree.setCurrentTree((av.currentTree == tp.getTree()));
910 tree.setNewick(tp.getTree().toString());
911 tree.setThreshold(tp.treeCanvas.threshold);
913 tree.setFitToWindow(tp.fitToWindow.getState());
914 tree.setFontName(tp.getTreeFont().getName());
915 tree.setFontSize(tp.getTreeFont().getSize());
916 tree.setFontStyle(tp.getTreeFont().getStyle());
917 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
919 tree.setShowBootstrap(tp.bootstrapMenu.getState());
920 tree.setShowDistances(tp.distanceMenu.getState());
922 tree.setHeight(tp.getHeight());
923 tree.setWidth(tp.getWidth());
924 tree.setXpos(tp.getX());
925 tree.setYpos(tp.getY());
926 tree.setId(makeHashCode(tp, null));
935 * store forward refs from an annotationRow to any groups
937 IdentityHashMap groupRefs = new IdentityHashMap();
940 for (SequenceI sq : jal.getSequences())
942 // Store annotation on dataset sequences only
943 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
944 if (aa != null && aa.length > 0)
946 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
953 if (jal.getAlignmentAnnotation() != null)
955 // Store the annotation shown on the alignment.
956 jalview.datamodel.AlignmentAnnotation[] aa = jal
957 .getAlignmentAnnotation();
958 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
963 if (jal.getGroups() != null)
965 JGroup[] groups = new JGroup[jal.getGroups().size()];
967 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
969 groups[++i] = new JGroup();
971 groups[i].setStart(sg.getStartRes());
972 groups[i].setEnd(sg.getEndRes());
973 groups[i].setName(sg.getName());
974 if (groupRefs.containsKey(sg))
976 // group has references so set it's ID field
977 groups[i].setId(groupRefs.get(sg).toString());
981 if (sg.cs.conservationApplied())
983 groups[i].setConsThreshold(sg.cs.getConservationInc());
985 if (sg.cs instanceof jalview.schemes.UserColourScheme)
987 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
993 .setColour(ColourSchemeProperty.getColourName(sg.cs));
996 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
998 groups[i].setColour("AnnotationColourGradient");
999 groups[i].setAnnotationColours(constructAnnotationColours(
1000 (jalview.schemes.AnnotationColourGradient) sg.cs,
1003 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1006 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
1010 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1013 groups[i].setPidThreshold(sg.cs.getThreshold());
1016 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1017 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1018 groups[i].setDisplayText(sg.getDisplayText());
1019 groups[i].setColourText(sg.getColourText());
1020 groups[i].setTextCol1(sg.textColour.getRGB());
1021 groups[i].setTextCol2(sg.textColour2.getRGB());
1022 groups[i].setTextColThreshold(sg.thresholdTextColour);
1023 groups[i].setShowUnconserved(sg.getShowNonconserved());
1024 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1025 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1026 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1027 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1028 for (int s = 0; s < sg.getSize(); s++)
1030 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1032 groups[i].addSeq(seqHash(seq));
1036 jms.setJGroup(groups);
1040 // /////////SAVE VIEWPORT
1041 Viewport view = new Viewport();
1042 view.setTitle(ap.alignFrame.getTitle());
1043 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1044 av.getSequenceSetId()));
1045 view.setId(av.getViewId());
1046 view.setViewName(av.viewName);
1047 view.setGatheredViews(av.gatherViewsHere);
1049 if (ap.av.explodedPosition != null)
1051 view.setXpos(av.explodedPosition.x);
1052 view.setYpos(av.explodedPosition.y);
1053 view.setWidth(av.explodedPosition.width);
1054 view.setHeight(av.explodedPosition.height);
1058 view.setXpos(ap.alignFrame.getBounds().x);
1059 view.setYpos(ap.alignFrame.getBounds().y);
1060 view.setWidth(ap.alignFrame.getBounds().width);
1061 view.setHeight(ap.alignFrame.getBounds().height);
1064 view.setStartRes(av.startRes);
1065 view.setStartSeq(av.startSeq);
1067 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1069 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1072 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1074 AnnotationColours ac = constructAnnotationColours(
1075 (jalview.schemes.AnnotationColourGradient) av
1076 .getGlobalColourScheme(),
1079 view.setAnnotationColours(ac);
1080 view.setBgColour("AnnotationColourGradient");
1084 view.setBgColour(ColourSchemeProperty.getColourName(av
1085 .getGlobalColourScheme()));
1088 ColourSchemeI cs = av.getGlobalColourScheme();
1092 if (cs.conservationApplied())
1094 view.setConsThreshold(cs.getConservationInc());
1095 if (cs instanceof jalview.schemes.UserColourScheme)
1097 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1101 if (cs instanceof ResidueColourScheme)
1103 view.setPidThreshold(cs.getThreshold());
1107 view.setConservationSelected(av.getConservationSelected());
1108 view.setPidSelected(av.getAbovePIDThreshold());
1109 view.setFontName(av.font.getName());
1110 view.setFontSize(av.font.getSize());
1111 view.setFontStyle(av.font.getStyle());
1112 view.setRenderGaps(av.renderGaps);
1113 view.setShowAnnotation(av.getShowAnnotation());
1114 view.setShowBoxes(av.getShowBoxes());
1115 view.setShowColourText(av.getColourText());
1116 view.setShowFullId(av.getShowJVSuffix());
1117 view.setRightAlignIds(av.rightAlignIds);
1118 view.setShowSequenceFeatures(av.showSequenceFeatures);
1119 view.setShowText(av.getShowText());
1120 view.setShowUnconserved(av.getShowUnconserved());
1121 view.setWrapAlignment(av.getWrapAlignment());
1122 view.setTextCol1(av.textColour.getRGB());
1123 view.setTextCol2(av.textColour2.getRGB());
1124 view.setTextColThreshold(av.thresholdTextColour);
1125 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1126 view.setShowSequenceLogo(av.isShowSequenceLogo());
1127 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1128 view.setShowGroupConsensus(av.isShowGroupConsensus());
1129 view.setShowGroupConservation(av.isShowGroupConservation());
1130 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1131 view.setShowDbRefTooltip(av.isShowDbRefs());
1132 view.setFollowHighlight(av.followHighlight);
1133 view.setFollowSelection(av.followSelection);
1134 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1135 if (av.featuresDisplayed != null)
1137 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1139 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1141 Vector settingsAdded = new Vector();
1142 Object gstyle = null;
1143 GraduatedColor gcol = null;
1144 if (renderOrder != null)
1146 for (int ro = 0; ro < renderOrder.length; ro++)
1148 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1149 .getFeatureStyle(renderOrder[ro]);
1150 Setting setting = new Setting();
1151 setting.setType(renderOrder[ro]);
1152 if (gstyle instanceof GraduatedColor)
1154 gcol = (GraduatedColor) gstyle;
1155 setting.setColour(gcol.getMaxColor().getRGB());
1156 setting.setMincolour(gcol.getMinColor().getRGB());
1157 setting.setMin(gcol.getMin());
1158 setting.setMax(gcol.getMax());
1159 setting.setColourByLabel(gcol.isColourByLabel());
1160 setting.setAutoScale(gcol.isAutoScale());
1161 setting.setThreshold(gcol.getThresh());
1162 setting.setThreshstate(gcol.getThreshType());
1166 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1167 .getColour(renderOrder[ro]).getRGB());
1170 setting.setDisplay(av.featuresDisplayed
1171 .containsKey(renderOrder[ro]));
1172 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1173 .getOrder(renderOrder[ro]);
1176 setting.setOrder(rorder);
1178 fs.addSetting(setting);
1179 settingsAdded.addElement(renderOrder[ro]);
1183 // Make sure we save none displayed feature settings
1184 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1185 .keySet().iterator();
1186 while (en.hasNext())
1188 String key = en.next().toString();
1189 if (settingsAdded.contains(key))
1194 Setting setting = new Setting();
1195 setting.setType(key);
1196 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1197 .getColour(key).getRGB());
1199 setting.setDisplay(false);
1200 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1204 setting.setOrder(rorder);
1206 fs.addSetting(setting);
1207 settingsAdded.addElement(key);
1209 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1210 .keySet().iterator();
1211 Vector groupsAdded = new Vector();
1212 while (en.hasNext())
1214 String grp = en.next().toString();
1215 if (groupsAdded.contains(grp))
1219 Group g = new Group();
1221 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas
1222 .getFeatureRenderer().featureGroups.get(grp))
1225 groupsAdded.addElement(grp);
1227 jms.setFeatureSettings(fs);
1231 if (av.hasHiddenColumns())
1233 if (av.getColumnSelection() == null
1234 || av.getColumnSelection().getHiddenColumns() == null)
1236 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1240 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1243 int[] region = av.getColumnSelection().getHiddenColumns()
1245 HiddenColumns hc = new HiddenColumns();
1246 hc.setStart(region[0]);
1247 hc.setEnd(region[1]);
1248 view.addHiddenColumns(hc);
1252 if (calcIdSet.size() > 0)
1254 for (String calcId : calcIdSet)
1256 if (calcId.trim().length() > 0)
1258 CalcIdParam cidp = createCalcIdParam(calcId, av);
1259 // Some calcIds have no parameters.
1262 view.addCalcIdParam(cidp);
1268 jms.addViewport(view);
1270 object.setJalviewModelSequence(jms);
1271 object.getVamsasModel().addSequenceSet(vamsasSet);
1273 if (jout != null && fileName != null)
1275 // We may not want to write the object to disk,
1276 // eg we can copy the alignViewport to a new view object
1277 // using save and then load
1280 JarEntry entry = new JarEntry(fileName);
1281 jout.putNextEntry(entry);
1282 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1284 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1286 marshaller.marshal(object);
1289 } catch (Exception ex)
1291 // TODO: raise error in GUI if marshalling failed.
1292 ex.printStackTrace();
1298 private AnnotationColours constructAnnotationColours(
1299 AnnotationColourGradient acg, Vector userColours,
1300 JalviewModelSequence jms)
1302 AnnotationColours ac = new AnnotationColours();
1303 ac.setAboveThreshold(acg.getAboveThreshold());
1304 ac.setThreshold(acg.getAnnotationThreshold());
1305 ac.setAnnotation(acg.getAnnotation());
1306 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1308 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1313 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1317 ac.setMaxColour(acg.getMaxColour().getRGB());
1318 ac.setMinColour(acg.getMinColour().getRGB());
1319 ac.setPerSequence(acg.isSeqAssociated());
1320 ac.setPredefinedColours(acg.isPredefinedColours());
1324 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1325 IdentityHashMap groupRefs, AlignmentViewport av,
1326 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1329 for (int i = 0; i < aa.length; i++)
1331 Annotation an = new Annotation();
1333 if (aa[i].annotationId != null)
1335 annotationIds.put(aa[i].annotationId, aa[i]);
1338 an.setId(aa[i].annotationId);
1340 an.setVisible(aa[i].visible);
1342 an.setDescription(aa[i].description);
1344 if (aa[i].sequenceRef != null)
1346 // TODO later annotation sequenceRef should be the XML ID of the
1347 // sequence rather than its display name
1348 an.setSequenceRef(aa[i].sequenceRef.getName());
1350 if (aa[i].groupRef != null)
1352 Object groupIdr = groupRefs.get(aa[i].groupRef);
1353 if (groupIdr == null)
1355 // make a locally unique String
1356 groupRefs.put(aa[i].groupRef,
1357 groupIdr = ("" + System.currentTimeMillis()
1358 + aa[i].groupRef.getName() + groupRefs.size()));
1360 an.setGroupRef(groupIdr.toString());
1363 // store all visualization attributes for annotation
1364 an.setGraphHeight(aa[i].graphHeight);
1365 an.setCentreColLabels(aa[i].centreColLabels);
1366 an.setScaleColLabels(aa[i].scaleColLabel);
1367 an.setShowAllColLabels(aa[i].showAllColLabels);
1368 an.setBelowAlignment(aa[i].belowAlignment);
1370 if (aa[i].graph > 0)
1373 an.setGraphType(aa[i].graph);
1374 an.setGraphGroup(aa[i].graphGroup);
1375 if (aa[i].getThreshold() != null)
1377 ThresholdLine line = new ThresholdLine();
1378 line.setLabel(aa[i].getThreshold().label);
1379 line.setValue(aa[i].getThreshold().value);
1380 line.setColour(aa[i].getThreshold().colour.getRGB());
1381 an.setThresholdLine(line);
1389 an.setLabel(aa[i].label);
1391 if (aa[i] == av.getAlignmentQualityAnnot()
1392 || aa[i] == av.getAlignmentConservationAnnotation()
1393 || aa[i] == av.getAlignmentConsensusAnnotation()
1394 || aa[i].autoCalculated)
1396 // new way of indicating autocalculated annotation -
1397 an.setAutoCalculated(aa[i].autoCalculated);
1399 if (aa[i].hasScore())
1401 an.setScore(aa[i].getScore());
1404 if (aa[i].getCalcId() != null)
1406 calcIdSet.add(aa[i].getCalcId());
1407 an.setCalcId(aa[i].getCalcId());
1409 if (aa[i].hasProperties())
1411 for (String pr : aa[i].getProperties())
1413 Property prop = new Property();
1415 prop.setValue(aa[i].getProperty(pr));
1416 an.addProperty(prop);
1419 AnnotationElement ae;
1420 if (aa[i].annotations != null)
1422 an.setScoreOnly(false);
1423 for (int a = 0; a < aa[i].annotations.length; a++)
1425 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1430 ae = new AnnotationElement();
1431 if (aa[i].annotations[a].description != null)
1433 ae.setDescription(aa[i].annotations[a].description);
1435 if (aa[i].annotations[a].displayCharacter != null)
1437 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1440 if (!Float.isNaN(aa[i].annotations[a].value))
1442 ae.setValue(aa[i].annotations[a].value);
1446 if (aa[i].annotations[a].secondaryStructure > ' ')
1448 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1452 if (aa[i].annotations[a].colour != null
1453 && aa[i].annotations[a].colour != java.awt.Color.black)
1455 ae.setColour(aa[i].annotations[a].colour.getRGB());
1458 an.addAnnotationElement(ae);
1459 if (aa[i].autoCalculated)
1461 // only write one non-null entry into the annotation row -
1462 // sufficient to get the visualization attributes necessary to
1470 an.setScoreOnly(true);
1472 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1474 // skip autocalculated annotation - these are only provided for
1476 vamsasSet.addAnnotation(an);
1482 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1484 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1485 if (settings != null)
1487 CalcIdParam vCalcIdParam = new CalcIdParam();
1488 vCalcIdParam.setCalcId(calcId);
1489 vCalcIdParam.addServiceURL(settings.getServiceURI());
1490 // generic URI allowing a third party to resolve another instance of the
1491 // service used for this calculation
1492 for (String urls : settings.getServiceURLs())
1494 vCalcIdParam.addServiceURL(urls);
1496 vCalcIdParam.setVersion("1.0");
1497 if (settings.getPreset() != null)
1499 WsParamSetI setting = settings.getPreset();
1500 vCalcIdParam.setName(setting.getName());
1501 vCalcIdParam.setDescription(setting.getDescription());
1505 vCalcIdParam.setName("");
1506 vCalcIdParam.setDescription("Last used parameters");
1508 // need to be able to recover 1) settings 2) user-defined presets or
1509 // recreate settings from preset 3) predefined settings provided by
1510 // service - or settings that can be transferred (or discarded)
1511 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1513 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1514 // todo - decide if updateImmediately is needed for any projects.
1516 return vCalcIdParam;
1521 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1524 if (calcIdParam.getVersion().equals("1.0"))
1526 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1527 .getPreferredServiceFor(calcIdParam.getServiceURL());
1528 if (service != null)
1530 WsParamSetI parmSet = null;
1533 parmSet = service.getParamStore().parseServiceParameterFile(
1534 calcIdParam.getName(), calcIdParam.getDescription(),
1535 calcIdParam.getServiceURL(),
1536 calcIdParam.getParameters().replace("|\\n|", "\n"));
1537 } catch (IOException x)
1539 warn("Couldn't parse parameter data for "
1540 + calcIdParam.getCalcId(), x);
1543 List<ArgumentI> argList = null;
1544 if (calcIdParam.getName().length() > 0)
1546 parmSet = service.getParamStore()
1547 .getPreset(calcIdParam.getName());
1548 if (parmSet != null)
1550 // TODO : check we have a good match with settings in AACon -
1551 // otherwise we'll need to create a new preset
1556 argList = parmSet.getArguments();
1559 AAConSettings settings = new AAConSettings(
1560 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1561 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1562 calcIdParam.isNeedsUpdate());
1567 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1571 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1575 * External mapping between jalview objects and objects yielding a valid and
1576 * unique object ID string. This is null for normal Jalview project IO, but
1577 * non-null when a jalview project is being read or written as part of a
1580 IdentityHashMap jv2vobj = null;
1583 * Construct a unique ID for jvobj using either existing bindings or if none
1584 * exist, the result of the hashcode call for the object.
1587 * jalview data object
1588 * @return unique ID for referring to jvobj
1590 private String makeHashCode(Object jvobj, String altCode)
1592 if (jv2vobj != null)
1594 Object id = jv2vobj.get(jvobj);
1597 return id.toString();
1599 // check string ID mappings
1600 if (jvids2vobj != null && jvobj instanceof String)
1602 id = jvids2vobj.get(jvobj);
1606 return id.toString();
1608 // give up and warn that something has gone wrong
1609 warn("Cannot find ID for object in external mapping : " + jvobj);
1615 * return local jalview object mapped to ID, if it exists
1619 * @return null or object bound to idcode
1621 private Object retrieveExistingObj(String idcode)
1623 if (idcode != null && vobj2jv != null)
1625 return vobj2jv.get(idcode);
1631 * binding from ID strings from external mapping table to jalview data model
1634 private Hashtable vobj2jv;
1636 private Sequence createVamsasSequence(String id, SequenceI jds)
1638 return createVamsasSequence(true, id, jds, null);
1641 private Sequence createVamsasSequence(boolean recurse, String id,
1642 SequenceI jds, SequenceI parentseq)
1644 Sequence vamsasSeq = new Sequence();
1645 vamsasSeq.setId(id);
1646 vamsasSeq.setName(jds.getName());
1647 vamsasSeq.setSequence(jds.getSequenceAsString());
1648 vamsasSeq.setDescription(jds.getDescription());
1649 jalview.datamodel.DBRefEntry[] dbrefs = null;
1650 if (jds.getDatasetSequence() != null)
1652 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1653 if (jds.getDatasetSequence().getDBRef() != null)
1655 dbrefs = jds.getDatasetSequence().getDBRef();
1660 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1661 // dataset sequences only
1662 dbrefs = jds.getDBRef();
1666 for (int d = 0; d < dbrefs.length; d++)
1668 DBRef dbref = new DBRef();
1669 dbref.setSource(dbrefs[d].getSource());
1670 dbref.setVersion(dbrefs[d].getVersion());
1671 dbref.setAccessionId(dbrefs[d].getAccessionId());
1672 if (dbrefs[d].hasMap())
1674 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1676 dbref.setMapping(mp);
1678 vamsasSeq.addDBRef(dbref);
1684 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1685 SequenceI parentseq, SequenceI jds, boolean recurse)
1688 if (jmp.getMap() != null)
1692 jalview.util.MapList mlst = jmp.getMap();
1693 int r[] = mlst.getFromRanges();
1694 for (int s = 0; s < r.length; s += 2)
1696 MapListFrom mfrom = new MapListFrom();
1697 mfrom.setStart(r[s]);
1698 mfrom.setEnd(r[s + 1]);
1699 mp.addMapListFrom(mfrom);
1701 r = mlst.getToRanges();
1702 for (int s = 0; s < r.length; s += 2)
1704 MapListTo mto = new MapListTo();
1706 mto.setEnd(r[s + 1]);
1707 mp.addMapListTo(mto);
1709 mp.setMapFromUnit(mlst.getFromRatio());
1710 mp.setMapToUnit(mlst.getToRatio());
1711 if (jmp.getTo() != null)
1713 MappingChoice mpc = new MappingChoice();
1715 && (parentseq != jmp.getTo() || parentseq
1716 .getDatasetSequence() != jmp.getTo()))
1718 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1724 SequenceI ps = null;
1725 if (parentseq != jmp.getTo()
1726 && parentseq.getDatasetSequence() != jmp.getTo())
1728 // chaining dbref rather than a handshaking one
1729 jmpid = seqHash(ps = jmp.getTo());
1733 jmpid = seqHash(ps = parentseq);
1735 mpc.setDseqFor(jmpid);
1736 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1738 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1739 seqRefIds.put(mpc.getDseqFor(), ps);
1743 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1746 mp.setMappingChoice(mpc);
1752 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1753 Vector userColours, JalviewModelSequence jms)
1756 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1757 boolean newucs = false;
1758 if (!userColours.contains(ucs))
1760 userColours.add(ucs);
1763 id = "ucs" + userColours.indexOf(ucs);
1766 // actually create the scheme's entry in the XML model
1767 java.awt.Color[] colours = ucs.getColours();
1768 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1769 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1771 for (int i = 0; i < colours.length; i++)
1773 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1774 col.setName(ResidueProperties.aa[i]);
1775 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1776 jbucs.addColour(col);
1778 if (ucs.getLowerCaseColours() != null)
1780 colours = ucs.getLowerCaseColours();
1781 for (int i = 0; i < colours.length; i++)
1783 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1784 col.setName(ResidueProperties.aa[i].toLowerCase());
1785 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1786 jbucs.addColour(col);
1791 uc.setUserColourScheme(jbucs);
1792 jms.addUserColours(uc);
1798 jalview.schemes.UserColourScheme GetUserColourScheme(
1799 JalviewModelSequence jms, String id)
1801 UserColours[] uc = jms.getUserColours();
1802 UserColours colours = null;
1804 for (int i = 0; i < uc.length; i++)
1806 if (uc[i].getId().equals(id))
1814 java.awt.Color[] newColours = new java.awt.Color[24];
1816 for (int i = 0; i < 24; i++)
1818 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1819 .getUserColourScheme().getColour(i).getRGB(), 16));
1822 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1825 if (colours.getUserColourScheme().getColourCount() > 24)
1827 newColours = new java.awt.Color[23];
1828 for (int i = 0; i < 23; i++)
1830 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1831 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1833 ucs.setLowerCaseColours(newColours);
1840 * contains last error message (if any) encountered by XML loader.
1842 String errorMessage = null;
1845 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1846 * exceptions are raised during project XML parsing
1848 public boolean attemptversion1parse = true;
1851 * Load a jalview project archive from a jar file
1854 * - HTTP URL or filename
1856 public AlignFrame LoadJalviewAlign(final String file)
1859 jalview.gui.AlignFrame af = null;
1863 // create list to store references for any new Jmol viewers created
1864 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1865 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1866 // Workaround is to make sure caller implements the JarInputStreamProvider
1868 // so we can re-open the jar input stream for each entry.
1870 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1871 af = LoadJalviewAlign(jprovider);
1873 } catch (MalformedURLException e)
1875 errorMessage = "Invalid URL format for '" + file + "'";
1881 SwingUtilities.invokeAndWait(new Runnable()
1885 setLoadingFinishedForNewStructureViewers();
1888 } catch (Exception x)
1896 private jarInputStreamProvider createjarInputStreamProvider(
1897 final String file) throws MalformedURLException
1900 errorMessage = null;
1901 uniqueSetSuffix = null;
1903 viewportsAdded = null;
1904 frefedSequence = null;
1906 if (file.startsWith("http://"))
1908 url = new URL(file);
1910 final URL _url = url;
1911 return new jarInputStreamProvider()
1915 public JarInputStream getJarInputStream() throws IOException
1919 return new JarInputStream(_url.openStream());
1923 return new JarInputStream(new FileInputStream(file));
1928 public String getFilename()
1936 * Recover jalview session from a jalview project archive. Caller may
1937 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1938 * themselves. Any null fields will be initialised with default values,
1939 * non-null fields are left alone.
1944 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1946 errorMessage = null;
1947 if (uniqueSetSuffix == null)
1949 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1951 if (seqRefIds == null)
1953 seqRefIds = new HashMap<String, SequenceI>();
1955 if (viewportsAdded == null)
1957 viewportsAdded = new Hashtable();
1959 if (frefedSequence == null)
1961 frefedSequence = new Vector();
1964 jalview.gui.AlignFrame af = null, _af = null;
1965 Hashtable gatherToThisFrame = new Hashtable();
1966 final String file = jprovider.getFilename();
1969 JarInputStream jin = null;
1970 JarEntry jarentry = null;
1975 jin = jprovider.getJarInputStream();
1976 for (int i = 0; i < entryCount; i++)
1978 jarentry = jin.getNextJarEntry();
1981 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1983 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1984 JalviewModel object = new JalviewModel();
1986 Unmarshaller unmar = new Unmarshaller(object);
1987 unmar.setValidation(false);
1988 object = (JalviewModel) unmar.unmarshal(in);
1989 if (true) // !skipViewport(object))
1991 _af = LoadFromObject(object, file, true, jprovider);
1992 if (object.getJalviewModelSequence().getViewportCount() > 0)
1995 if (af.viewport.gatherViewsHere)
1997 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2003 else if (jarentry != null)
2005 // Some other file here.
2008 } while (jarentry != null);
2009 resolveFrefedSequences();
2010 } catch (java.io.FileNotFoundException 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 (java.net.UnknownHostException ex)
2018 ex.printStackTrace();
2019 errorMessage = "Couldn't locate Jalview XML file : " + file;
2020 System.err.println("Exception whilst loading jalview XML file : "
2022 } catch (Exception ex)
2024 System.err.println("Parsing as Jalview Version 2 file failed.");
2025 ex.printStackTrace(System.err);
2026 if (attemptversion1parse)
2028 // Is Version 1 Jar file?
2031 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2032 } catch (Exception ex2)
2034 System.err.println("Exception whilst loading as jalviewXMLV1:");
2035 ex2.printStackTrace();
2039 if (Desktop.instance != null)
2041 Desktop.instance.stopLoading();
2045 System.out.println("Successfully loaded archive file");
2048 ex.printStackTrace();
2050 System.err.println("Exception whilst loading jalview XML file : "
2052 } catch (OutOfMemoryError e)
2054 // Don't use the OOM Window here
2055 errorMessage = "Out of memory loading jalview XML file";
2056 System.err.println("Out of memory whilst loading jalview XML file");
2057 e.printStackTrace();
2060 if (Desktop.instance != null)
2062 Desktop.instance.stopLoading();
2065 Enumeration en = gatherToThisFrame.elements();
2066 while (en.hasMoreElements())
2068 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2070 if (errorMessage != null)
2078 * check errorMessage for a valid error message and raise an error box in the
2079 * GUI or write the current errorMessage to stderr and then clear the error
2082 protected void reportErrors()
2084 reportErrors(false);
2087 protected void reportErrors(final boolean saving)
2089 if (errorMessage != null)
2091 final String finalErrorMessage = errorMessage;
2094 javax.swing.SwingUtilities.invokeLater(new Runnable()
2099 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2100 finalErrorMessage, "Error "
2101 + (saving ? "saving" : "loading")
2102 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2108 System.err.println("Problem loading Jalview file: " + errorMessage);
2111 errorMessage = null;
2114 Hashtable<String, String> alreadyLoadedPDB;
2117 * when set, local views will be updated from view stored in JalviewXML
2118 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2119 * sync if this is set to true.
2121 private final boolean updateLocalViews = false;
2123 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2125 if (alreadyLoadedPDB == null)
2127 alreadyLoadedPDB = new Hashtable();
2130 if (alreadyLoadedPDB.containsKey(pdbId))
2132 return alreadyLoadedPDB.get(pdbId).toString();
2137 JarInputStream jin = jprovider.getJarInputStream();
2139 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2140 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2141 * FileInputStream(jprovider)); }
2144 JarEntry entry = null;
2147 entry = jin.getNextJarEntry();
2148 } while (entry != null && !entry.getName().equals(pdbId));
2151 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2152 File outFile = File.createTempFile("jalview_pdb", ".txt");
2153 outFile.deleteOnExit();
2154 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2157 while ((data = in.readLine()) != null)
2164 } catch (Exception foo)
2169 String t = outFile.getAbsolutePath();
2170 alreadyLoadedPDB.put(pdbId, t);
2175 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2177 } catch (Exception ex)
2179 ex.printStackTrace();
2185 private class JvAnnotRow
2187 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2194 * persisted version of annotation row from which to take vis properties
2196 public jalview.datamodel.AlignmentAnnotation template;
2199 * original position of the annotation row in the alignment
2205 * Load alignment frame from jalview XML DOM object
2210 * filename source string
2211 * @param loadTreesAndStructures
2212 * when false only create Viewport
2214 * data source provider
2215 * @return alignment frame created from view stored in DOM
2217 AlignFrame LoadFromObject(JalviewModel object, String file,
2218 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2220 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2221 Sequence[] vamsasSeq = vamsasSet.getSequence();
2223 JalviewModelSequence jms = object.getJalviewModelSequence();
2225 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2228 // ////////////////////////////////
2231 Vector hiddenSeqs = null;
2232 jalview.datamodel.Sequence jseq;
2234 ArrayList tmpseqs = new ArrayList();
2236 boolean multipleView = false;
2238 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2239 int vi = 0; // counter in vamsasSeq array
2240 for (int i = 0; i < JSEQ.length; i++)
2242 String seqId = JSEQ[i].getId();
2244 if (seqRefIds.get(seqId) != null)
2246 tmpseqs.add(seqRefIds.get(seqId));
2247 multipleView = true;
2251 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2252 vamsasSeq[vi].getSequence());
2253 jseq.setDescription(vamsasSeq[vi].getDescription());
2254 jseq.setStart(JSEQ[i].getStart());
2255 jseq.setEnd(JSEQ[i].getEnd());
2256 jseq.setVamsasId(uniqueSetSuffix + seqId);
2257 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2262 if (JSEQ[i].getHidden())
2264 if (hiddenSeqs == null)
2266 hiddenSeqs = new Vector();
2269 hiddenSeqs.addElement(seqRefIds.get(seqId));
2275 // Create the alignment object from the sequence set
2276 // ///////////////////////////////
2277 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2280 tmpseqs.toArray(orderedSeqs);
2282 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2285 // / Add the alignment properties
2286 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2288 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2289 al.setProperty(ssp.getKey(), ssp.getValue());
2293 // SequenceFeatures are added to the DatasetSequence,
2294 // so we must create or recover the dataset before loading features
2295 // ///////////////////////////////
2296 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2298 // older jalview projects do not have a dataset id.
2299 al.setDataset(null);
2303 // recover dataset - passing on flag indicating if this a 'viewless'
2304 // sequence set (a.k.a. a stored dataset for the project)
2305 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2306 .getViewportCount() == 0);
2308 // ///////////////////////////////
2310 Hashtable pdbloaded = new Hashtable();
2313 // load sequence features, database references and any associated PDB
2314 // structures for the alignment
2315 for (int i = 0; i < vamsasSeq.length; i++)
2317 if (JSEQ[i].getFeaturesCount() > 0)
2319 Features[] features = JSEQ[i].getFeatures();
2320 for (int f = 0; f < features.length; f++)
2322 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2323 features[f].getType(), features[f].getDescription(),
2324 features[f].getStatus(), features[f].getBegin(),
2325 features[f].getEnd(), features[f].getFeatureGroup());
2327 sf.setScore(features[f].getScore());
2328 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2330 OtherData keyValue = features[f].getOtherData(od);
2331 if (keyValue.getKey().startsWith("LINK"))
2333 sf.addLink(keyValue.getValue());
2337 sf.setValue(keyValue.getKey(), keyValue.getValue());
2342 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2345 if (vamsasSeq[i].getDBRefCount() > 0)
2347 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2349 if (JSEQ[i].getPdbidsCount() > 0)
2351 Pdbids[] ids = JSEQ[i].getPdbids();
2352 for (int p = 0; p < ids.length; p++)
2354 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2355 entry.setId(ids[p].getId());
2356 entry.setType(ids[p].getType());
2357 if (ids[p].getFile() != null)
2359 if (!pdbloaded.containsKey(ids[p].getFile()))
2361 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2365 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2368 StructureSelectionManager.getStructureSelectionManager(
2370 .registerPDBEntry(entry);
2371 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2375 } // end !multipleview
2377 // ///////////////////////////////
2378 // LOAD SEQUENCE MAPPINGS
2380 if (vamsasSet.getAlcodonFrameCount() > 0)
2382 // TODO Potentially this should only be done once for all views of an
2384 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2385 for (int i = 0; i < alc.length; i++)
2387 AlignedCodonFrame cf = new AlignedCodonFrame();
2388 if (alc[i].getAlcodMapCount() > 0)
2390 AlcodMap[] maps = alc[i].getAlcodMap();
2391 for (int m = 0; m < maps.length; m++)
2393 SequenceI dnaseq = seqRefIds
2394 .get(maps[m].getDnasq());
2396 jalview.datamodel.Mapping mapping = null;
2397 // attach to dna sequence reference.
2398 if (maps[m].getMapping() != null)
2400 mapping = addMapping(maps[m].getMapping());
2404 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2409 frefedSequence.add(new Object[]
2410 { maps[m].getDnasq(), cf, mapping });
2414 al.addCodonFrame(cf);
2419 // ////////////////////////////////
2421 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2423 * store any annotations which forward reference a group's ID
2425 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2427 if (vamsasSet.getAnnotationCount() > 0)
2429 Annotation[] an = vamsasSet.getAnnotation();
2431 for (int i = 0; i < an.length; i++)
2434 * test if annotation is automatically calculated for this view only
2436 boolean autoForView = false;
2437 if (an[i].getLabel().equals("Quality")
2438 || an[i].getLabel().equals("Conservation")
2439 || an[i].getLabel().equals("Consensus"))
2441 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2443 if (!an[i].hasAutoCalculated())
2445 an[i].setAutoCalculated(true);
2449 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2451 // remove ID - we don't recover annotation from other views for
2452 // view-specific annotation
2456 // set visiblity for other annotation in this view
2457 if (an[i].getId() != null
2458 && annotationIds.containsKey(an[i].getId()))
2460 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2461 .get(an[i].getId());
2462 // in principle Visible should always be true for annotation displayed
2463 // in multiple views
2464 if (an[i].hasVisible())
2466 jda.visible = an[i].getVisible();
2469 al.addAnnotation(jda);
2473 // Construct new annotation from model.
2474 AnnotationElement[] ae = an[i].getAnnotationElement();
2475 jalview.datamodel.Annotation[] anot = null;
2476 java.awt.Color firstColour = null;
2478 if (!an[i].getScoreOnly())
2480 anot = new jalview.datamodel.Annotation[al.getWidth()];
2481 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2483 anpos = ae[aa].getPosition();
2485 if (anpos >= anot.length)
2490 anot[anpos] = new jalview.datamodel.Annotation(
2492 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2493 (ae[aa].getSecondaryStructure() == null || ae[aa]
2494 .getSecondaryStructure().length() == 0) ? ' '
2495 : ae[aa].getSecondaryStructure().charAt(0),
2499 // JBPNote: Consider verifying dataflow for IO of secondary
2500 // structure annotation read from Stockholm files
2501 // this was added to try to ensure that
2502 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2504 // anot[ae[aa].getPosition()].displayCharacter = "";
2506 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2507 if (firstColour == null)
2509 firstColour = anot[anpos].colour;
2513 jalview.datamodel.AlignmentAnnotation jaa = null;
2515 if (an[i].getGraph())
2517 float llim = 0, hlim = 0;
2518 // if (autoForView || an[i].isAutoCalculated()) {
2521 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2522 an[i].getDescription(), anot, llim, hlim,
2523 an[i].getGraphType());
2525 jaa.graphGroup = an[i].getGraphGroup();
2526 jaa._linecolour = firstColour;
2527 if (an[i].getThresholdLine() != null)
2529 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2530 .getThresholdLine().getValue(), an[i]
2531 .getThresholdLine().getLabel(), new java.awt.Color(
2532 an[i].getThresholdLine().getColour())));
2535 if (autoForView || an[i].isAutoCalculated())
2537 // Hardwire the symbol display line to ensure that labels for
2538 // histograms are displayed
2544 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2545 an[i].getDescription(), anot);
2546 jaa._linecolour = firstColour;
2548 // register new annotation
2549 if (an[i].getId() != null)
2551 annotationIds.put(an[i].getId(), jaa);
2552 jaa.annotationId = an[i].getId();
2554 // recover sequence association
2555 if (an[i].getSequenceRef() != null)
2557 if (al.findName(an[i].getSequenceRef()) != null)
2559 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2561 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2564 // and make a note of any group association
2565 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2567 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2568 .get(an[i].getGroupRef());
2571 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2572 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2577 if (an[i].hasScore())
2579 jaa.setScore(an[i].getScore());
2581 if (an[i].hasVisible())
2583 jaa.visible = an[i].getVisible();
2586 if (an[i].hasCentreColLabels())
2588 jaa.centreColLabels = an[i].getCentreColLabels();
2591 if (an[i].hasScaleColLabels())
2593 jaa.scaleColLabel = an[i].getScaleColLabels();
2595 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2597 // newer files have an 'autoCalculated' flag and store calculation
2598 // state in viewport properties
2599 jaa.autoCalculated = true; // means annotation will be marked for
2600 // update at end of load.
2602 if (an[i].hasGraphHeight())
2604 jaa.graphHeight = an[i].getGraphHeight();
2606 if (an[i].hasBelowAlignment())
2608 jaa.belowAlignment = an[i].isBelowAlignment();
2610 jaa.setCalcId(an[i].getCalcId());
2611 if (an[i].getPropertyCount() > 0)
2613 for (jalview.schemabinding.version2.Property prop : an[i]
2616 jaa.setProperty(prop.getName(), prop.getValue());
2619 if (jaa.autoCalculated)
2621 autoAlan.add(new JvAnnotRow(i, jaa));
2624 // if (!autoForView)
2626 // add autocalculated group annotation and any user created annotation
2628 al.addAnnotation(jaa);
2632 // ///////////////////////
2634 // Create alignment markup and styles for this view
2635 if (jms.getJGroupCount() > 0)
2637 JGroup[] groups = jms.getJGroup();
2638 boolean addAnnotSchemeGroup = false;
2639 for (int i = 0; i < groups.length; i++)
2641 ColourSchemeI cs = null;
2643 if (groups[i].getColour() != null)
2645 if (groups[i].getColour().startsWith("ucs"))
2647 cs = GetUserColourScheme(jms, groups[i].getColour());
2649 else if (groups[i].getColour().equals("AnnotationColourGradient")
2650 && groups[i].getAnnotationColours() != null)
2652 addAnnotSchemeGroup = true;
2657 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2662 cs.setThreshold(groups[i].getPidThreshold(), true);
2666 Vector seqs = new Vector();
2668 for (int s = 0; s < groups[i].getSeqCount(); s++)
2670 String seqId = groups[i].getSeq(s) + "";
2671 jalview.datamodel.SequenceI ts = seqRefIds
2676 seqs.addElement(ts);
2680 if (seqs.size() < 1)
2685 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2686 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2687 groups[i].getDisplayText(), groups[i].getColourText(),
2688 groups[i].getStart(), groups[i].getEnd());
2690 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2692 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2693 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2694 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2695 .isShowUnconserved() : false);
2696 sg.thresholdTextColour = groups[i].getTextColThreshold();
2697 if (groups[i].hasShowConsensusHistogram())
2699 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2702 if (groups[i].hasShowSequenceLogo())
2704 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2706 if (groups[i].hasNormaliseSequenceLogo())
2708 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2710 if (groups[i].hasIgnoreGapsinConsensus())
2712 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2714 if (groups[i].getConsThreshold() != 0)
2716 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2717 "All", ResidueProperties.propHash, 3,
2718 sg.getSequences(null), 0, sg.getWidth() - 1);
2720 c.verdict(false, 25);
2721 sg.cs.setConservation(c);
2724 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2726 // re-instate unique group/annotation row reference
2727 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2728 .get(groups[i].getId());
2731 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2734 if (jaa.autoCalculated)
2736 // match up and try to set group autocalc alignment row for this
2738 if (jaa.label.startsWith("Consensus for "))
2740 sg.setConsensus(jaa);
2742 // match up and try to set group autocalc alignment row for this
2744 if (jaa.label.startsWith("Conservation for "))
2746 sg.setConservationRow(jaa);
2753 if (addAnnotSchemeGroup)
2755 // reconstruct the annotation colourscheme
2756 sg.cs = constructAnnotationColour(
2757 groups[i].getAnnotationColours(), null, al, jms, false);
2763 // only dataset in this model, so just return.
2766 // ///////////////////////////////
2769 // If we just load in the same jar file again, the sequenceSetId
2770 // will be the same, and we end up with multiple references
2771 // to the same sequenceSet. We must modify this id on load
2772 // so that each load of the file gives a unique id
2773 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2774 String viewId = (view.getId() == null ? null : view.getId()
2776 AlignFrame af = null;
2777 AlignViewport av = null;
2778 // now check to see if we really need to create a new viewport.
2779 if (multipleView && viewportsAdded.size() == 0)
2781 // We recovered an alignment for which a viewport already exists.
2782 // TODO: fix up any settings necessary for overlaying stored state onto
2783 // state recovered from another document. (may not be necessary).
2784 // we may need a binding from a viewport in memory to one recovered from
2786 // and then recover its containing af to allow the settings to be applied.
2787 // TODO: fix for vamsas demo
2789 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2791 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2792 if (seqsetobj != null)
2794 if (seqsetobj instanceof String)
2796 uniqueSeqSetId = (String) seqsetobj;
2798 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2804 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2810 * indicate that annotation colours are applied across all groups (pre
2811 * Jalview 2.8.1 behaviour)
2813 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2814 object.getVersion());
2816 AlignmentPanel ap = null;
2817 boolean isnewview = true;
2820 // Check to see if this alignment already has a view id == viewId
2821 jalview.gui.AlignmentPanel views[] = Desktop
2822 .getAlignmentPanels(uniqueSeqSetId);
2823 if (views != null && views.length > 0)
2825 for (int v = 0; v < views.length; v++)
2827 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2829 // recover the existing alignpanel, alignframe, viewport
2830 af = views[v].alignFrame;
2833 // TODO: could even skip resetting view settings if we don't want to
2834 // change the local settings from other jalview processes
2843 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2844 uniqueSeqSetId, viewId, autoAlan);
2849 // /////////////////////////////////////
2850 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2854 for (int t = 0; t < jms.getTreeCount(); t++)
2857 Tree tree = jms.getTree(t);
2859 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2862 tp = af.ShowNewickTree(
2863 new jalview.io.NewickFile(tree.getNewick()),
2864 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2865 tree.getXpos(), tree.getYpos());
2866 if (tree.getId() != null)
2868 // perhaps bind the tree id to something ?
2873 // update local tree attributes ?
2874 // TODO: should check if tp has been manipulated by user - if so its
2875 // settings shouldn't be modified
2876 tp.setTitle(tree.getTitle());
2877 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2878 .getWidth(), tree.getHeight()));
2879 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2882 tp.treeCanvas.av = av; // af.viewport;
2883 tp.treeCanvas.ap = ap; // af.alignPanel;
2888 warn("There was a problem recovering stored Newick tree: \n"
2889 + tree.getNewick());
2893 tp.fitToWindow.setState(tree.getFitToWindow());
2894 tp.fitToWindow_actionPerformed(null);
2896 if (tree.getFontName() != null)
2898 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2899 .getFontStyle(), tree.getFontSize()));
2903 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2904 .getFontStyle(), tree.getFontSize()));
2907 tp.showPlaceholders(tree.getMarkUnlinked());
2908 tp.showBootstrap(tree.getShowBootstrap());
2909 tp.showDistances(tree.getShowDistances());
2911 tp.treeCanvas.threshold = tree.getThreshold();
2913 if (tree.getCurrentTree())
2915 af.viewport.setCurrentTree(tp.getTree());
2919 } catch (Exception ex)
2921 ex.printStackTrace();
2925 // //LOAD STRUCTURES
2926 if (loadTreesAndStructures)
2928 // run through all PDB ids on the alignment, and collect mappings between
2929 // jmol view ids and all sequences referring to it
2930 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2932 for (int i = 0; i < JSEQ.length; i++)
2934 if (JSEQ[i].getPdbidsCount() > 0)
2936 Pdbids[] ids = JSEQ[i].getPdbids();
2937 for (int p = 0; p < ids.length; p++)
2939 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2941 // check to see if we haven't already created this structure view
2942 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2943 : ids[p].getStructureState(s).getViewId()
2945 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2946 // Originally : ids[p].getFile()
2947 // : TODO: verify external PDB file recovery still works in normal
2948 // jalview project load
2949 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2950 jpdb.setId(ids[p].getId());
2952 int x = ids[p].getStructureState(s).getXpos();
2953 int y = ids[p].getStructureState(s).getYpos();
2954 int width = ids[p].getStructureState(s).getWidth();
2955 int height = ids[p].getStructureState(s).getHeight();
2957 // Probably don't need to do this anymore...
2958 // Desktop.desktop.getComponentAt(x, y);
2959 // TODO: NOW: check that this recovers the PDB file correctly.
2960 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2961 jalview.datamodel.SequenceI seq = seqRefIds
2962 .get(JSEQ[i].getId() + "");
2963 if (sviewid == null)
2965 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2968 if (!jmolViewIds.containsKey(sviewid))
2970 jmolViewIds.put(sviewid, new Object[]
2972 { x, y, width, height }, "",
2973 new Hashtable<String, Object[]>(), new boolean[]
2974 { false, false, true } });
2975 // Legacy pre-2.7 conversion JAL-823 :
2976 // do not assume any view has to be linked for colour by
2980 // assemble String[] { pdb files }, String[] { id for each
2981 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2982 // seqs_file 2}, boolean[] {
2983 // linkAlignPanel,superposeWithAlignpanel}} from hash
2984 Object[] jmoldat = jmolViewIds.get(sviewid);
2985 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2986 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2987 s).getAlignwithAlignPanel() : false;
2988 // never colour by linked panel if not specified
2989 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2990 .hasColourwithAlignPanel() ? ids[p]
2991 .getStructureState(s).getColourwithAlignPanel()
2993 // default for pre-2.7 projects is that Jmol colouring is enabled
2994 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2995 .hasColourByJmol() ? ids[p].getStructureState(s)
2996 .getColourByJmol() : true;
2998 if (((String) jmoldat[1]).length() < ids[p]
2999 .getStructureState(s).getContent().length())
3002 jmoldat[1] = ids[p].getStructureState(s).getContent();
3005 if (ids[p].getFile() != null)
3007 File mapkey = new File(ids[p].getFile());
3008 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
3010 if (seqstrmaps == null)
3012 ((Hashtable) jmoldat[2]).put(mapkey,
3013 seqstrmaps = new Object[]
3014 { pdbFile, ids[p].getId(), new Vector(),
3017 if (!((Vector) seqstrmaps[2]).contains(seq))
3019 ((Vector) seqstrmaps[2]).addElement(seq);
3020 // ((Vector)seqstrmaps[3]).addElement(n) :
3021 // in principle, chains
3022 // should be stored here : do we need to
3023 // TODO: store and recover seq/pdb_id :
3029 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");
3038 // Instantiate the associated Jmol views
3039 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
3041 String sviewid = entry.getKey();
3042 Object[] svattrib = entry.getValue();
3043 int[] geom = (int[]) svattrib[0];
3044 String state = (String) svattrib[1];
3045 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
3046 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
3047 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
3048 // collate the pdbfile -> sequence mappings from this view
3049 Vector<String> pdbfilenames = new Vector<String>();
3050 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3051 Vector<String> pdbids = new Vector<String>();
3053 // Search to see if we've already created this Jmol view
3054 AppJmol comp = null;
3055 JInternalFrame[] frames = null;
3060 frames = Desktop.desktop.getAllFrames();
3061 } catch (ArrayIndexOutOfBoundsException e)
3063 // occasional No such child exceptions are thrown here...
3068 } catch (Exception f)
3073 } while (frames == null);
3074 // search for any Jmol windows already open from other
3075 // alignment views that exactly match the stored structure state
3076 for (int f = 0; comp == null && f < frames.length; f++)
3078 if (frames[f] instanceof AppJmol)
3081 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3083 // post jalview 2.4 schema includes structure view id
3084 comp = (AppJmol) frames[f];
3086 else if (frames[f].getX() == x && frames[f].getY() == y
3087 && frames[f].getHeight() == height
3088 && frames[f].getWidth() == width)
3090 comp = (AppJmol) frames[f];
3097 // create a new Jmol window.
3098 // First parse the Jmol state to translate filenames loaded into the
3099 // view, and record the order in which files are shown in the Jmol
3100 // view, so we can add the sequence mappings in same order.
3101 StringBuffer newFileLoc = null;
3102 int cp = 0, ncp, ecp;
3103 while ((ncp = state.indexOf("load ", cp)) > -1)
3105 if (newFileLoc == null)
3107 newFileLoc = new StringBuffer();
3111 // look for next filename in load statement
3112 newFileLoc.append(state.substring(cp,
3113 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3114 String oldfilenam = state.substring(ncp,
3115 ecp = state.indexOf("\"", ncp));
3116 // recover the new mapping data for this old filename
3117 // have to normalize filename - since Jmol and jalview do
3119 // translation differently.
3120 Object[] filedat = oldFiles.get(new File(oldfilenam));
3121 newFileLoc.append(Platform
3122 .escapeString((String) filedat[0]));
3123 pdbfilenames.addElement((String) filedat[0]);
3124 pdbids.addElement((String) filedat[1]);
3125 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3126 .toArray(new SequenceI[0]));
3127 newFileLoc.append("\"");
3128 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3129 // look for next file statement.
3130 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3134 // just append rest of state
3135 newFileLoc.append(state.substring(cp));
3140 .print("Ignoring incomplete Jmol state for PDB ids: ");
3141 newFileLoc = new StringBuffer(state);
3142 newFileLoc.append("; load append ");
3143 for (File id : oldFiles.keySet())
3145 // add this and any other pdb files that should be present in
3147 Object[] filedat = oldFiles.get(id);
3149 newFileLoc.append(((String) filedat[0]));
3150 pdbfilenames.addElement((String) filedat[0]);
3151 pdbids.addElement((String) filedat[1]);
3152 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3153 .toArray(new SequenceI[0]));
3154 newFileLoc.append(" \"");
3155 newFileLoc.append((String) filedat[0]);
3156 newFileLoc.append("\"");
3159 newFileLoc.append(";");
3162 if (newFileLoc != null)
3164 int histbug = newFileLoc.indexOf("history = ");
3166 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3168 String val = (diff == -1) ? null : newFileLoc.substring(
3170 if (val != null && val.length() >= 4)
3172 if (val.contains("e"))
3174 if (val.trim().equals("true"))
3182 newFileLoc.replace(histbug, diff, val);
3185 // TODO: assemble String[] { pdb files }, String[] { id for each
3186 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3187 // seqs_file 2}} from hash
3188 final String[] pdbf = pdbfilenames
3189 .toArray(new String[pdbfilenames.size()]), id = pdbids
3190 .toArray(new String[pdbids.size()]);
3191 final SequenceI[][] sq = seqmaps
3192 .toArray(new SequenceI[seqmaps.size()][]);
3193 final String fileloc = newFileLoc.toString(), vid = sviewid;
3194 final AlignFrame alf = af;
3195 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3199 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3204 JalviewStructureDisplayI sview = null;
3207 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3208 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3209 useinJmolsuperpos, usetoColourbyseq,
3210 jmolColouring, fileloc, rect, vid);
3211 addNewStructureViewer(sview);
3212 } catch (OutOfMemoryError ex)
3214 new OOMWarning("restoring structure view for PDB id "
3215 + id, (OutOfMemoryError) ex.getCause());
3216 if (sview != null && sview.isVisible())
3218 sview.closeViewer();
3219 sview.setVisible(false);
3225 } catch (InvocationTargetException ex)
3227 warn("Unexpected error when opening Jmol view.", ex);
3229 } catch (InterruptedException e)
3231 // e.printStackTrace();
3237 // if (comp != null)
3239 // NOTE: if the jalview project is part of a shared session then
3240 // view synchronization should/could be done here.
3242 // add mapping for sequences in this view to an already open Jmol
3244 for (File id : oldFiles.keySet())
3246 // add this and any other pdb files that should be present in the
3248 Object[] filedat = oldFiles.get(id);
3249 String pdbFile = (String) filedat[0];
3250 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3251 .toArray(new SequenceI[0]);
3252 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3253 jalview.io.AppletFormatAdapter.FILE);
3254 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3256 // and add the AlignmentPanel's reference to the Jmol view
3257 comp.addAlignmentPanel(ap);
3258 if (useinJmolsuperpos)
3260 comp.useAlignmentPanelForSuperposition(ap);
3264 comp.excludeAlignmentPanelForSuperposition(ap);
3266 if (usetoColourbyseq)
3268 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3272 comp.excludeAlignmentPanelForColourbyseq(ap);
3278 // and finally return.
3285 * - minimum version we are comparing against
3287 * - version of data being processsed.
3288 * @return true if version is development/null or evaluates to the same or
3289 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3291 private boolean isVersionStringLaterThan(String supported, String version)
3293 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3294 || version.equalsIgnoreCase("Test")
3295 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3297 System.err.println("Assuming project file with "
3298 + (version == null ? "null" : version)
3299 + " is compatible with Jalview version " + supported);
3304 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3306 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3308 // convert b to decimal to catch bugfix releases within a series
3309 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3310 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3313 if (Float.valueOf(curT) > Float.valueOf(fileT))
3315 // current version is newer than the version that wrote the file
3318 } catch (NumberFormatException nfe)
3321 .println("** WARNING: Version comparison failed for tokens ("
3325 + ")\n** Current: '"
3326 + supported + "' and Version: '" + version + "'");
3329 if (currentV.hasMoreElements())
3331 // fileV has no minor version but identical series to current
3338 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3340 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3342 if (newStructureViewers != null)
3344 sview.getBinding().setFinishedLoadingFromArchive(false);
3345 newStructureViewers.add(sview);
3349 protected void setLoadingFinishedForNewStructureViewers()
3351 if (newStructureViewers != null)
3353 for (JalviewStructureDisplayI sview : newStructureViewers)
3355 sview.getBinding().setFinishedLoadingFromArchive(true);
3357 newStructureViewers.clear();
3358 newStructureViewers = null;
3362 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3363 Alignment al, JalviewModelSequence jms, Viewport view,
3364 String uniqueSeqSetId, String viewId,
3365 ArrayList<JvAnnotRow> autoAlan)
3367 AlignFrame af = null;
3368 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3369 uniqueSeqSetId, viewId);
3371 af.setFileName(file, "Jalview");
3373 for (int i = 0; i < JSEQ.length; i++)
3375 af.viewport.setSequenceColour(af.viewport.getAlignment()
3376 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3379 af.viewport.gatherViewsHere = view.getGatheredViews();
3381 if (view.getSequenceSetId() != null)
3383 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3384 .get(uniqueSeqSetId);
3386 af.viewport.setSequenceSetId(uniqueSeqSetId);
3389 // propagate shared settings to this new view
3390 af.viewport.setHistoryList(av.getHistoryList());
3391 af.viewport.setRedoList(av.getRedoList());
3395 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3397 // TODO: check if this method can be called repeatedly without
3398 // side-effects if alignpanel already registered.
3399 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3401 // apply Hidden regions to view.
3402 if (hiddenSeqs != null)
3404 for (int s = 0; s < JSEQ.length; s++)
3406 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3408 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3411 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3413 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3416 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3419 for (int s = 0; s < hiddenSeqs.size(); s++)
3421 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3424 af.viewport.hideSequence(hseqs);
3427 // recover view properties and display parameters
3428 if (view.getViewName() != null)
3430 af.viewport.viewName = view.getViewName();
3431 af.setInitialTabVisible();
3433 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3436 af.viewport.setShowAnnotation(view.getShowAnnotation());
3437 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3439 af.viewport.setColourText(view.getShowColourText());
3441 af.viewport.setConservationSelected(view.getConservationSelected());
3442 af.viewport.setShowJVSuffix(view.getShowFullId());
3443 af.viewport.rightAlignIds = view.getRightAlignIds();
3444 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3445 .getFontStyle(), view.getFontSize()));
3446 af.alignPanel.fontChanged();
3447 af.viewport.setRenderGaps(view.getRenderGaps());
3448 af.viewport.setWrapAlignment(view.getWrapAlignment());
3449 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3450 af.viewport.setShowAnnotation(view.getShowAnnotation());
3451 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3453 af.viewport.setShowBoxes(view.getShowBoxes());
3455 af.viewport.setShowText(view.getShowText());
3457 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3458 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3459 af.viewport.thresholdTextColour = view.getTextColThreshold();
3460 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3461 .isShowUnconserved() : false);
3462 af.viewport.setStartRes(view.getStartRes());
3463 af.viewport.setStartSeq(view.getStartSeq());
3465 ColourSchemeI cs = null;
3466 // apply colourschemes
3467 if (view.getBgColour() != null)
3469 if (view.getBgColour().startsWith("ucs"))
3471 cs = GetUserColourScheme(jms, view.getBgColour());
3473 else if (view.getBgColour().startsWith("Annotation"))
3475 AnnotationColours viewAnnColour = view.getAnnotationColours();
3476 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3483 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3488 cs.setThreshold(view.getPidThreshold(), true);
3489 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3493 af.viewport.setGlobalColourScheme(cs);
3494 af.viewport.setColourAppliesToAllGroups(false);
3496 if (view.getConservationSelected() && cs != null)
3498 cs.setConservationInc(view.getConsThreshold());
3501 af.changeColour(cs);
3503 af.viewport.setColourAppliesToAllGroups(true);
3505 if (view.getShowSequenceFeatures())
3507 af.viewport.showSequenceFeatures = true;
3509 if (view.hasCentreColumnLabels())
3511 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3513 if (view.hasIgnoreGapsinConsensus())
3515 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3518 if (view.hasFollowHighlight())
3520 af.viewport.followHighlight = view.getFollowHighlight();
3522 if (view.hasFollowSelection())
3524 af.viewport.followSelection = view.getFollowSelection();
3526 if (view.hasShowConsensusHistogram())
3528 af.viewport.setShowConsensusHistogram(view
3529 .getShowConsensusHistogram());
3533 af.viewport.setShowConsensusHistogram(true);
3535 if (view.hasShowSequenceLogo())
3537 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3541 af.viewport.setShowSequenceLogo(false);
3543 if (view.hasNormaliseSequenceLogo())
3545 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3547 if (view.hasShowDbRefTooltip())
3549 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3551 if (view.hasShowNPfeatureTooltip())
3553 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3555 if (view.hasShowGroupConsensus())
3557 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3561 af.viewport.setShowGroupConsensus(false);
3563 if (view.hasShowGroupConservation())
3565 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3569 af.viewport.setShowGroupConservation(false);
3572 // recover featre settings
3573 if (jms.getFeatureSettings() != null)
3575 af.viewport.featuresDisplayed = new Hashtable();
3576 String[] renderOrder = new String[jms.getFeatureSettings()
3577 .getSettingCount()];
3578 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3580 Setting setting = jms.getFeatureSettings().getSetting(fs);
3581 if (setting.hasMincolour())
3583 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3584 new java.awt.Color(setting.getMincolour()),
3585 new java.awt.Color(setting.getColour()),
3586 setting.getMin(), setting.getMax()) : new GraduatedColor(
3587 new java.awt.Color(setting.getMincolour()),
3588 new java.awt.Color(setting.getColour()), 0, 1);
3589 if (setting.hasThreshold())
3591 gc.setThresh(setting.getThreshold());
3592 gc.setThreshType(setting.getThreshstate());
3594 gc.setAutoScaled(true); // default
3595 if (setting.hasAutoScale())
3597 gc.setAutoScaled(setting.getAutoScale());
3599 if (setting.hasColourByLabel())
3601 gc.setColourByLabel(setting.getColourByLabel());
3603 // and put in the feature colour table.
3604 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3605 setting.getType(), gc);
3609 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3611 new java.awt.Color(setting.getColour()));
3613 renderOrder[fs] = setting.getType();
3614 if (setting.hasOrder())
3616 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3617 setting.getType(), setting.getOrder());
3621 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3623 fs / jms.getFeatureSettings().getSettingCount());
3625 if (setting.getDisplay())
3627 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3628 setting.getColour()));
3631 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3633 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3634 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3636 Group grp = jms.getFeatureSettings().getGroup(gs);
3637 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3641 if (view.getHiddenColumnsCount() > 0)
3643 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3645 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3646 .getHiddenColumns(c).getEnd() // +1
3650 if (view.getCalcIdParam() != null)
3652 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3654 if (calcIdParam != null)
3656 if (recoverCalcIdParam(calcIdParam, af.viewport))
3661 warn("Couldn't recover parameters for "
3662 + calcIdParam.getCalcId());
3667 af.setMenusFromViewport(af.viewport);
3668 // TODO: we don't need to do this if the viewport is aready visible.
3669 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3671 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3672 reorderAutoannotation(af, al, autoAlan);
3673 af.alignPanel.alignmentChanged();
3677 private ColourSchemeI constructAnnotationColour(
3678 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3679 JalviewModelSequence jms, boolean checkGroupAnnColour)
3681 boolean propagateAnnColour = false;
3682 ColourSchemeI cs = null;
3683 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3684 if (checkGroupAnnColour && al.getGroups() != null
3685 && al.getGroups().size() > 0)
3687 // pre 2.8.1 behaviour
3688 // check to see if we should transfer annotation colours
3689 propagateAnnColour = true;
3690 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3692 if (sg.cs instanceof AnnotationColourGradient)
3694 propagateAnnColour = false;
3698 // int find annotation
3699 if (annAlignment.getAlignmentAnnotation() != null)
3701 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3703 if (annAlignment.getAlignmentAnnotation()[i].label
3704 .equals(viewAnnColour.getAnnotation()))
3706 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3708 annAlignment.getAlignmentAnnotation()[i]
3709 .setThreshold(new jalview.datamodel.GraphLine(
3710 viewAnnColour.getThreshold(), "Threshold",
3711 java.awt.Color.black)
3716 if (viewAnnColour.getColourScheme().equals("None"))
3718 cs = new AnnotationColourGradient(
3719 annAlignment.getAlignmentAnnotation()[i],
3720 new java.awt.Color(viewAnnColour.getMinColour()),
3721 new java.awt.Color(viewAnnColour.getMaxColour()),
3722 viewAnnColour.getAboveThreshold());
3724 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3726 cs = new AnnotationColourGradient(
3727 annAlignment.getAlignmentAnnotation()[i],
3728 GetUserColourScheme(jms,
3729 viewAnnColour.getColourScheme()),
3730 viewAnnColour.getAboveThreshold());
3734 cs = new AnnotationColourGradient(
3735 annAlignment.getAlignmentAnnotation()[i],
3736 ColourSchemeProperty.getColour(al,
3737 viewAnnColour.getColourScheme()),
3738 viewAnnColour.getAboveThreshold());
3740 if (viewAnnColour.hasPerSequence())
3742 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3745 if (viewAnnColour.hasPredefinedColours())
3747 ((AnnotationColourGradient) cs)
3748 .setPredefinedColours(viewAnnColour
3749 .isPredefinedColours());
3751 if (propagateAnnColour && al.getGroups() != null)
3753 // Also use these settings for all the groups
3754 for (int g = 0; g < al.getGroups().size(); g++)
3756 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3764 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3765 * new AnnotationColourGradient(
3766 * annAlignment.getAlignmentAnnotation()[i], new
3767 * java.awt.Color(viewAnnColour. getMinColour()), new
3768 * java.awt.Color(viewAnnColour. getMaxColour()),
3769 * viewAnnColour.getAboveThreshold()); } else
3772 sg.cs = new AnnotationColourGradient(
3773 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3774 viewAnnColour.getAboveThreshold());
3775 if (cs instanceof AnnotationColourGradient)
3777 if (viewAnnColour.hasPerSequence())
3779 ((AnnotationColourGradient) cs)
3780 .setSeqAssociated(viewAnnColour.isPerSequence());
3782 if (viewAnnColour.hasPredefinedColours())
3784 ((AnnotationColourGradient) cs)
3785 .setPredefinedColours(viewAnnColour
3786 .isPredefinedColours());
3802 private void reorderAutoannotation(AlignFrame af, Alignment al,
3803 ArrayList<JvAnnotRow> autoAlan)
3805 // copy over visualization settings for autocalculated annotation in the
3807 if (al.getAlignmentAnnotation() != null)
3810 * Kludge for magic autoannotation names (see JAL-811)
3812 String[] magicNames = new String[]
3813 { "Consensus", "Quality", "Conservation" };
3814 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3815 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3816 for (String nm : magicNames)
3818 visan.put(nm, nullAnnot);
3820 for (JvAnnotRow auan : autoAlan)
3822 visan.put(auan.template.label
3823 + (auan.template.getCalcId() == null ? "" : "\t"
3824 + auan.template.getCalcId()), auan);
3826 int hSize = al.getAlignmentAnnotation().length;
3827 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3828 // work through any autoCalculated annotation already on the view
3829 // removing it if it should be placed in a different location on the
3830 // annotation panel.
3831 List<String> remains = new ArrayList(visan.keySet());
3832 for (int h = 0; h < hSize; h++)
3834 jalview.datamodel.AlignmentAnnotation jalan = al
3835 .getAlignmentAnnotation()[h];
3836 if (jalan.autoCalculated)
3839 JvAnnotRow valan = visan.get(k = jalan.label);
3840 if (jalan.getCalcId() != null)
3842 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3847 // delete the auto calculated row from the alignment
3848 al.deleteAnnotation(jalan, false);
3852 if (valan != nullAnnot)
3854 if (jalan != valan.template)
3856 // newly created autoannotation row instance
3857 // so keep a reference to the visible annotation row
3858 // and copy over all relevant attributes
3859 if (valan.template.graphHeight >= 0)
3862 jalan.graphHeight = valan.template.graphHeight;
3864 jalan.visible = valan.template.visible;
3866 reorder.add(new JvAnnotRow(valan.order, jalan));
3871 // Add any (possibly stale) autocalculated rows that were not appended to
3872 // the view during construction
3873 for (String other : remains)
3875 JvAnnotRow othera = visan.get(other);
3876 if (othera != nullAnnot && othera.template.getCalcId() != null
3877 && othera.template.getCalcId().length() > 0)
3879 reorder.add(othera);
3882 // now put the automatic annotation in its correct place
3883 int s = 0, srt[] = new int[reorder.size()];
3884 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3885 for (JvAnnotRow jvar : reorder)
3888 srt[s++] = jvar.order;
3891 jalview.util.QuickSort.sort(srt, rws);
3892 // and re-insert the annotation at its correct position
3893 for (JvAnnotRow jvar : rws)
3895 al.addAnnotation(jvar.template, jvar.order);
3897 af.alignPanel.adjustAnnotationHeight();
3901 Hashtable skipList = null;
3904 * TODO remove this method
3907 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3908 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3909 * throw new Error("Implementation Error. No skipList defined for this
3910 * Jalview2XML instance."); } return (AlignFrame)
3911 * skipList.get(view.getSequenceSetId()); }
3915 * Check if the Jalview view contained in object should be skipped or not.
3918 * @return true if view's sequenceSetId is a key in skipList
3920 private boolean skipViewport(JalviewModel object)
3922 if (skipList == null)
3927 if (skipList.containsKey(id = object.getJalviewModelSequence()
3928 .getViewport()[0].getSequenceSetId()))
3930 if (Cache.log != null && Cache.log.isDebugEnabled())
3932 Cache.log.debug("Skipping seuqence set id " + id);
3939 public void AddToSkipList(AlignFrame af)
3941 if (skipList == null)
3943 skipList = new Hashtable();
3945 skipList.put(af.getViewport().getSequenceSetId(), af);
3948 public void clearSkipList()
3950 if (skipList != null)
3957 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
3958 boolean ignoreUnrefed)
3960 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3961 Vector dseqs = null;
3964 // create a list of new dataset sequences
3965 dseqs = new Vector();
3967 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3969 Sequence vamsasSeq = vamsasSet.getSequence(i);
3970 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
3972 // create a new dataset
3975 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3976 dseqs.copyInto(dsseqs);
3977 ds = new jalview.datamodel.Alignment(dsseqs);
3978 debug("Created new dataset " + vamsasSet.getDatasetId()
3979 + " for alignment " + System.identityHashCode(al));
3980 addDatasetRef(vamsasSet.getDatasetId(), ds);
3982 // set the dataset for the newly imported alignment.
3983 if (al.getDataset() == null && !ignoreUnrefed)
3992 * sequence definition to create/merge dataset sequence for
3996 * vector to add new dataset sequence to
3998 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3999 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4001 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4003 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4004 SequenceI dsq = null;
4005 if (sq != null && sq.getDatasetSequence() != null)
4007 dsq = sq.getDatasetSequence();
4009 if (sq == null && ignoreUnrefed)
4013 String sqid = vamsasSeq.getDsseqid();
4016 // need to create or add a new dataset sequence reference to this sequence
4019 dsq = seqRefIds.get(sqid);
4024 // make a new dataset sequence
4025 dsq = sq.createDatasetSequence();
4028 // make up a new dataset reference for this sequence
4029 sqid = seqHash(dsq);
4031 dsq.setVamsasId(uniqueSetSuffix + sqid);
4032 seqRefIds.put(sqid, dsq);
4037 dseqs.addElement(dsq);
4042 ds.addSequence(dsq);
4048 { // make this dataset sequence sq's dataset sequence
4049 sq.setDatasetSequence(dsq);
4050 // and update the current dataset alignment
4055 if (!dseqs.contains(dsq))
4062 if (ds.findIndex(dsq) < 0)
4064 ds.addSequence(dsq);
4071 // TODO: refactor this as a merge dataset sequence function
4072 // now check that sq (the dataset sequence) sequence really is the union of
4073 // all references to it
4074 // boolean pre = sq.getStart() < dsq.getStart();
4075 // boolean post = sq.getEnd() > dsq.getEnd();
4079 StringBuffer sb = new StringBuffer();
4080 String newres = jalview.analysis.AlignSeq.extractGaps(
4081 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4082 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4083 && newres.length() > dsq.getLength())
4085 // Update with the longer sequence.
4089 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4090 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4091 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4092 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4094 dsq.setSequence(newres);
4096 // TODO: merges will never happen if we 'know' we have the real dataset
4097 // sequence - this should be detected when id==dssid
4099 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4100 // + (pre ? "prepended" : "") + " "
4101 // + (post ? "appended" : ""));
4106 java.util.Hashtable datasetIds = null;
4108 java.util.IdentityHashMap dataset2Ids = null;
4110 private Alignment getDatasetFor(String datasetId)
4112 if (datasetIds == null)
4114 datasetIds = new Hashtable();
4117 if (datasetIds.containsKey(datasetId))
4119 return (Alignment) datasetIds.get(datasetId);
4124 private void addDatasetRef(String datasetId, Alignment dataset)
4126 if (datasetIds == null)
4128 datasetIds = new Hashtable();
4130 datasetIds.put(datasetId, dataset);
4134 * make a new dataset ID for this jalview dataset alignment
4139 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4141 if (dataset.getDataset() != null)
4143 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4145 String datasetId = makeHashCode(dataset, null);
4146 if (datasetId == null)
4148 // make a new datasetId and record it
4149 if (dataset2Ids == null)
4151 dataset2Ids = new IdentityHashMap();
4155 datasetId = (String) dataset2Ids.get(dataset);
4157 if (datasetId == null)
4159 datasetId = "ds" + dataset2Ids.size() + 1;
4160 dataset2Ids.put(dataset, datasetId);
4166 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4168 for (int d = 0; d < sequence.getDBRefCount(); d++)
4170 DBRef dr = sequence.getDBRef(d);
4171 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4172 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4173 .getVersion(), sequence.getDBRef(d).getAccessionId());
4174 if (dr.getMapping() != null)
4176 entry.setMap(addMapping(dr.getMapping()));
4178 datasetSequence.addDBRef(entry);
4182 private jalview.datamodel.Mapping addMapping(Mapping m)
4184 SequenceI dsto = null;
4185 // Mapping m = dr.getMapping();
4186 int fr[] = new int[m.getMapListFromCount() * 2];
4187 Enumeration f = m.enumerateMapListFrom();
4188 for (int _i = 0; f.hasMoreElements(); _i += 2)
4190 MapListFrom mf = (MapListFrom) f.nextElement();
4191 fr[_i] = mf.getStart();
4192 fr[_i + 1] = mf.getEnd();
4194 int fto[] = new int[m.getMapListToCount() * 2];
4195 f = m.enumerateMapListTo();
4196 for (int _i = 0; f.hasMoreElements(); _i += 2)
4198 MapListTo mf = (MapListTo) f.nextElement();
4199 fto[_i] = mf.getStart();
4200 fto[_i + 1] = mf.getEnd();
4202 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4203 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4204 if (m.getMappingChoice() != null)
4206 MappingChoice mc = m.getMappingChoice();
4207 if (mc.getDseqFor() != null)
4209 String dsfor = "" + mc.getDseqFor();
4210 if (seqRefIds.containsKey(dsfor))
4215 jmap.setTo(seqRefIds.get(dsfor));
4219 frefedSequence.add(new Object[]
4226 * local sequence definition
4228 Sequence ms = mc.getSequence();
4229 SequenceI djs = null;
4230 String sqid = ms.getDsseqid();
4231 if (sqid != null && sqid.length() > 0)
4234 * recover dataset sequence
4236 djs = seqRefIds.get(sqid);
4241 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4242 sqid = ((Object) ms).toString(); // make up a new hascode for
4243 // undefined dataset sequence hash
4244 // (unlikely to happen)
4250 * make a new dataset sequence and add it to refIds hash
4252 djs = new jalview.datamodel.Sequence(ms.getName(),
4254 djs.setStart(jmap.getMap().getToLowest());
4255 djs.setEnd(jmap.getMap().getToHighest());
4256 djs.setVamsasId(uniqueSetSuffix + sqid);
4258 seqRefIds.put(sqid, djs);
4261 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4270 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4271 boolean keepSeqRefs)
4274 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4280 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4284 uniqueSetSuffix = "";
4285 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4290 if (this.frefedSequence == null)
4292 frefedSequence = new Vector();
4295 viewportsAdded = new Hashtable();
4297 AlignFrame af = LoadFromObject(jm, null, false, null);
4298 // next line added in an attempt to copy AlignedCodonFrame list but failed
4299 // resolveFrefedSequences();
4300 af.alignPanels.clear();
4301 af.closeMenuItem_actionPerformed(true);
4304 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4305 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4306 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4307 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4308 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4311 return af.alignPanel;
4315 * flag indicating if hashtables should be cleared on finalization TODO this
4316 * flag may not be necessary
4318 private final boolean _cleartables = true;
4320 private Hashtable jvids2vobj;
4325 * @see java.lang.Object#finalize()
4328 protected void finalize() throws Throwable
4330 // really make sure we have no buried refs left.
4335 this.seqRefIds = null;
4336 this.seqsToIds = null;
4340 private void warn(String msg)
4345 private void warn(String msg, Exception e)
4347 if (Cache.log != null)
4351 Cache.log.warn(msg, e);
4355 Cache.log.warn(msg);
4360 System.err.println("Warning: " + msg);
4363 e.printStackTrace();
4368 private void debug(String string)
4370 debug(string, null);
4373 private void debug(String msg, Exception e)
4375 if (Cache.log != null)
4379 Cache.log.debug(msg, e);
4383 Cache.log.debug(msg);
4388 System.err.println("Warning: " + msg);
4391 e.printStackTrace();
4397 * set the object to ID mapping tables used to write/recover objects and XML
4398 * ID strings for the jalview project. If external tables are provided then
4399 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4400 * object goes out of scope. - also populates the datasetIds hashtable with
4401 * alignment objects containing dataset sequences
4404 * Map from ID strings to jalview datamodel
4406 * Map from jalview datamodel to ID strings
4410 public void setObjectMappingTables(Hashtable vobj2jv,
4411 IdentityHashMap jv2vobj)
4413 this.jv2vobj = jv2vobj;
4414 this.vobj2jv = vobj2jv;
4415 Iterator ds = jv2vobj.keySet().iterator();
4417 while (ds.hasNext())
4419 Object jvobj = ds.next();
4420 id = jv2vobj.get(jvobj).toString();
4421 if (jvobj instanceof jalview.datamodel.Alignment)
4423 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4425 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4428 else if (jvobj instanceof jalview.datamodel.Sequence)
4430 // register sequence object so the XML parser can recover it.
4431 if (seqRefIds == null)
4433 seqRefIds = new HashMap<String, SequenceI>();
4435 if (seqsToIds == null)
4437 seqsToIds = new IdentityHashMap();
4439 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4440 seqsToIds.put(jvobj, id);
4442 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4444 if (annotationIds == null)
4446 annotationIds = new Hashtable();
4449 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4450 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4451 if (jvann.annotationId == null)
4453 jvann.annotationId = anid;
4455 if (!jvann.annotationId.equals(anid))
4457 // TODO verify that this is the correct behaviour
4458 this.warn("Overriding Annotation ID for " + anid
4459 + " from different id : " + jvann.annotationId);
4460 jvann.annotationId = anid;
4463 else if (jvobj instanceof String)
4465 if (jvids2vobj == null)
4467 jvids2vobj = new Hashtable();
4468 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4473 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4479 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4480 * objects created from the project archive. If string is null (default for
4481 * construction) then suffix will be set automatically.
4485 public void setUniqueSetSuffix(String string)
4487 uniqueSetSuffix = string;
4492 * uses skipList2 as the skipList for skipping views on sequence sets
4493 * associated with keys in the skipList
4497 public void setSkipList(Hashtable skipList2)
4499 skipList = skipList2;