2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.structures.JalviewStructureDisplayI;
24 import jalview.bin.Cache;
25 import jalview.datamodel.Alignment;
26 import jalview.datamodel.AlignmentAnnotation;
27 import jalview.datamodel.AlignmentI;
28 import jalview.datamodel.PDBEntry;
29 import jalview.datamodel.SequenceI;
30 import jalview.schemabinding.version2.AlcodMap;
31 import jalview.schemabinding.version2.Alcodon;
32 import jalview.schemabinding.version2.AlcodonFrame;
33 import jalview.schemabinding.version2.Annotation;
34 import jalview.schemabinding.version2.AnnotationColours;
35 import jalview.schemabinding.version2.AnnotationElement;
36 import jalview.schemabinding.version2.CalcIdParam;
37 import jalview.schemabinding.version2.DBRef;
38 import jalview.schemabinding.version2.Features;
39 import jalview.schemabinding.version2.Group;
40 import jalview.schemabinding.version2.HiddenColumns;
41 import jalview.schemabinding.version2.JGroup;
42 import jalview.schemabinding.version2.JSeq;
43 import jalview.schemabinding.version2.JalviewModel;
44 import jalview.schemabinding.version2.JalviewModelSequence;
45 import jalview.schemabinding.version2.MapListFrom;
46 import jalview.schemabinding.version2.MapListTo;
47 import jalview.schemabinding.version2.Mapping;
48 import jalview.schemabinding.version2.MappingChoice;
49 import jalview.schemabinding.version2.OtherData;
50 import jalview.schemabinding.version2.PdbentryItem;
51 import jalview.schemabinding.version2.Pdbids;
52 import jalview.schemabinding.version2.Property;
53 import jalview.schemabinding.version2.Sequence;
54 import jalview.schemabinding.version2.SequenceSet;
55 import jalview.schemabinding.version2.SequenceSetProperties;
56 import jalview.schemabinding.version2.Setting;
57 import jalview.schemabinding.version2.StructureState;
58 import jalview.schemabinding.version2.ThresholdLine;
59 import jalview.schemabinding.version2.Tree;
60 import jalview.schemabinding.version2.UserColours;
61 import jalview.schemabinding.version2.Viewport;
62 import jalview.schemes.AnnotationColourGradient;
63 import jalview.schemes.ColourSchemeI;
64 import jalview.schemes.ColourSchemeProperty;
65 import jalview.schemes.GraduatedColor;
66 import jalview.schemes.ResidueColourScheme;
67 import jalview.schemes.ResidueProperties;
68 import jalview.schemes.UserColourScheme;
69 import jalview.structure.StructureSelectionManager;
70 import jalview.structures.models.AAStructureBindingModel;
71 import jalview.util.MessageManager;
72 import jalview.util.Platform;
73 import jalview.util.jarInputStreamProvider;
74 import jalview.viewmodel.AlignmentViewport;
75 import jalview.ws.jws2.Jws2Discoverer;
76 import jalview.ws.jws2.dm.AAConSettings;
77 import jalview.ws.jws2.jabaws2.Jws2Instance;
78 import jalview.ws.params.ArgumentI;
79 import jalview.ws.params.AutoCalcSetting;
80 import jalview.ws.params.WsParamSetI;
82 import java.awt.Rectangle;
83 import java.io.BufferedReader;
84 import java.io.DataInputStream;
85 import java.io.DataOutputStream;
87 import java.io.FileInputStream;
88 import java.io.FileOutputStream;
89 import java.io.IOException;
90 import java.io.InputStreamReader;
91 import java.io.OutputStreamWriter;
92 import java.io.PrintWriter;
93 import java.lang.reflect.InvocationTargetException;
94 import java.net.MalformedURLException;
96 import java.util.ArrayList;
97 import java.util.Enumeration;
98 import java.util.HashMap;
99 import java.util.HashSet;
100 import java.util.Hashtable;
101 import java.util.IdentityHashMap;
102 import java.util.Iterator;
103 import java.util.List;
104 import java.util.Map;
105 import java.util.Map.Entry;
106 import java.util.Set;
107 import java.util.StringTokenizer;
108 import java.util.Vector;
109 import java.util.jar.JarEntry;
110 import java.util.jar.JarInputStream;
111 import java.util.jar.JarOutputStream;
113 import javax.swing.JInternalFrame;
114 import javax.swing.JOptionPane;
115 import javax.swing.SwingUtilities;
117 import org.exolab.castor.xml.Unmarshaller;
120 * Write out the current jalview desktop state as a Jalview XML stream.
122 * Note: the vamsas objects referred to here are primitive versions of the
123 * VAMSAS project schema elements - they are not the same and most likely never
127 * @version $Revision: 1.134 $
129 public class Jalview2XML
132 private class ViewerData
143 private boolean alignWithPanel;
145 private boolean colourWithAlignPanel;
147 private boolean colourByViewer;
149 private String stateData = "";
151 // todo: java bean in place of Object []
152 private Map<File, Object[]> fileData = new HashMap<File, Object[]>();
154 public ViewerData(int x, int y, int width, int height,
155 boolean alignWithPanel, boolean colourWithAlignPanel,
156 boolean colourByViewer)
161 this.height = height;
162 this.alignWithPanel = alignWithPanel;
163 this.colourWithAlignPanel = colourWithAlignPanel;
164 this.colourByViewer = colourByViewer;
170 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
171 * of sequence objects are created.
173 IdentityHashMap<SequenceI, String> seqsToIds = null;
176 * jalview XML Sequence ID to jalview sequence object reference (both dataset
177 * and alignment sequences. Populated as XML reps of sequence objects are
180 Map<String, SequenceI> seqRefIds = null;
182 Vector frefedSequence = null;
184 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
187 * create/return unique hash string for sq
190 * @return new or existing unique string for sq
192 String seqHash(SequenceI sq)
194 if (seqsToIds == null)
198 if (seqsToIds.containsKey(sq))
200 return seqsToIds.get(sq);
204 // create sequential key
205 String key = "sq" + (seqsToIds.size() + 1);
206 key = makeHashCode(sq, key); // check we don't have an external reference
208 seqsToIds.put(sq, key);
217 if (seqRefIds != null)
221 if (seqsToIds != null)
231 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
232 // seqRefIds = new Hashtable();
233 // seqsToIds = new IdentityHashMap();
239 if (seqsToIds == null)
241 seqsToIds = new IdentityHashMap<SequenceI, String>();
243 if (seqRefIds == null)
245 seqRefIds = new HashMap<String, SequenceI>();
253 public Jalview2XML(boolean raiseGUI)
255 this.raiseGUI = raiseGUI;
258 public void resolveFrefedSequences()
260 if (frefedSequence.size() > 0)
262 int r = 0, rSize = frefedSequence.size();
265 Object[] ref = (Object[]) frefedSequence.elementAt(r);
268 String sref = (String) ref[0];
269 if (seqRefIds.containsKey(sref))
271 if (ref[1] instanceof jalview.datamodel.Mapping)
273 SequenceI seq = seqRefIds.get(sref);
274 while (seq.getDatasetSequence() != null)
276 seq = seq.getDatasetSequence();
278 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
282 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
284 SequenceI seq = seqRefIds.get(sref);
285 while (seq.getDatasetSequence() != null)
287 seq = seq.getDatasetSequence();
290 && ref[2] instanceof jalview.datamodel.Mapping)
292 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
293 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
294 seq, mp.getTo(), mp.getMap());
299 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
300 + ref[2].getClass() + " type objects.");
306 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
307 + ref[1].getClass() + " type objects.");
310 frefedSequence.remove(r);
316 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
318 + " with objecttype "
319 + ref[1].getClass());
326 frefedSequence.remove(r);
334 * This maintains a list of viewports, the key being the seqSetId. Important
335 * to set historyItem and redoList for multiple views
337 Hashtable viewportsAdded;
339 Hashtable annotationIds = new Hashtable();
341 String uniqueSetSuffix = "";
344 * List of pdbfiles added to Jar
346 List<String> pdbfiles = null;
348 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
349 public void saveState(File statefile)
351 FileOutputStream fos = null;
354 fos = new FileOutputStream(statefile);
355 JarOutputStream jout = new JarOutputStream(fos);
358 } catch (Exception e)
360 // TODO: inform user of the problem - they need to know if their data was
362 if (errorMessage == null)
364 errorMessage = "Couldn't write Jalview Archive to output file '"
365 + statefile + "' - See console error log for details";
369 errorMessage += "(output file was '" + statefile + "')";
379 } catch (IOException e)
389 * Writes a jalview project archive to the given Jar output stream.
393 public void saveState(JarOutputStream jout)
395 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
402 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
407 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
408 // //////////////////////////////////////////////////
410 Vector shortNames = new Vector();
413 for (int i = frames.length - 1; i > -1; i--)
415 if (frames[i] instanceof AlignFrame)
417 AlignFrame af = (AlignFrame) frames[i];
420 && skipList.containsKey(af.getViewport()
421 .getSequenceSetId()))
426 String shortName = af.getTitle();
428 if (shortName.indexOf(File.separatorChar) > -1)
430 shortName = shortName.substring(shortName
431 .lastIndexOf(File.separatorChar) + 1);
436 while (shortNames.contains(shortName))
438 if (shortName.endsWith("_" + (count - 1)))
440 shortName = shortName
441 .substring(0, shortName.lastIndexOf("_"));
444 shortName = shortName.concat("_" + count);
448 shortNames.addElement(shortName);
450 if (!shortName.endsWith(".xml"))
452 shortName = shortName + ".xml";
455 int ap, apSize = af.alignPanels.size();
457 for (ap = 0; ap < apSize; ap++)
459 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
461 String fileName = apSize == 1 ? shortName : ap + shortName;
462 if (!fileName.endsWith(".xml"))
464 fileName = fileName + ".xml";
467 saveState(apanel, fileName, jout);
469 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
471 if (!dsses.containsKey(dssid))
473 dsses.put(dssid, af);
480 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
486 } catch (Exception foo)
491 } catch (Exception ex)
493 // TODO: inform user of the problem - they need to know if their data was
495 if (errorMessage == null)
497 errorMessage = "Couldn't write Jalview Archive - see error output for details";
499 ex.printStackTrace();
503 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
504 public boolean saveAlignment(AlignFrame af, String jarFile,
509 int ap, apSize = af.alignPanels.size();
510 FileOutputStream fos = new FileOutputStream(jarFile);
511 JarOutputStream jout = new JarOutputStream(fos);
512 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
513 for (ap = 0; ap < apSize; ap++)
515 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
517 String jfileName = apSize == 1 ? fileName : fileName + ap;
518 if (!jfileName.endsWith(".xml"))
520 jfileName = jfileName + ".xml";
522 saveState(apanel, jfileName, jout);
523 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
525 if (!dsses.containsKey(dssid))
527 dsses.put(dssid, af);
530 writeDatasetFor(dsses, fileName, jout);
534 } catch (Exception foo)
540 } catch (Exception ex)
542 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
543 ex.printStackTrace();
548 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
549 String fileName, JarOutputStream jout)
552 for (String dssids : dsses.keySet())
554 AlignFrame _af = dsses.get(dssids);
555 String jfileName = fileName + " Dataset for " + _af.getTitle();
556 if (!jfileName.endsWith(".xml"))
558 jfileName = jfileName + ".xml";
560 saveState(_af.alignPanel, jfileName, true, jout);
565 * create a JalviewModel from an alignment view and marshall it to a
569 * panel to create jalview model for
571 * name of alignment panel written to output stream
577 public JalviewModel saveState(AlignmentPanel ap, String fileName,
578 JarOutputStream jout)
580 return saveState(ap, fileName, false, jout);
584 * create a JalviewModel from an alignment view and marshall it to a
588 * panel to create jalview model for
590 * name of alignment panel written to output stream
592 * when true, only write the dataset for the alignment, not the data
593 * associated with the view.
599 public JalviewModel saveState(AlignmentPanel ap, String fileName,
600 boolean storeDS, JarOutputStream jout)
603 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
605 AlignViewport av = ap.av;
607 JalviewModel object = new JalviewModel();
608 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
610 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
611 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
612 "Development Build"));
614 jalview.datamodel.AlignmentI jal = av.getAlignment();
616 if (av.hasHiddenRows())
618 jal = jal.getHiddenSequences().getFullAlignment();
621 SequenceSet vamsasSet = new SequenceSet();
623 JalviewModelSequence jms = new JalviewModelSequence();
625 vamsasSet.setGapChar(jal.getGapCharacter() + "");
627 if (jal.getDataset() != null)
629 // dataset id is the dataset's hashcode
630 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
633 // switch jal and the dataset
634 jal = jal.getDataset();
637 if (jal.getProperties() != null)
639 Enumeration en = jal.getProperties().keys();
640 while (en.hasMoreElements())
642 String key = en.nextElement().toString();
643 SequenceSetProperties ssp = new SequenceSetProperties();
645 ssp.setValue(jal.getProperties().get(key).toString());
646 vamsasSet.addSequenceSetProperties(ssp);
651 Set<String> calcIdSet = new HashSet<String>();
655 jalview.datamodel.SequenceI jds, jdatasq;
656 for (int i = 0; i < jal.getHeight(); i++)
658 jds = jal.getSequenceAt(i);
659 jdatasq = jds.getDatasetSequence() == null ? jds : jds
660 .getDatasetSequence();
663 if (seqRefIds.get(id) != null)
665 // This happens for two reasons: 1. multiple views are being serialised.
666 // 2. the hashCode has collided with another sequence's code. This DOES
667 // HAPPEN! (PF00072.15.stk does this)
668 // JBPNote: Uncomment to debug writing out of files that do not read
669 // back in due to ArrayOutOfBoundExceptions.
670 // System.err.println("vamsasSeq backref: "+id+"");
671 // System.err.println(jds.getName()+"
672 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
673 // System.err.println("Hashcode: "+seqHash(jds));
674 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
675 // System.err.println(rsq.getName()+"
676 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
677 // System.err.println("Hashcode: "+seqHash(rsq));
681 vamsasSeq = createVamsasSequence(id, jds);
682 vamsasSet.addSequence(vamsasSeq);
683 seqRefIds.put(id, jds);
687 jseq.setStart(jds.getStart());
688 jseq.setEnd(jds.getEnd());
689 jseq.setColour(av.getSequenceColour(jds).getRGB());
691 jseq.setId(id); // jseq id should be a string not a number
694 // Store any sequences this sequence represents
695 if (av.hasHiddenRows())
697 jseq.setHidden(av.getAlignment().getHiddenSequences()
700 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
702 jalview.datamodel.SequenceI[] reps = av
703 .getRepresentedSequences(jal.getSequenceAt(i))
704 .getSequencesInOrder(jal);
706 for (int h = 0; h < reps.length; h++)
708 if (reps[h] != jal.getSequenceAt(i))
710 jseq.addHiddenSequences(jal.findIndex(reps[h]));
717 if (jdatasq.getSequenceFeatures() != null)
719 jalview.datamodel.SequenceFeature[] sf = jdatasq
720 .getSequenceFeatures();
722 while (index < sf.length)
724 Features features = new Features();
726 features.setBegin(sf[index].getBegin());
727 features.setEnd(sf[index].getEnd());
728 features.setDescription(sf[index].getDescription());
729 features.setType(sf[index].getType());
730 features.setFeatureGroup(sf[index].getFeatureGroup());
731 features.setScore(sf[index].getScore());
732 if (sf[index].links != null)
734 for (int l = 0; l < sf[index].links.size(); l++)
736 OtherData keyValue = new OtherData();
737 keyValue.setKey("LINK_" + l);
738 keyValue.setValue(sf[index].links.elementAt(l).toString());
739 features.addOtherData(keyValue);
742 if (sf[index].otherDetails != null)
745 Enumeration keys = sf[index].otherDetails.keys();
746 while (keys.hasMoreElements())
748 key = keys.nextElement().toString();
749 OtherData keyValue = new OtherData();
750 keyValue.setKey(key);
751 keyValue.setValue(sf[index].otherDetails.get(key).toString());
752 features.addOtherData(keyValue);
756 jseq.addFeatures(features);
761 if (jdatasq.getPDBId() != null)
763 Enumeration en = jdatasq.getPDBId().elements();
764 while (en.hasMoreElements())
766 Pdbids pdb = new Pdbids();
767 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
770 pdb.setId(entry.getId());
771 pdb.setType(entry.getType());
774 * Store any JMol or Chimera views associated with this sequence. This
775 * section copes with duplicate entries in the project, so a dataset
776 * only view *should* be coped with sensibly.
778 List<String> viewIds = new ArrayList<String>();
779 // This must have been loaded, is it still visible?
780 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
781 String matchedFile = null;
782 for (int f = frames.length - 1; f > -1; f--)
784 if (frames[f] instanceof StructureViewerBase)
786 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
787 matchedFile = saveStructureState(ap, jds, pdb, entry,
788 viewIds, matchedFile, viewFrame);
792 if (matchedFile != null || entry.getFile() != null)
794 if (entry.getFile() != null)
797 matchedFile = entry.getFile();
799 pdb.setFile(matchedFile); // entry.getFile());
800 if (pdbfiles == null)
802 pdbfiles = new ArrayList<String>();
805 if (!pdbfiles.contains(entry.getId()))
807 pdbfiles.add(entry.getId());
808 DataInputStream dis = null;
811 File file = new File(matchedFile);
812 if (file.exists() && jout != null)
814 byte[] data = new byte[(int) file.length()];
815 jout.putNextEntry(new JarEntry(entry.getId()));
816 dis = new DataInputStream(
817 new FileInputStream(file));
820 DataOutputStream dout = new DataOutputStream(jout);
821 dout.write(data, 0, data.length);
825 } catch (Exception ex)
827 ex.printStackTrace();
835 } catch (IOException e)
845 if (entry.getProperty() != null)
847 PdbentryItem item = new PdbentryItem();
848 Hashtable properties = entry.getProperty();
849 Enumeration en2 = properties.keys();
850 while (en2.hasMoreElements())
852 Property prop = new Property();
853 String key = en2.nextElement().toString();
855 prop.setValue(properties.get(key).toString());
856 item.addProperty(prop);
858 pdb.addPdbentryItem(item);
868 if (!storeDS && av.hasHiddenRows())
870 jal = av.getAlignment();
873 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
875 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
876 for (int i = 0; i < jac.length; i++)
878 AlcodonFrame alc = new AlcodonFrame();
879 vamsasSet.addAlcodonFrame(alc);
880 for (int p = 0; p < jac[i].aaWidth; p++)
882 Alcodon cmap = new Alcodon();
883 if (jac[i].codons[p] != null)
885 // Null codons indicate a gapped column in the translated peptide
887 cmap.setPos1(jac[i].codons[p][0]);
888 cmap.setPos2(jac[i].codons[p][1]);
889 cmap.setPos3(jac[i].codons[p][2]);
891 alc.addAlcodon(cmap);
893 if (jac[i].getProtMappings() != null
894 && jac[i].getProtMappings().length > 0)
896 SequenceI[] dnas = jac[i].getdnaSeqs();
897 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
898 for (int m = 0; m < pmaps.length; m++)
900 AlcodMap alcmap = new AlcodMap();
901 alcmap.setDnasq(seqHash(dnas[m]));
902 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
904 alc.addAlcodMap(alcmap);
911 // /////////////////////////////////
912 if (!storeDS && av.currentTree != null)
914 // FIND ANY ASSOCIATED TREES
915 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
916 if (Desktop.desktop != null)
918 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
920 for (int t = 0; t < frames.length; t++)
922 if (frames[t] instanceof TreePanel)
924 TreePanel tp = (TreePanel) frames[t];
926 if (tp.treeCanvas.av.getAlignment() == jal)
928 Tree tree = new Tree();
929 tree.setTitle(tp.getTitle());
930 tree.setCurrentTree((av.currentTree == tp.getTree()));
931 tree.setNewick(tp.getTree().toString());
932 tree.setThreshold(tp.treeCanvas.threshold);
934 tree.setFitToWindow(tp.fitToWindow.getState());
935 tree.setFontName(tp.getTreeFont().getName());
936 tree.setFontSize(tp.getTreeFont().getSize());
937 tree.setFontStyle(tp.getTreeFont().getStyle());
938 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
940 tree.setShowBootstrap(tp.bootstrapMenu.getState());
941 tree.setShowDistances(tp.distanceMenu.getState());
943 tree.setHeight(tp.getHeight());
944 tree.setWidth(tp.getWidth());
945 tree.setXpos(tp.getX());
946 tree.setYpos(tp.getY());
947 tree.setId(makeHashCode(tp, null));
956 * store forward refs from an annotationRow to any groups
958 IdentityHashMap groupRefs = new IdentityHashMap();
961 for (SequenceI sq : jal.getSequences())
963 // Store annotation on dataset sequences only
964 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
965 if (aa != null && aa.length > 0)
967 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
974 if (jal.getAlignmentAnnotation() != null)
976 // Store the annotation shown on the alignment.
977 jalview.datamodel.AlignmentAnnotation[] aa = jal
978 .getAlignmentAnnotation();
979 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
984 if (jal.getGroups() != null)
986 JGroup[] groups = new JGroup[jal.getGroups().size()];
988 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
990 groups[++i] = new JGroup();
992 groups[i].setStart(sg.getStartRes());
993 groups[i].setEnd(sg.getEndRes());
994 groups[i].setName(sg.getName());
995 if (groupRefs.containsKey(sg))
997 // group has references so set it's ID field
998 groups[i].setId(groupRefs.get(sg).toString());
1002 if (sg.cs.conservationApplied())
1004 groups[i].setConsThreshold(sg.cs.getConservationInc());
1006 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1008 groups[i].setColour(setUserColourScheme(sg.cs, userColours,
1014 .setColour(ColourSchemeProperty.getColourName(sg.cs));
1017 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1019 groups[i].setColour("AnnotationColourGradient");
1020 groups[i].setAnnotationColours(constructAnnotationColours(
1021 (jalview.schemes.AnnotationColourGradient) sg.cs,
1024 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1027 .setColour(setUserColourScheme(sg.cs, userColours, jms));
1031 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
1034 groups[i].setPidThreshold(sg.cs.getThreshold());
1037 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1038 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1039 groups[i].setDisplayText(sg.getDisplayText());
1040 groups[i].setColourText(sg.getColourText());
1041 groups[i].setTextCol1(sg.textColour.getRGB());
1042 groups[i].setTextCol2(sg.textColour2.getRGB());
1043 groups[i].setTextColThreshold(sg.thresholdTextColour);
1044 groups[i].setShowUnconserved(sg.getShowNonconserved());
1045 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1046 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1047 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1048 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1049 for (int s = 0; s < sg.getSize(); s++)
1051 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1053 groups[i].addSeq(seqHash(seq));
1057 jms.setJGroup(groups);
1061 // /////////SAVE VIEWPORT
1062 Viewport view = new Viewport();
1063 view.setTitle(ap.alignFrame.getTitle());
1064 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1065 av.getSequenceSetId()));
1066 view.setId(av.getViewId());
1067 view.setViewName(av.viewName);
1068 view.setGatheredViews(av.gatherViewsHere);
1070 if (ap.av.explodedPosition != null)
1072 view.setXpos(av.explodedPosition.x);
1073 view.setYpos(av.explodedPosition.y);
1074 view.setWidth(av.explodedPosition.width);
1075 view.setHeight(av.explodedPosition.height);
1079 view.setXpos(ap.alignFrame.getBounds().x);
1080 view.setYpos(ap.alignFrame.getBounds().y);
1081 view.setWidth(ap.alignFrame.getBounds().width);
1082 view.setHeight(ap.alignFrame.getBounds().height);
1085 view.setStartRes(av.startRes);
1086 view.setStartSeq(av.startSeq);
1088 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1090 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1093 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1095 AnnotationColours ac = constructAnnotationColours(
1096 (jalview.schemes.AnnotationColourGradient) av
1097 .getGlobalColourScheme(),
1100 view.setAnnotationColours(ac);
1101 view.setBgColour("AnnotationColourGradient");
1105 view.setBgColour(ColourSchemeProperty.getColourName(av
1106 .getGlobalColourScheme()));
1109 ColourSchemeI cs = av.getGlobalColourScheme();
1113 if (cs.conservationApplied())
1115 view.setConsThreshold(cs.getConservationInc());
1116 if (cs instanceof jalview.schemes.UserColourScheme)
1118 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1122 if (cs instanceof ResidueColourScheme)
1124 view.setPidThreshold(cs.getThreshold());
1128 view.setConservationSelected(av.getConservationSelected());
1129 view.setPidSelected(av.getAbovePIDThreshold());
1130 view.setFontName(av.font.getName());
1131 view.setFontSize(av.font.getSize());
1132 view.setFontStyle(av.font.getStyle());
1133 view.setRenderGaps(av.renderGaps);
1134 view.setShowAnnotation(av.getShowAnnotation());
1135 view.setShowBoxes(av.getShowBoxes());
1136 view.setShowColourText(av.getColourText());
1137 view.setShowFullId(av.getShowJVSuffix());
1138 view.setRightAlignIds(av.isRightAlignIds());
1139 view.setShowSequenceFeatures(av.showSequenceFeatures);
1140 view.setShowText(av.getShowText());
1141 view.setShowUnconserved(av.getShowUnconserved());
1142 view.setWrapAlignment(av.getWrapAlignment());
1143 view.setTextCol1(av.textColour.getRGB());
1144 view.setTextCol2(av.textColour2.getRGB());
1145 view.setTextColThreshold(av.thresholdTextColour);
1146 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1147 view.setShowSequenceLogo(av.isShowSequenceLogo());
1148 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1149 view.setShowGroupConsensus(av.isShowGroupConsensus());
1150 view.setShowGroupConservation(av.isShowGroupConservation());
1151 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1152 view.setShowDbRefTooltip(av.isShowDbRefs());
1153 view.setFollowHighlight(av.followHighlight);
1154 view.setFollowSelection(av.followSelection);
1155 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1156 if (av.getFeaturesDisplayed() != null)
1158 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1160 String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder;
1162 Vector settingsAdded = new Vector();
1163 Object gstyle = null;
1164 GraduatedColor gcol = null;
1165 if (renderOrder != null)
1167 for (int ro = 0; ro < renderOrder.length; ro++)
1169 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1170 .getFeatureStyle(renderOrder[ro]);
1171 Setting setting = new Setting();
1172 setting.setType(renderOrder[ro]);
1173 if (gstyle instanceof GraduatedColor)
1175 gcol = (GraduatedColor) gstyle;
1176 setting.setColour(gcol.getMaxColor().getRGB());
1177 setting.setMincolour(gcol.getMinColor().getRGB());
1178 setting.setMin(gcol.getMin());
1179 setting.setMax(gcol.getMax());
1180 setting.setColourByLabel(gcol.isColourByLabel());
1181 setting.setAutoScale(gcol.isAutoScale());
1182 setting.setThreshold(gcol.getThresh());
1183 setting.setThreshstate(gcol.getThreshType());
1187 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1188 .getColour(renderOrder[ro]).getRGB());
1191 setting.setDisplay(av.getFeaturesDisplayed()
1192 .containsKey(renderOrder[ro]));
1193 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1194 .getOrder(renderOrder[ro]);
1197 setting.setOrder(rorder);
1199 fs.addSetting(setting);
1200 settingsAdded.addElement(renderOrder[ro]);
1204 // Make sure we save none displayed feature settings
1205 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureColours
1206 .keySet().iterator();
1207 while (en.hasNext())
1209 String key = en.next().toString();
1210 if (settingsAdded.contains(key))
1215 Setting setting = new Setting();
1216 setting.setType(key);
1217 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1218 .getColour(key).getRGB());
1220 setting.setDisplay(false);
1221 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1225 setting.setOrder(rorder);
1227 fs.addSetting(setting);
1228 settingsAdded.addElement(key);
1230 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups
1231 .keySet().iterator();
1232 Vector groupsAdded = new Vector();
1233 while (en.hasNext())
1235 String grp = en.next().toString();
1236 if (groupsAdded.contains(grp))
1240 Group g = new Group();
1242 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1243 .getFeatureRenderer().featureGroups.get(grp))
1246 groupsAdded.addElement(grp);
1248 jms.setFeatureSettings(fs);
1252 if (av.hasHiddenColumns())
1254 if (av.getColumnSelection() == null
1255 || av.getColumnSelection().getHiddenColumns() == null)
1257 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1261 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1264 int[] region = (int[]) av.getColumnSelection()
1265 .getHiddenColumns().elementAt(c);
1266 HiddenColumns hc = new HiddenColumns();
1267 hc.setStart(region[0]);
1268 hc.setEnd(region[1]);
1269 view.addHiddenColumns(hc);
1273 if (calcIdSet.size() > 0)
1275 for (String calcId : calcIdSet)
1277 if (calcId.trim().length() > 0)
1279 CalcIdParam cidp = createCalcIdParam(calcId, av);
1280 // Some calcIds have no parameters.
1283 view.addCalcIdParam(cidp);
1289 jms.addViewport(view);
1291 object.setJalviewModelSequence(jms);
1292 object.getVamsasModel().addSequenceSet(vamsasSet);
1294 if (jout != null && fileName != null)
1296 // We may not want to write the object to disk,
1297 // eg we can copy the alignViewport to a new view object
1298 // using save and then load
1301 JarEntry entry = new JarEntry(fileName);
1302 jout.putNextEntry(entry);
1303 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1305 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1307 marshaller.marshal(object);
1310 } catch (Exception ex)
1312 // TODO: raise error in GUI if marshalling failed.
1313 ex.printStackTrace();
1320 * Save the state of a structure viewer
1325 * the archive XML element under which to save the state
1328 * @param matchedFile
1332 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1333 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1334 String matchedFile, StructureViewerBase viewFrame)
1336 final AAStructureBindingModel bindingModel = viewFrame
1338 for (int peid = 0; peid < bindingModel
1339 .getPdbCount(); peid++)
1341 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1342 final String pdbId = pdbentry.getId();
1343 if (!pdbId.equals(entry.getId())
1344 && !(entry.getId().length() > 4 && entry.getId()
1346 .startsWith(pdbId.toLowerCase())))
1350 if (matchedFile == null)
1352 matchedFile = pdbentry.getFile();
1354 else if (!matchedFile.equals(pdbentry
1358 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1359 + pdbentry.getFile());
1363 // can get at it if the ID
1364 // match is ambiguous (e.g.
1366 String statestring = viewFrame.getStateInfo();
1368 for (int smap = 0; smap < viewFrame.getBinding()
1369 .getSequence()[peid].length; smap++)
1371 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1372 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1374 StructureState state = new StructureState();
1375 state.setVisible(true);
1376 state.setXpos(viewFrame.getX());
1377 state.setYpos(viewFrame.getY());
1378 state.setWidth(viewFrame.getWidth());
1379 state.setHeight(viewFrame.getHeight());
1380 final String viewId = viewFrame.getViewId();
1381 state.setViewId(viewId);
1382 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1383 state.setColourwithAlignPanel(viewFrame
1384 .isUsedforcolourby(ap));
1385 state.setColourByJmol(viewFrame.isColouredByViewer());
1387 * Only store each structure viewer's state once in each XML document.
1389 if (!viewIds.contains(viewId))
1391 viewIds.add(viewId);
1392 state.setContent(statestring.replaceAll("\n", ""));
1396 state.setContent("# duplicate state");
1398 pdb.addStructureState(state);
1405 private AnnotationColours constructAnnotationColours(
1406 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1407 JalviewModelSequence jms)
1409 AnnotationColours ac = new AnnotationColours();
1410 ac.setAboveThreshold(acg.getAboveThreshold());
1411 ac.setThreshold(acg.getAnnotationThreshold());
1412 ac.setAnnotation(acg.getAnnotation());
1413 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1415 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1420 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1424 ac.setMaxColour(acg.getMaxColour().getRGB());
1425 ac.setMinColour(acg.getMinColour().getRGB());
1426 ac.setPerSequence(acg.isSeqAssociated());
1427 ac.setPredefinedColours(acg.isPredefinedColours());
1431 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1432 IdentityHashMap groupRefs, AlignmentViewport av,
1433 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1436 for (int i = 0; i < aa.length; i++)
1438 Annotation an = new Annotation();
1440 if (aa[i].annotationId != null)
1442 annotationIds.put(aa[i].annotationId, aa[i]);
1445 an.setId(aa[i].annotationId);
1447 an.setVisible(aa[i].visible);
1449 an.setDescription(aa[i].description);
1451 if (aa[i].sequenceRef != null)
1453 // TODO later annotation sequenceRef should be the XML ID of the
1454 // sequence rather than its display name
1455 an.setSequenceRef(aa[i].sequenceRef.getName());
1457 if (aa[i].groupRef != null)
1459 Object groupIdr = groupRefs.get(aa[i].groupRef);
1460 if (groupIdr == null)
1462 // make a locally unique String
1463 groupRefs.put(aa[i].groupRef,
1464 groupIdr = ("" + System.currentTimeMillis()
1465 + aa[i].groupRef.getName() + groupRefs.size()));
1467 an.setGroupRef(groupIdr.toString());
1470 // store all visualization attributes for annotation
1471 an.setGraphHeight(aa[i].graphHeight);
1472 an.setCentreColLabels(aa[i].centreColLabels);
1473 an.setScaleColLabels(aa[i].scaleColLabel);
1474 an.setShowAllColLabels(aa[i].showAllColLabels);
1475 an.setBelowAlignment(aa[i].belowAlignment);
1477 if (aa[i].graph > 0)
1480 an.setGraphType(aa[i].graph);
1481 an.setGraphGroup(aa[i].graphGroup);
1482 if (aa[i].getThreshold() != null)
1484 ThresholdLine line = new ThresholdLine();
1485 line.setLabel(aa[i].getThreshold().label);
1486 line.setValue(aa[i].getThreshold().value);
1487 line.setColour(aa[i].getThreshold().colour.getRGB());
1488 an.setThresholdLine(line);
1496 an.setLabel(aa[i].label);
1498 if (aa[i] == av.getAlignmentQualityAnnot()
1499 || aa[i] == av.getAlignmentConservationAnnotation()
1500 || aa[i] == av.getAlignmentConsensusAnnotation()
1501 || aa[i].autoCalculated)
1503 // new way of indicating autocalculated annotation -
1504 an.setAutoCalculated(aa[i].autoCalculated);
1506 if (aa[i].hasScore())
1508 an.setScore(aa[i].getScore());
1511 if (aa[i].getCalcId() != null)
1513 calcIdSet.add(aa[i].getCalcId());
1514 an.setCalcId(aa[i].getCalcId());
1516 if (aa[i].hasProperties())
1518 for (String pr : aa[i].getProperties())
1520 Property prop = new Property();
1522 prop.setValue(aa[i].getProperty(pr));
1523 an.addProperty(prop);
1526 AnnotationElement ae;
1527 if (aa[i].annotations != null)
1529 an.setScoreOnly(false);
1530 for (int a = 0; a < aa[i].annotations.length; a++)
1532 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1537 ae = new AnnotationElement();
1538 if (aa[i].annotations[a].description != null)
1540 ae.setDescription(aa[i].annotations[a].description);
1542 if (aa[i].annotations[a].displayCharacter != null)
1544 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1547 if (!Float.isNaN(aa[i].annotations[a].value))
1549 ae.setValue(aa[i].annotations[a].value);
1553 if (aa[i].annotations[a].secondaryStructure > ' ')
1555 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1559 if (aa[i].annotations[a].colour != null
1560 && aa[i].annotations[a].colour != java.awt.Color.black)
1562 ae.setColour(aa[i].annotations[a].colour.getRGB());
1565 an.addAnnotationElement(ae);
1566 if (aa[i].autoCalculated)
1568 // only write one non-null entry into the annotation row -
1569 // sufficient to get the visualization attributes necessary to
1577 an.setScoreOnly(true);
1579 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1581 // skip autocalculated annotation - these are only provided for
1583 vamsasSet.addAnnotation(an);
1589 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1591 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1592 if (settings != null)
1594 CalcIdParam vCalcIdParam = new CalcIdParam();
1595 vCalcIdParam.setCalcId(calcId);
1596 vCalcIdParam.addServiceURL(settings.getServiceURI());
1597 // generic URI allowing a third party to resolve another instance of the
1598 // service used for this calculation
1599 for (String urls : settings.getServiceURLs())
1601 vCalcIdParam.addServiceURL(urls);
1603 vCalcIdParam.setVersion("1.0");
1604 if (settings.getPreset() != null)
1606 WsParamSetI setting = settings.getPreset();
1607 vCalcIdParam.setName(setting.getName());
1608 vCalcIdParam.setDescription(setting.getDescription());
1612 vCalcIdParam.setName("");
1613 vCalcIdParam.setDescription("Last used parameters");
1615 // need to be able to recover 1) settings 2) user-defined presets or
1616 // recreate settings from preset 3) predefined settings provided by
1617 // service - or settings that can be transferred (or discarded)
1618 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1620 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1621 // todo - decide if updateImmediately is needed for any projects.
1623 return vCalcIdParam;
1628 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1631 if (calcIdParam.getVersion().equals("1.0"))
1633 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1634 .getPreferredServiceFor(calcIdParam.getServiceURL());
1635 if (service != null)
1637 WsParamSetI parmSet = null;
1640 parmSet = service.getParamStore().parseServiceParameterFile(
1641 calcIdParam.getName(), calcIdParam.getDescription(),
1642 calcIdParam.getServiceURL(),
1643 calcIdParam.getParameters().replace("|\\n|", "\n"));
1644 } catch (IOException x)
1646 warn("Couldn't parse parameter data for "
1647 + calcIdParam.getCalcId(), x);
1650 List<ArgumentI> argList = null;
1651 if (calcIdParam.getName().length() > 0)
1653 parmSet = service.getParamStore()
1654 .getPreset(calcIdParam.getName());
1655 if (parmSet != null)
1657 // TODO : check we have a good match with settings in AACon -
1658 // otherwise we'll need to create a new preset
1663 argList = parmSet.getArguments();
1666 AAConSettings settings = new AAConSettings(
1667 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1668 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1669 calcIdParam.isNeedsUpdate());
1674 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1678 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1682 * External mapping between jalview objects and objects yielding a valid and
1683 * unique object ID string. This is null for normal Jalview project IO, but
1684 * non-null when a jalview project is being read or written as part of a
1687 IdentityHashMap jv2vobj = null;
1690 * Construct a unique ID for jvobj using either existing bindings or if none
1691 * exist, the result of the hashcode call for the object.
1694 * jalview data object
1695 * @return unique ID for referring to jvobj
1697 private String makeHashCode(Object jvobj, String altCode)
1699 if (jv2vobj != null)
1701 Object id = jv2vobj.get(jvobj);
1704 return id.toString();
1706 // check string ID mappings
1707 if (jvids2vobj != null && jvobj instanceof String)
1709 id = jvids2vobj.get(jvobj);
1713 return id.toString();
1715 // give up and warn that something has gone wrong
1716 warn("Cannot find ID for object in external mapping : " + jvobj);
1722 * return local jalview object mapped to ID, if it exists
1726 * @return null or object bound to idcode
1728 private Object retrieveExistingObj(String idcode)
1730 if (idcode != null && vobj2jv != null)
1732 return vobj2jv.get(idcode);
1738 * binding from ID strings from external mapping table to jalview data model
1741 private Hashtable vobj2jv;
1743 private Sequence createVamsasSequence(String id, SequenceI jds)
1745 return createVamsasSequence(true, id, jds, null);
1748 private Sequence createVamsasSequence(boolean recurse, String id,
1749 SequenceI jds, SequenceI parentseq)
1751 Sequence vamsasSeq = new Sequence();
1752 vamsasSeq.setId(id);
1753 vamsasSeq.setName(jds.getName());
1754 vamsasSeq.setSequence(jds.getSequenceAsString());
1755 vamsasSeq.setDescription(jds.getDescription());
1756 jalview.datamodel.DBRefEntry[] dbrefs = null;
1757 if (jds.getDatasetSequence() != null)
1759 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1760 if (jds.getDatasetSequence().getDBRef() != null)
1762 dbrefs = jds.getDatasetSequence().getDBRef();
1767 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1768 // dataset sequences only
1769 dbrefs = jds.getDBRef();
1773 for (int d = 0; d < dbrefs.length; d++)
1775 DBRef dbref = new DBRef();
1776 dbref.setSource(dbrefs[d].getSource());
1777 dbref.setVersion(dbrefs[d].getVersion());
1778 dbref.setAccessionId(dbrefs[d].getAccessionId());
1779 if (dbrefs[d].hasMap())
1781 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1783 dbref.setMapping(mp);
1785 vamsasSeq.addDBRef(dbref);
1791 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1792 SequenceI parentseq, SequenceI jds, boolean recurse)
1795 if (jmp.getMap() != null)
1799 jalview.util.MapList mlst = jmp.getMap();
1800 int r[] = mlst.getFromRanges();
1801 for (int s = 0; s < r.length; s += 2)
1803 MapListFrom mfrom = new MapListFrom();
1804 mfrom.setStart(r[s]);
1805 mfrom.setEnd(r[s + 1]);
1806 mp.addMapListFrom(mfrom);
1808 r = mlst.getToRanges();
1809 for (int s = 0; s < r.length; s += 2)
1811 MapListTo mto = new MapListTo();
1813 mto.setEnd(r[s + 1]);
1814 mp.addMapListTo(mto);
1816 mp.setMapFromUnit(mlst.getFromRatio());
1817 mp.setMapToUnit(mlst.getToRatio());
1818 if (jmp.getTo() != null)
1820 MappingChoice mpc = new MappingChoice();
1822 && (parentseq != jmp.getTo() || parentseq
1823 .getDatasetSequence() != jmp.getTo()))
1825 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1831 SequenceI ps = null;
1832 if (parentseq != jmp.getTo()
1833 && parentseq.getDatasetSequence() != jmp.getTo())
1835 // chaining dbref rather than a handshaking one
1836 jmpid = seqHash(ps = jmp.getTo());
1840 jmpid = seqHash(ps = parentseq);
1842 mpc.setDseqFor(jmpid);
1843 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1845 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1846 seqRefIds.put(mpc.getDseqFor(), ps);
1850 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1853 mp.setMappingChoice(mpc);
1859 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
1860 List<UserColourScheme> userColours, JalviewModelSequence jms)
1863 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1864 boolean newucs = false;
1865 if (!userColours.contains(ucs))
1867 userColours.add(ucs);
1870 id = "ucs" + userColours.indexOf(ucs);
1873 // actually create the scheme's entry in the XML model
1874 java.awt.Color[] colours = ucs.getColours();
1875 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1876 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1878 for (int i = 0; i < colours.length; i++)
1880 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1881 col.setName(ResidueProperties.aa[i]);
1882 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1883 jbucs.addColour(col);
1885 if (ucs.getLowerCaseColours() != null)
1887 colours = ucs.getLowerCaseColours();
1888 for (int i = 0; i < colours.length; i++)
1890 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1891 col.setName(ResidueProperties.aa[i].toLowerCase());
1892 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1893 jbucs.addColour(col);
1898 uc.setUserColourScheme(jbucs);
1899 jms.addUserColours(uc);
1905 jalview.schemes.UserColourScheme getUserColourScheme(
1906 JalviewModelSequence jms, String id)
1908 UserColours[] uc = jms.getUserColours();
1909 UserColours colours = null;
1911 for (int i = 0; i < uc.length; i++)
1913 if (uc[i].getId().equals(id))
1921 java.awt.Color[] newColours = new java.awt.Color[24];
1923 for (int i = 0; i < 24; i++)
1925 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1926 .getUserColourScheme().getColour(i).getRGB(), 16));
1929 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1932 if (colours.getUserColourScheme().getColourCount() > 24)
1934 newColours = new java.awt.Color[23];
1935 for (int i = 0; i < 23; i++)
1937 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1938 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1940 ucs.setLowerCaseColours(newColours);
1947 * contains last error message (if any) encountered by XML loader.
1949 String errorMessage = null;
1952 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1953 * exceptions are raised during project XML parsing
1955 public boolean attemptversion1parse = true;
1958 * Load a jalview project archive from a jar file
1961 * - HTTP URL or filename
1963 public AlignFrame loadJalviewAlign(final String file)
1966 jalview.gui.AlignFrame af = null;
1970 // create list to store references for any new Jmol viewers created
1971 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1972 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1973 // Workaround is to make sure caller implements the JarInputStreamProvider
1975 // so we can re-open the jar input stream for each entry.
1977 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1978 af = loadJalviewAlign(jprovider);
1980 } catch (MalformedURLException e)
1982 errorMessage = "Invalid URL format for '" + file + "'";
1988 SwingUtilities.invokeAndWait(new Runnable()
1992 setLoadingFinishedForNewStructureViewers();
1995 } catch (Exception x)
2003 private jarInputStreamProvider createjarInputStreamProvider(
2004 final String file) throws MalformedURLException
2007 errorMessage = null;
2008 uniqueSetSuffix = null;
2010 viewportsAdded = null;
2011 frefedSequence = null;
2013 if (file.startsWith("http://"))
2015 url = new URL(file);
2017 final URL _url = url;
2018 return new jarInputStreamProvider()
2022 public JarInputStream getJarInputStream() throws IOException
2026 return new JarInputStream(_url.openStream());
2030 return new JarInputStream(new FileInputStream(file));
2035 public String getFilename()
2043 * Recover jalview session from a jalview project archive. Caller may
2044 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2045 * themselves. Any null fields will be initialised with default values,
2046 * non-null fields are left alone.
2051 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2053 errorMessage = null;
2054 if (uniqueSetSuffix == null)
2056 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2058 if (seqRefIds == null)
2060 seqRefIds = new HashMap<String, SequenceI>();
2062 if (viewportsAdded == null)
2064 viewportsAdded = new Hashtable();
2066 if (frefedSequence == null)
2068 frefedSequence = new Vector();
2071 jalview.gui.AlignFrame af = null, _af = null;
2072 Hashtable gatherToThisFrame = new Hashtable();
2073 final String file = jprovider.getFilename();
2076 JarInputStream jin = null;
2077 JarEntry jarentry = null;
2082 jin = jprovider.getJarInputStream();
2083 for (int i = 0; i < entryCount; i++)
2085 jarentry = jin.getNextJarEntry();
2088 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2090 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2091 JalviewModel object = new JalviewModel();
2093 Unmarshaller unmar = new Unmarshaller(object);
2094 unmar.setValidation(false);
2095 object = (JalviewModel) unmar.unmarshal(in);
2096 if (true) // !skipViewport(object))
2098 _af = loadFromObject(object, file, true, jprovider);
2099 if (object.getJalviewModelSequence().getViewportCount() > 0)
2102 if (af.viewport.gatherViewsHere)
2104 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2110 else if (jarentry != null)
2112 // Some other file here.
2115 } while (jarentry != null);
2116 resolveFrefedSequences();
2117 } catch (java.io.FileNotFoundException ex)
2119 ex.printStackTrace();
2120 errorMessage = "Couldn't locate Jalview XML file : " + file;
2121 System.err.println("Exception whilst loading jalview XML file : "
2123 } catch (java.net.UnknownHostException ex)
2125 ex.printStackTrace();
2126 errorMessage = "Couldn't locate Jalview XML file : " + file;
2127 System.err.println("Exception whilst loading jalview XML file : "
2129 } catch (Exception ex)
2131 System.err.println("Parsing as Jalview Version 2 file failed.");
2132 ex.printStackTrace(System.err);
2133 if (attemptversion1parse)
2135 // Is Version 1 Jar file?
2138 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2139 } catch (Exception ex2)
2141 System.err.println("Exception whilst loading as jalviewXMLV1:");
2142 ex2.printStackTrace();
2146 if (Desktop.instance != null)
2148 Desktop.instance.stopLoading();
2152 System.out.println("Successfully loaded archive file");
2155 ex.printStackTrace();
2157 System.err.println("Exception whilst loading jalview XML file : "
2159 } catch (OutOfMemoryError e)
2161 // Don't use the OOM Window here
2162 errorMessage = "Out of memory loading jalview XML file";
2163 System.err.println("Out of memory whilst loading jalview XML file");
2164 e.printStackTrace();
2167 if (Desktop.instance != null)
2169 Desktop.instance.stopLoading();
2172 Enumeration en = gatherToThisFrame.elements();
2173 while (en.hasMoreElements())
2175 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2177 if (errorMessage != null)
2185 * check errorMessage for a valid error message and raise an error box in the
2186 * GUI or write the current errorMessage to stderr and then clear the error
2189 protected void reportErrors()
2191 reportErrors(false);
2194 protected void reportErrors(final boolean saving)
2196 if (errorMessage != null)
2198 final String finalErrorMessage = errorMessage;
2201 javax.swing.SwingUtilities.invokeLater(new Runnable()
2206 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2207 finalErrorMessage, "Error "
2208 + (saving ? "saving" : "loading")
2209 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2215 System.err.println("Problem loading Jalview file: " + errorMessage);
2218 errorMessage = null;
2221 Hashtable<String, String> alreadyLoadedPDB;
2224 * when set, local views will be updated from view stored in JalviewXML
2225 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2226 * sync if this is set to true.
2228 private final boolean updateLocalViews = false;
2230 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2232 if (alreadyLoadedPDB == null)
2234 alreadyLoadedPDB = new Hashtable();
2237 if (alreadyLoadedPDB.containsKey(pdbId))
2239 return alreadyLoadedPDB.get(pdbId).toString();
2244 JarInputStream jin = jprovider.getJarInputStream();
2246 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2247 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2248 * FileInputStream(jprovider)); }
2251 JarEntry entry = null;
2254 entry = jin.getNextJarEntry();
2255 } while (entry != null && !entry.getName().equals(pdbId));
2258 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2259 File outFile = File.createTempFile("jalview_pdb", ".txt");
2260 outFile.deleteOnExit();
2261 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2264 while ((data = in.readLine()) != null)
2271 } catch (Exception foo)
2276 String t = outFile.getAbsolutePath();
2277 alreadyLoadedPDB.put(pdbId, t);
2282 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2284 } catch (Exception ex)
2286 ex.printStackTrace();
2292 private class JvAnnotRow
2294 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2301 * persisted version of annotation row from which to take vis properties
2303 public jalview.datamodel.AlignmentAnnotation template;
2306 * original position of the annotation row in the alignment
2312 * Load alignment frame from jalview XML DOM object
2317 * filename source string
2318 * @param loadTreesAndStructures
2319 * when false only create Viewport
2321 * data source provider
2322 * @return alignment frame created from view stored in DOM
2324 AlignFrame loadFromObject(JalviewModel object, String file,
2325 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2327 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2328 Sequence[] vamsasSeq = vamsasSet.getSequence();
2330 JalviewModelSequence jms = object.getJalviewModelSequence();
2332 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2335 // ////////////////////////////////
2338 Vector hiddenSeqs = null;
2339 jalview.datamodel.Sequence jseq;
2341 ArrayList tmpseqs = new ArrayList();
2343 boolean multipleView = false;
2345 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2346 int vi = 0; // counter in vamsasSeq array
2347 for (int i = 0; i < jseqs.length; i++)
2349 String seqId = jseqs[i].getId();
2351 if (seqRefIds.get(seqId) != null)
2353 tmpseqs.add(seqRefIds.get(seqId));
2354 multipleView = true;
2358 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2359 vamsasSeq[vi].getSequence());
2360 jseq.setDescription(vamsasSeq[vi].getDescription());
2361 jseq.setStart(jseqs[i].getStart());
2362 jseq.setEnd(jseqs[i].getEnd());
2363 jseq.setVamsasId(uniqueSetSuffix + seqId);
2364 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2369 if (jseqs[i].getHidden())
2371 if (hiddenSeqs == null)
2373 hiddenSeqs = new Vector();
2376 hiddenSeqs.addElement(seqRefIds.get(seqId));
2382 // Create the alignment object from the sequence set
2383 // ///////////////////////////////
2384 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2387 tmpseqs.toArray(orderedSeqs);
2389 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2392 // / Add the alignment properties
2393 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2395 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2396 al.setProperty(ssp.getKey(), ssp.getValue());
2400 // SequenceFeatures are added to the DatasetSequence,
2401 // so we must create or recover the dataset before loading features
2402 // ///////////////////////////////
2403 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2405 // older jalview projects do not have a dataset id.
2406 al.setDataset(null);
2410 // recover dataset - passing on flag indicating if this a 'viewless'
2411 // sequence set (a.k.a. a stored dataset for the project)
2412 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2413 .getViewportCount() == 0);
2415 // ///////////////////////////////
2417 Hashtable pdbloaded = new Hashtable();
2420 // load sequence features, database references and any associated PDB
2421 // structures for the alignment
2422 for (int i = 0; i < vamsasSeq.length; i++)
2424 if (jseqs[i].getFeaturesCount() > 0)
2426 Features[] features = jseqs[i].getFeatures();
2427 for (int f = 0; f < features.length; f++)
2429 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2430 features[f].getType(), features[f].getDescription(),
2431 features[f].getStatus(), features[f].getBegin(),
2432 features[f].getEnd(), features[f].getFeatureGroup());
2434 sf.setScore(features[f].getScore());
2435 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2437 OtherData keyValue = features[f].getOtherData(od);
2438 if (keyValue.getKey().startsWith("LINK"))
2440 sf.addLink(keyValue.getValue());
2444 sf.setValue(keyValue.getKey(), keyValue.getValue());
2449 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2452 if (vamsasSeq[i].getDBRefCount() > 0)
2454 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2456 if (jseqs[i].getPdbidsCount() > 0)
2458 Pdbids[] ids = jseqs[i].getPdbids();
2459 for (int p = 0; p < ids.length; p++)
2461 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2462 entry.setId(ids[p].getId());
2463 entry.setType(ids[p].getType());
2464 if (ids[p].getFile() != null)
2466 if (!pdbloaded.containsKey(ids[p].getFile()))
2468 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2472 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2475 StructureSelectionManager.getStructureSelectionManager(
2477 .registerPDBEntry(entry);
2478 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2482 } // end !multipleview
2484 // ///////////////////////////////
2485 // LOAD SEQUENCE MAPPINGS
2487 if (vamsasSet.getAlcodonFrameCount() > 0)
2489 // TODO Potentially this should only be done once for all views of an
2491 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2492 for (int i = 0; i < alc.length; i++)
2494 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2495 alc[i].getAlcodonCount());
2496 if (alc[i].getAlcodonCount() > 0)
2498 Alcodon[] alcods = alc[i].getAlcodon();
2499 for (int p = 0; p < cf.codons.length; p++)
2501 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2502 && alcods[p].hasPos3())
2504 // translated codons require three valid positions
2505 cf.codons[p] = new int[3];
2506 cf.codons[p][0] = (int) alcods[p].getPos1();
2507 cf.codons[p][1] = (int) alcods[p].getPos2();
2508 cf.codons[p][2] = (int) alcods[p].getPos3();
2512 cf.codons[p] = null;
2516 if (alc[i].getAlcodMapCount() > 0)
2518 AlcodMap[] maps = alc[i].getAlcodMap();
2519 for (int m = 0; m < maps.length; m++)
2521 SequenceI dnaseq = seqRefIds
2522 .get(maps[m].getDnasq());
2524 jalview.datamodel.Mapping mapping = null;
2525 // attach to dna sequence reference.
2526 if (maps[m].getMapping() != null)
2528 mapping = addMapping(maps[m].getMapping());
2532 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2537 frefedSequence.add(new Object[]
2538 { maps[m].getDnasq(), cf, mapping });
2542 al.addCodonFrame(cf);
2547 // ////////////////////////////////
2549 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2551 * store any annotations which forward reference a group's ID
2553 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2555 if (vamsasSet.getAnnotationCount() > 0)
2557 Annotation[] an = vamsasSet.getAnnotation();
2559 for (int i = 0; i < an.length; i++)
2562 * test if annotation is automatically calculated for this view only
2564 boolean autoForView = false;
2565 if (an[i].getLabel().equals("Quality")
2566 || an[i].getLabel().equals("Conservation")
2567 || an[i].getLabel().equals("Consensus"))
2569 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2571 if (!an[i].hasAutoCalculated())
2573 an[i].setAutoCalculated(true);
2577 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2579 // remove ID - we don't recover annotation from other views for
2580 // view-specific annotation
2584 // set visiblity for other annotation in this view
2585 if (an[i].getId() != null
2586 && annotationIds.containsKey(an[i].getId()))
2588 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2589 .get(an[i].getId());
2590 // in principle Visible should always be true for annotation displayed
2591 // in multiple views
2592 if (an[i].hasVisible())
2594 jda.visible = an[i].getVisible();
2597 al.addAnnotation(jda);
2601 // Construct new annotation from model.
2602 AnnotationElement[] ae = an[i].getAnnotationElement();
2603 jalview.datamodel.Annotation[] anot = null;
2604 java.awt.Color firstColour = null;
2606 if (!an[i].getScoreOnly())
2608 anot = new jalview.datamodel.Annotation[al.getWidth()];
2609 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2611 anpos = ae[aa].getPosition();
2613 if (anpos >= anot.length)
2618 anot[anpos] = new jalview.datamodel.Annotation(
2620 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2621 (ae[aa].getSecondaryStructure() == null || ae[aa]
2622 .getSecondaryStructure().length() == 0) ? ' '
2623 : ae[aa].getSecondaryStructure().charAt(0),
2627 // JBPNote: Consider verifying dataflow for IO of secondary
2628 // structure annotation read from Stockholm files
2629 // this was added to try to ensure that
2630 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2632 // anot[ae[aa].getPosition()].displayCharacter = "";
2634 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2635 if (firstColour == null)
2637 firstColour = anot[anpos].colour;
2641 jalview.datamodel.AlignmentAnnotation jaa = null;
2643 if (an[i].getGraph())
2645 float llim = 0, hlim = 0;
2646 // if (autoForView || an[i].isAutoCalculated()) {
2649 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2650 an[i].getDescription(), anot, llim, hlim,
2651 an[i].getGraphType());
2653 jaa.graphGroup = an[i].getGraphGroup();
2654 jaa._linecolour = firstColour;
2655 if (an[i].getThresholdLine() != null)
2657 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2658 .getThresholdLine().getValue(), an[i]
2659 .getThresholdLine().getLabel(), new java.awt.Color(
2660 an[i].getThresholdLine().getColour())));
2663 if (autoForView || an[i].isAutoCalculated())
2665 // Hardwire the symbol display line to ensure that labels for
2666 // histograms are displayed
2672 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2673 an[i].getDescription(), anot);
2674 jaa._linecolour = firstColour;
2676 // register new annotation
2677 if (an[i].getId() != null)
2679 annotationIds.put(an[i].getId(), jaa);
2680 jaa.annotationId = an[i].getId();
2682 // recover sequence association
2683 if (an[i].getSequenceRef() != null)
2685 if (al.findName(an[i].getSequenceRef()) != null)
2687 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2689 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2692 // and make a note of any group association
2693 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2695 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2696 .get(an[i].getGroupRef());
2699 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2700 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2705 if (an[i].hasScore())
2707 jaa.setScore(an[i].getScore());
2709 if (an[i].hasVisible())
2711 jaa.visible = an[i].getVisible();
2714 if (an[i].hasCentreColLabels())
2716 jaa.centreColLabels = an[i].getCentreColLabels();
2719 if (an[i].hasScaleColLabels())
2721 jaa.scaleColLabel = an[i].getScaleColLabels();
2723 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2725 // newer files have an 'autoCalculated' flag and store calculation
2726 // state in viewport properties
2727 jaa.autoCalculated = true; // means annotation will be marked for
2728 // update at end of load.
2730 if (an[i].hasGraphHeight())
2732 jaa.graphHeight = an[i].getGraphHeight();
2734 if (an[i].hasBelowAlignment())
2736 jaa.belowAlignment = an[i].isBelowAlignment();
2738 jaa.setCalcId(an[i].getCalcId());
2739 if (an[i].getPropertyCount() > 0)
2741 for (jalview.schemabinding.version2.Property prop : an[i]
2744 jaa.setProperty(prop.getName(), prop.getValue());
2747 if (jaa.autoCalculated)
2749 autoAlan.add(new JvAnnotRow(i, jaa));
2752 // if (!autoForView)
2754 // add autocalculated group annotation and any user created annotation
2756 al.addAnnotation(jaa);
2760 // ///////////////////////
2762 // Create alignment markup and styles for this view
2763 if (jms.getJGroupCount() > 0)
2765 JGroup[] groups = jms.getJGroup();
2766 boolean addAnnotSchemeGroup = false;
2767 for (int i = 0; i < groups.length; i++)
2769 ColourSchemeI cs = null;
2771 if (groups[i].getColour() != null)
2773 if (groups[i].getColour().startsWith("ucs"))
2775 cs = getUserColourScheme(jms, groups[i].getColour());
2777 else if (groups[i].getColour().equals("AnnotationColourGradient")
2778 && groups[i].getAnnotationColours() != null)
2780 addAnnotSchemeGroup = true;
2785 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2790 cs.setThreshold(groups[i].getPidThreshold(), true);
2794 Vector seqs = new Vector();
2796 for (int s = 0; s < groups[i].getSeqCount(); s++)
2798 String seqId = groups[i].getSeq(s) + "";
2799 jalview.datamodel.SequenceI ts = seqRefIds
2804 seqs.addElement(ts);
2808 if (seqs.size() < 1)
2813 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2814 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2815 groups[i].getDisplayText(), groups[i].getColourText(),
2816 groups[i].getStart(), groups[i].getEnd());
2818 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2820 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2821 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2822 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2823 .isShowUnconserved() : false);
2824 sg.thresholdTextColour = groups[i].getTextColThreshold();
2825 if (groups[i].hasShowConsensusHistogram())
2827 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2830 if (groups[i].hasShowSequenceLogo())
2832 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2834 if (groups[i].hasNormaliseSequenceLogo())
2836 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2838 if (groups[i].hasIgnoreGapsinConsensus())
2840 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2842 if (groups[i].getConsThreshold() != 0)
2844 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2845 "All", ResidueProperties.propHash, 3,
2846 sg.getSequences(null), 0, sg.getWidth() - 1);
2848 c.verdict(false, 25);
2849 sg.cs.setConservation(c);
2852 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2854 // re-instate unique group/annotation row reference
2855 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2856 .get(groups[i].getId());
2859 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2862 if (jaa.autoCalculated)
2864 // match up and try to set group autocalc alignment row for this
2866 if (jaa.label.startsWith("Consensus for "))
2868 sg.setConsensus(jaa);
2870 // match up and try to set group autocalc alignment row for this
2872 if (jaa.label.startsWith("Conservation for "))
2874 sg.setConservationRow(jaa);
2881 if (addAnnotSchemeGroup)
2883 // reconstruct the annotation colourscheme
2884 sg.cs = constructAnnotationColour(
2885 groups[i].getAnnotationColours(), null, al, jms, false);
2891 // only dataset in this model, so just return.
2894 // ///////////////////////////////
2897 // If we just load in the same jar file again, the sequenceSetId
2898 // will be the same, and we end up with multiple references
2899 // to the same sequenceSet. We must modify this id on load
2900 // so that each load of the file gives a unique id
2901 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2902 String viewId = (view.getId() == null ? null : view.getId()
2904 AlignFrame af = null;
2905 AlignViewport av = null;
2906 // now check to see if we really need to create a new viewport.
2907 if (multipleView && viewportsAdded.size() == 0)
2909 // We recovered an alignment for which a viewport already exists.
2910 // TODO: fix up any settings necessary for overlaying stored state onto
2911 // state recovered from another document. (may not be necessary).
2912 // we may need a binding from a viewport in memory to one recovered from
2914 // and then recover its containing af to allow the settings to be applied.
2915 // TODO: fix for vamsas demo
2917 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2919 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2920 if (seqsetobj != null)
2922 if (seqsetobj instanceof String)
2924 uniqueSeqSetId = (String) seqsetobj;
2926 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2932 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2938 * indicate that annotation colours are applied across all groups (pre
2939 * Jalview 2.8.1 behaviour)
2941 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2942 object.getVersion());
2944 AlignmentPanel ap = null;
2945 boolean isnewview = true;
2948 // Check to see if this alignment already has a view id == viewId
2949 jalview.gui.AlignmentPanel views[] = Desktop
2950 .getAlignmentPanels(uniqueSeqSetId);
2951 if (views != null && views.length > 0)
2953 for (int v = 0; v < views.length; v++)
2955 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2957 // recover the existing alignpanel, alignframe, viewport
2958 af = views[v].alignFrame;
2961 // TODO: could even skip resetting view settings if we don't want to
2962 // change the local settings from other jalview processes
2971 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
2972 uniqueSeqSetId, viewId, autoAlan);
2977 // /////////////////////////////////////
2978 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2982 for (int t = 0; t < jms.getTreeCount(); t++)
2985 Tree tree = jms.getTree(t);
2987 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2990 tp = af.ShowNewickTree(
2991 new jalview.io.NewickFile(tree.getNewick()),
2992 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2993 tree.getXpos(), tree.getYpos());
2994 if (tree.getId() != null)
2996 // perhaps bind the tree id to something ?
3001 // update local tree attributes ?
3002 // TODO: should check if tp has been manipulated by user - if so its
3003 // settings shouldn't be modified
3004 tp.setTitle(tree.getTitle());
3005 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3006 .getWidth(), tree.getHeight()));
3007 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3010 tp.treeCanvas.av = av; // af.viewport;
3011 tp.treeCanvas.ap = ap; // af.alignPanel;
3016 warn("There was a problem recovering stored Newick tree: \n"
3017 + tree.getNewick());
3021 tp.fitToWindow.setState(tree.getFitToWindow());
3022 tp.fitToWindow_actionPerformed(null);
3024 if (tree.getFontName() != null)
3026 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3027 .getFontStyle(), tree.getFontSize()));
3031 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3032 .getFontStyle(), tree.getFontSize()));
3035 tp.showPlaceholders(tree.getMarkUnlinked());
3036 tp.showBootstrap(tree.getShowBootstrap());
3037 tp.showDistances(tree.getShowDistances());
3039 tp.treeCanvas.threshold = tree.getThreshold();
3041 if (tree.getCurrentTree())
3043 af.viewport.setCurrentTree(tp.getTree());
3047 } catch (Exception ex)
3049 ex.printStackTrace();
3053 // //LOAD STRUCTURES
3054 if (loadTreesAndStructures)
3056 loadStructures(jprovider, jseqs, af, ap);
3058 // and finally return.
3063 * Load and link any saved structure viewers.
3070 protected void loadStructures(jarInputStreamProvider jprovider,
3071 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3073 // run through all PDB ids on the alignment, and collect mappings between
3074 // jmol view ids and all sequences referring to it
3075 Map<String, ViewerData> jmolViewIds = new HashMap<String, ViewerData>();
3077 for (int i = 0; i < jseqs.length; i++)
3079 if (jseqs[i].getPdbidsCount() > 0)
3081 Pdbids[] ids = jseqs[i].getPdbids();
3082 for (int p = 0; p < ids.length; p++)
3084 final int structureStateCount = ids[p].getStructureStateCount();
3085 for (int s = 0; s < structureStateCount; s++)
3087 // check to see if we haven't already created this structure view
3088 final StructureState structureState = ids[p].getStructureState(s);
3089 String sviewid = (structureState.getViewId() == null) ? null
3090 : structureState.getViewId()
3092 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3093 // Originally : ids[p].getFile()
3094 // : TODO: verify external PDB file recovery still works in normal
3095 // jalview project load
3096 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3097 jpdb.setId(ids[p].getId());
3099 int x = structureState.getXpos();
3100 int y = structureState.getYpos();
3101 int width = structureState.getWidth();
3102 int height = structureState.getHeight();
3104 // Probably don't need to do this anymore...
3105 // Desktop.desktop.getComponentAt(x, y);
3106 // TODO: NOW: check that this recovers the PDB file correctly.
3107 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3108 jalview.datamodel.SequenceI seq = seqRefIds
3109 .get(jseqs[i].getId() + "");
3110 if (sviewid == null)
3112 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3115 if (!jmolViewIds.containsKey(sviewid))
3117 jmolViewIds.put(sviewid, new ViewerData(x, y, width, height,
3118 false, false, true));
3119 // Legacy pre-2.7 conversion JAL-823 :
3120 // do not assume any view has to be linked for colour by
3124 // assemble String[] { pdb files }, String[] { id for each
3125 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3126 // seqs_file 2}, boolean[] {
3127 // linkAlignPanel,superposeWithAlignpanel}} from hash
3128 ViewerData jmoldat = jmolViewIds.get(sviewid);
3129 jmoldat.alignWithPanel |= structureState
3130 .hasAlignwithAlignPanel() ? structureState.getAlignwithAlignPanel() : false;
3131 // never colour by linked panel if not specified
3132 jmoldat.colourWithAlignPanel |= structureState
3133 .hasColourwithAlignPanel() ? structureState.getColourwithAlignPanel()
3135 // default for pre-2.7 projects is that Jmol colouring is enabled
3136 jmoldat.colourByViewer &= structureState
3137 .hasColourByJmol() ? structureState
3138 .getColourByJmol() : true;
3140 if (jmoldat.stateData.length() < structureState.getContent()
3144 jmoldat.stateData = structureState.getContent();
3147 if (ids[p].getFile() != null)
3149 File mapkey = new File(ids[p].getFile());
3150 Object[] seqstrmaps = jmoldat.fileData.get(mapkey);
3151 if (seqstrmaps == null)
3153 jmoldat.fileData.put(mapkey,
3154 seqstrmaps = new Object[]
3155 { pdbFile, ids[p].getId(), new Vector(),
3158 if (!((Vector) seqstrmaps[2]).contains(seq))
3160 ((Vector) seqstrmaps[2]).addElement(seq);
3161 // ((Vector)seqstrmaps[3]).addElement(n) :
3162 // in principle, chains
3163 // should be stored here : do we need to
3164 // TODO: store and recover seq/pdb_id :
3170 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");
3179 // Instantiate the associated Jmol views
3180 for (Entry<String, ViewerData> entry : jmolViewIds.entrySet())
3182 String sviewid = entry.getKey();
3183 ViewerData svattrib = entry.getValue();
3184 String state = svattrib.stateData;
3185 Map<File, Object[]> oldFiles = svattrib.fileData;
3186 final boolean useinJmolsuperpos = svattrib.alignWithPanel;
3187 final boolean usetoColourbyseq = svattrib.colourWithAlignPanel;
3188 final boolean jmolColouring = svattrib.colourByViewer;
3191 int width = svattrib.width;
3192 int height = svattrib.height;
3193 // collate the pdbfile -> sequence mappings from this view
3194 Vector<String> pdbfilenames = new Vector<String>();
3195 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
3196 Vector<String> pdbids = new Vector<String>();
3199 * Search for any Jmol windows already open from other alignment views
3200 * that exactly match the stored structure state
3202 AppJmol comp = null;
3203 JInternalFrame[] frames = getAllFrames();
3204 for (JInternalFrame frame : frames)
3206 if (frame instanceof AppJmol)
3209 * Post jalview 2.4 schema includes structure view id
3212 && ((StructureViewerBase) frame).getViewId().equals(
3215 comp = (AppJmol) frame;
3218 * Otherwise test for matching position and size of viewer frame
3220 else if (frame.getX() == x && frame.getY() == y
3221 && frame.getHeight() == height
3222 && frame.getWidth() == width)
3224 comp = (AppJmol) frame;
3232 * Create a new Jmol window. First parse the Jmol state to translate
3233 * filenames loaded into the view, and record the order in which files
3234 * are shown in the Jmol view, so we can add the sequence mappings in
3237 StringBuffer newFileLoc = null;
3238 int cp = 0, ncp, ecp;
3239 while ((ncp = state.indexOf("load ", cp)) > -1)
3241 if (newFileLoc == null)
3243 newFileLoc = new StringBuffer();
3247 // look for next filename in load statement
3248 newFileLoc.append(state.substring(cp,
3249 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3250 String oldfilenam = state.substring(ncp,
3251 ecp = state.indexOf("\"", ncp));
3252 // recover the new mapping data for this old filename
3253 // have to normalize filename - since Jmol and jalview do
3255 // translation differently.
3256 Object[] filedat = oldFiles.get(new File(oldfilenam));
3257 newFileLoc.append(Platform
3258 .escapeString((String) filedat[0]));
3259 pdbfilenames.addElement((String) filedat[0]);
3260 pdbids.addElement((String) filedat[1]);
3261 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3262 .toArray(new SequenceI[0]));
3263 newFileLoc.append("\"");
3264 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3265 // look for next file statement.
3266 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3270 // just append rest of state
3271 newFileLoc.append(state.substring(cp));
3276 .print("Ignoring incomplete Jmol state for PDB ids: ");
3277 newFileLoc = new StringBuffer(state);
3278 newFileLoc.append("; load append ");
3279 for (File id : oldFiles.keySet())
3281 // add this and any other pdb files that should be present in
3283 Object[] filedat = oldFiles.get(id);
3285 newFileLoc.append(((String) filedat[0]));
3286 pdbfilenames.addElement((String) filedat[0]);
3287 pdbids.addElement((String) filedat[1]);
3288 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3289 .toArray(new SequenceI[0]));
3290 newFileLoc.append(" \"");
3291 newFileLoc.append((String) filedat[0]);
3292 newFileLoc.append("\"");
3295 newFileLoc.append(";");
3298 if (newFileLoc != null)
3300 int histbug = newFileLoc.indexOf("history = ");
3302 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3304 String val = (diff == -1) ? null : newFileLoc.substring(
3306 if (val != null && val.length() >= 4)
3308 if (val.contains("e"))
3310 if (val.trim().equals("true"))
3318 newFileLoc.replace(histbug, diff, val);
3321 // TODO: assemble String[] { pdb files }, String[] { id for each
3322 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3323 // seqs_file 2}} from hash
3324 final String[] pdbf = pdbfilenames
3325 .toArray(new String[pdbfilenames.size()]), id = pdbids
3326 .toArray(new String[pdbids.size()]);
3327 final SequenceI[][] sq = seqmaps
3328 .toArray(new SequenceI[seqmaps.size()][]);
3329 final String fileloc = newFileLoc.toString(), vid = sviewid;
3330 final AlignFrame alf = af;
3331 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3335 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3340 JalviewStructureDisplayI sview = null;
3343 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3344 sview = new StructureViewer(alf.alignPanel
3345 .getStructureSelectionManager()).createView(
3346 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3348 useinJmolsuperpos, usetoColourbyseq,
3349 jmolColouring, fileloc, rect, vid);
3350 addNewStructureViewer(sview);
3351 } catch (OutOfMemoryError ex)
3353 new OOMWarning("restoring structure view for PDB id "
3354 + id, (OutOfMemoryError) ex.getCause());
3355 if (sview != null && sview.isVisible())
3357 sview.closeViewer();
3358 sview.setVisible(false);
3364 } catch (InvocationTargetException ex)
3366 warn("Unexpected error when opening Jmol view.", ex);
3368 } catch (InterruptedException e)
3370 // e.printStackTrace();
3376 // if (comp != null)
3378 linkStructureViewer(ap, comp, oldFiles, useinJmolsuperpos,
3379 usetoColourbyseq, jmolColouring);
3386 * Link an AlignmentPanel to an existing JMol viewer.
3391 * @param useinJmolsuperpos
3392 * @param usetoColourbyseq
3393 * @param jmolColouring
3395 protected void linkStructureViewer(AlignmentPanel ap, AppJmol viewer,
3396 Map<File, Object[]> oldFiles,
3397 final boolean useinJmolsuperpos, final boolean usetoColourbyseq,
3398 final boolean jmolColouring)
3400 // NOTE: if the jalview project is part of a shared session then
3401 // view synchronization should/could be done here.
3403 // add mapping for sequences in this view to an already open Jmol
3405 for (File id : oldFiles.keySet())
3407 // add this and any other pdb files that should be present in the
3409 Object[] filedat = oldFiles.get(id);
3410 String pdbFile = (String) filedat[0];
3411 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3412 .toArray(new SequenceI[0]);
3413 viewer.jmb.getSsm().setMapping(seq, null, pdbFile,
3414 jalview.io.AppletFormatAdapter.FILE);
3415 viewer.jmb.addSequenceForStructFile(pdbFile, seq);
3417 // and add the AlignmentPanel's reference to the Jmol view
3418 viewer.addAlignmentPanel(ap);
3419 if (useinJmolsuperpos)
3421 viewer.useAlignmentPanelForSuperposition(ap);
3425 viewer.excludeAlignmentPanelForSuperposition(ap);
3427 if (usetoColourbyseq)
3429 viewer.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3433 viewer.excludeAlignmentPanelForColourbyseq(ap);
3438 * Get all frames within the Desktop.
3442 protected JInternalFrame[] getAllFrames()
3444 JInternalFrame[] frames = null;
3445 // TODO is this necessary - is it safe - risk of hanging?
3450 frames = Desktop.desktop.getAllFrames();
3451 } catch (ArrayIndexOutOfBoundsException e)
3453 // occasional No such child exceptions are thrown here...
3457 } catch (InterruptedException f)
3461 } while (frames == null);
3468 * - minimum version we are comparing against
3470 * - version of data being processsed.
3471 * @return true if version is development/null or evaluates to the same or
3472 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3474 private boolean isVersionStringLaterThan(String supported, String version)
3476 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3477 || version.equalsIgnoreCase("Test")
3478 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3480 System.err.println("Assuming project file with "
3481 + (version == null ? "null" : version)
3482 + " is compatible with Jalview version " + supported);
3487 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3489 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3491 // convert b to decimal to catch bugfix releases within a series
3492 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3493 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3496 if (Float.valueOf(curT) > Float.valueOf(fileT))
3498 // current version is newer than the version that wrote the file
3501 } catch (NumberFormatException nfe)
3504 .println("** WARNING: Version comparison failed for tokens ("
3508 + ")\n** Current: '"
3509 + supported + "' and Version: '" + version + "'");
3512 if (currentV.hasMoreElements())
3514 // fileV has no minor version but identical series to current
3521 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3523 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3525 if (newStructureViewers != null)
3527 sview.getBinding().setFinishedLoadingFromArchive(false);
3528 newStructureViewers.add(sview);
3532 protected void setLoadingFinishedForNewStructureViewers()
3534 if (newStructureViewers != null)
3536 for (JalviewStructureDisplayI sview : newStructureViewers)
3538 sview.getBinding().setFinishedLoadingFromArchive(true);
3540 newStructureViewers.clear();
3541 newStructureViewers = null;
3545 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3546 Alignment al, JalviewModelSequence jms, Viewport view,
3547 String uniqueSeqSetId, String viewId,
3548 ArrayList<JvAnnotRow> autoAlan)
3550 AlignFrame af = null;
3551 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3552 uniqueSeqSetId, viewId);
3554 af.setFileName(file, "Jalview");
3556 for (int i = 0; i < JSEQ.length; i++)
3558 af.viewport.setSequenceColour(af.viewport.getAlignment()
3559 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3562 af.viewport.gatherViewsHere = view.getGatheredViews();
3564 if (view.getSequenceSetId() != null)
3566 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3567 .get(uniqueSeqSetId);
3569 af.viewport.setSequenceSetId(uniqueSeqSetId);
3572 // propagate shared settings to this new view
3573 af.viewport.historyList = av.historyList;
3574 af.viewport.redoList = av.redoList;
3578 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3580 // TODO: check if this method can be called repeatedly without
3581 // side-effects if alignpanel already registered.
3582 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3584 // apply Hidden regions to view.
3585 if (hiddenSeqs != null)
3587 for (int s = 0; s < JSEQ.length; s++)
3589 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3591 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3594 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3596 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3599 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3602 for (int s = 0; s < hiddenSeqs.size(); s++)
3604 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3607 af.viewport.hideSequence(hseqs);
3610 // recover view properties and display parameters
3611 if (view.getViewName() != null)
3613 af.viewport.viewName = view.getViewName();
3614 af.setInitialTabVisible();
3616 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3619 af.viewport.setShowAnnotation(view.getShowAnnotation());
3620 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3622 af.viewport.setColourText(view.getShowColourText());
3624 af.viewport.setConservationSelected(view.getConservationSelected());
3625 af.viewport.setShowJVSuffix(view.getShowFullId());
3626 af.viewport.setRightAlignIds(view.getRightAlignIds());
3627 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3628 .getFontStyle(), view.getFontSize()));
3629 af.alignPanel.fontChanged();
3630 af.viewport.setRenderGaps(view.getRenderGaps());
3631 af.viewport.setWrapAlignment(view.getWrapAlignment());
3632 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3633 af.viewport.setShowAnnotation(view.getShowAnnotation());
3634 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3636 af.viewport.setShowBoxes(view.getShowBoxes());
3638 af.viewport.setShowText(view.getShowText());
3640 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3641 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3642 af.viewport.thresholdTextColour = view.getTextColThreshold();
3643 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3644 .isShowUnconserved() : false);
3645 af.viewport.setStartRes(view.getStartRes());
3646 af.viewport.setStartSeq(view.getStartSeq());
3648 ColourSchemeI cs = null;
3649 // apply colourschemes
3650 if (view.getBgColour() != null)
3652 if (view.getBgColour().startsWith("ucs"))
3654 cs = getUserColourScheme(jms, view.getBgColour());
3656 else if (view.getBgColour().startsWith("Annotation"))
3658 AnnotationColours viewAnnColour = view.getAnnotationColours();
3659 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3666 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3671 cs.setThreshold(view.getPidThreshold(), true);
3672 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3676 af.viewport.setGlobalColourScheme(cs);
3677 af.viewport.setColourAppliesToAllGroups(false);
3679 if (view.getConservationSelected() && cs != null)
3681 cs.setConservationInc(view.getConsThreshold());
3684 af.changeColour(cs);
3686 af.viewport.setColourAppliesToAllGroups(true);
3688 if (view.getShowSequenceFeatures())
3690 af.viewport.showSequenceFeatures = true;
3692 if (view.hasCentreColumnLabels())
3694 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3696 if (view.hasIgnoreGapsinConsensus())
3698 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3701 if (view.hasFollowHighlight())
3703 af.viewport.followHighlight = view.getFollowHighlight();
3705 if (view.hasFollowSelection())
3707 af.viewport.followSelection = view.getFollowSelection();
3709 if (view.hasShowConsensusHistogram())
3711 af.viewport.setShowConsensusHistogram(view
3712 .getShowConsensusHistogram());
3716 af.viewport.setShowConsensusHistogram(true);
3718 if (view.hasShowSequenceLogo())
3720 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3724 af.viewport.setShowSequenceLogo(false);
3726 if (view.hasNormaliseSequenceLogo())
3728 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3730 if (view.hasShowDbRefTooltip())
3732 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3734 if (view.hasShowNPfeatureTooltip())
3736 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3738 if (view.hasShowGroupConsensus())
3740 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3744 af.viewport.setShowGroupConsensus(false);
3746 if (view.hasShowGroupConservation())
3748 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3752 af.viewport.setShowGroupConservation(false);
3755 // recover featre settings
3756 if (jms.getFeatureSettings() != null)
3758 af.viewport.setFeaturesDisplayed(new Hashtable());
3759 String[] renderOrder = new String[jms.getFeatureSettings()
3760 .getSettingCount()];
3761 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3763 Setting setting = jms.getFeatureSettings().getSetting(fs);
3764 if (setting.hasMincolour())
3766 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3767 new java.awt.Color(setting.getMincolour()),
3768 new java.awt.Color(setting.getColour()),
3769 setting.getMin(), setting.getMax()) : new GraduatedColor(
3770 new java.awt.Color(setting.getMincolour()),
3771 new java.awt.Color(setting.getColour()), 0, 1);
3772 if (setting.hasThreshold())
3774 gc.setThresh(setting.getThreshold());
3775 gc.setThreshType(setting.getThreshstate());
3777 gc.setAutoScaled(true); // default
3778 if (setting.hasAutoScale())
3780 gc.setAutoScaled(setting.getAutoScale());
3782 if (setting.hasColourByLabel())
3784 gc.setColourByLabel(setting.getColourByLabel());
3786 // and put in the feature colour table.
3787 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3788 setting.getType(), gc);
3792 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3794 new java.awt.Color(setting.getColour()));
3796 renderOrder[fs] = setting.getType();
3797 if (setting.hasOrder())
3799 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3800 setting.getType(), setting.getOrder());
3804 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3806 fs / jms.getFeatureSettings().getSettingCount());
3808 if (setting.getDisplay())
3810 af.viewport.getFeaturesDisplayed().put(setting.getType(), new Integer(
3811 setting.getColour()));
3814 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3816 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3817 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3819 Group grp = jms.getFeatureSettings().getGroup(gs);
3820 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3824 if (view.getHiddenColumnsCount() > 0)
3826 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3828 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3829 .getHiddenColumns(c).getEnd() // +1
3833 if (view.getCalcIdParam() != null)
3835 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3837 if (calcIdParam != null)
3839 if (recoverCalcIdParam(calcIdParam, af.viewport))
3844 warn("Couldn't recover parameters for "
3845 + calcIdParam.getCalcId());
3850 af.setMenusFromViewport(af.viewport);
3851 // TODO: we don't need to do this if the viewport is aready visible.
3852 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3854 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3855 reorderAutoannotation(af, al, autoAlan);
3856 af.alignPanel.alignmentChanged();
3860 private ColourSchemeI constructAnnotationColour(
3861 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3862 JalviewModelSequence jms, boolean checkGroupAnnColour)
3864 boolean propagateAnnColour = false;
3865 ColourSchemeI cs = null;
3866 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3867 if (checkGroupAnnColour && al.getGroups() != null
3868 && al.getGroups().size() > 0)
3870 // pre 2.8.1 behaviour
3871 // check to see if we should transfer annotation colours
3872 propagateAnnColour = true;
3873 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3875 if (sg.cs instanceof AnnotationColourGradient)
3877 propagateAnnColour = false;
3881 // int find annotation
3882 if (annAlignment.getAlignmentAnnotation() != null)
3884 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3886 if (annAlignment.getAlignmentAnnotation()[i].label
3887 .equals(viewAnnColour.getAnnotation()))
3889 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3891 annAlignment.getAlignmentAnnotation()[i]
3892 .setThreshold(new jalview.datamodel.GraphLine(
3893 viewAnnColour.getThreshold(), "Threshold",
3894 java.awt.Color.black)
3899 if (viewAnnColour.getColourScheme().equals("None"))
3901 cs = new AnnotationColourGradient(
3902 annAlignment.getAlignmentAnnotation()[i],
3903 new java.awt.Color(viewAnnColour.getMinColour()),
3904 new java.awt.Color(viewAnnColour.getMaxColour()),
3905 viewAnnColour.getAboveThreshold());
3907 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3909 cs = new AnnotationColourGradient(
3910 annAlignment.getAlignmentAnnotation()[i],
3911 getUserColourScheme(jms,
3912 viewAnnColour.getColourScheme()),
3913 viewAnnColour.getAboveThreshold());
3917 cs = new AnnotationColourGradient(
3918 annAlignment.getAlignmentAnnotation()[i],
3919 ColourSchemeProperty.getColour(al,
3920 viewAnnColour.getColourScheme()),
3921 viewAnnColour.getAboveThreshold());
3923 if (viewAnnColour.hasPerSequence())
3925 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3928 if (viewAnnColour.hasPredefinedColours())
3930 ((AnnotationColourGradient) cs)
3931 .setPredefinedColours(viewAnnColour
3932 .isPredefinedColours());
3934 if (propagateAnnColour && al.getGroups() != null)
3936 // Also use these settings for all the groups
3937 for (int g = 0; g < al.getGroups().size(); g++)
3939 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3947 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3948 * new AnnotationColourGradient(
3949 * annAlignment.getAlignmentAnnotation()[i], new
3950 * java.awt.Color(viewAnnColour. getMinColour()), new
3951 * java.awt.Color(viewAnnColour. getMaxColour()),
3952 * viewAnnColour.getAboveThreshold()); } else
3955 sg.cs = new AnnotationColourGradient(
3956 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3957 viewAnnColour.getAboveThreshold());
3958 if (cs instanceof AnnotationColourGradient)
3960 if (viewAnnColour.hasPerSequence())
3962 ((AnnotationColourGradient) cs)
3963 .setSeqAssociated(viewAnnColour.isPerSequence());
3965 if (viewAnnColour.hasPredefinedColours())
3967 ((AnnotationColourGradient) cs)
3968 .setPredefinedColours(viewAnnColour
3969 .isPredefinedColours());
3985 private void reorderAutoannotation(AlignFrame af, Alignment al,
3986 ArrayList<JvAnnotRow> autoAlan)
3988 // copy over visualization settings for autocalculated annotation in the
3990 if (al.getAlignmentAnnotation() != null)
3993 * Kludge for magic autoannotation names (see JAL-811)
3995 String[] magicNames = new String[]
3996 { "Consensus", "Quality", "Conservation" };
3997 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3998 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3999 for (String nm : magicNames)
4001 visan.put(nm, nullAnnot);
4003 for (JvAnnotRow auan : autoAlan)
4005 visan.put(auan.template.label
4006 + (auan.template.getCalcId() == null ? "" : "\t"
4007 + auan.template.getCalcId()), auan);
4009 int hSize = al.getAlignmentAnnotation().length;
4010 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4011 // work through any autoCalculated annotation already on the view
4012 // removing it if it should be placed in a different location on the
4013 // annotation panel.
4014 List<String> remains = new ArrayList(visan.keySet());
4015 for (int h = 0; h < hSize; h++)
4017 jalview.datamodel.AlignmentAnnotation jalan = al
4018 .getAlignmentAnnotation()[h];
4019 if (jalan.autoCalculated)
4022 JvAnnotRow valan = visan.get(k = jalan.label);
4023 if (jalan.getCalcId() != null)
4025 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4030 // delete the auto calculated row from the alignment
4031 al.deleteAnnotation(jalan, false);
4035 if (valan != nullAnnot)
4037 if (jalan != valan.template)
4039 // newly created autoannotation row instance
4040 // so keep a reference to the visible annotation row
4041 // and copy over all relevant attributes
4042 if (valan.template.graphHeight >= 0)
4045 jalan.graphHeight = valan.template.graphHeight;
4047 jalan.visible = valan.template.visible;
4049 reorder.add(new JvAnnotRow(valan.order, jalan));
4054 // Add any (possibly stale) autocalculated rows that were not appended to
4055 // the view during construction
4056 for (String other : remains)
4058 JvAnnotRow othera = visan.get(other);
4059 if (othera != nullAnnot && othera.template.getCalcId() != null
4060 && othera.template.getCalcId().length() > 0)
4062 reorder.add(othera);
4065 // now put the automatic annotation in its correct place
4066 int s = 0, srt[] = new int[reorder.size()];
4067 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4068 for (JvAnnotRow jvar : reorder)
4071 srt[s++] = jvar.order;
4074 jalview.util.QuickSort.sort(srt, rws);
4075 // and re-insert the annotation at its correct position
4076 for (JvAnnotRow jvar : rws)
4078 al.addAnnotation(jvar.template, jvar.order);
4080 af.alignPanel.adjustAnnotationHeight();
4084 Hashtable skipList = null;
4087 * TODO remove this method
4090 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4091 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4092 * throw new Error("Implementation Error. No skipList defined for this
4093 * Jalview2XML instance."); } return (AlignFrame)
4094 * skipList.get(view.getSequenceSetId()); }
4098 * Check if the Jalview view contained in object should be skipped or not.
4101 * @return true if view's sequenceSetId is a key in skipList
4103 private boolean skipViewport(JalviewModel object)
4105 if (skipList == null)
4110 if (skipList.containsKey(id = object.getJalviewModelSequence()
4111 .getViewport()[0].getSequenceSetId()))
4113 if (Cache.log != null && Cache.log.isDebugEnabled())
4115 Cache.log.debug("Skipping seuqence set id " + id);
4122 public void addToSkipList(AlignFrame af)
4124 if (skipList == null)
4126 skipList = new Hashtable();
4128 skipList.put(af.getViewport().getSequenceSetId(), af);
4131 public void clearSkipList()
4133 if (skipList != null)
4140 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4141 boolean ignoreUnrefed)
4143 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4144 Vector dseqs = null;
4147 // create a list of new dataset sequences
4148 dseqs = new Vector();
4150 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4152 Sequence vamsasSeq = vamsasSet.getSequence(i);
4153 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4155 // create a new dataset
4158 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4159 dseqs.copyInto(dsseqs);
4160 ds = new jalview.datamodel.Alignment(dsseqs);
4161 debug("Created new dataset " + vamsasSet.getDatasetId()
4162 + " for alignment " + System.identityHashCode(al));
4163 addDatasetRef(vamsasSet.getDatasetId(), ds);
4165 // set the dataset for the newly imported alignment.
4166 if (al.getDataset() == null && !ignoreUnrefed)
4175 * sequence definition to create/merge dataset sequence for
4179 * vector to add new dataset sequence to
4181 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4182 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4184 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4186 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4187 .get(vamsasSeq.getId());
4188 jalview.datamodel.SequenceI dsq = null;
4189 if (sq != null && sq.getDatasetSequence() != null)
4191 dsq = sq.getDatasetSequence();
4193 if (sq == null && ignoreUnrefed)
4197 String sqid = vamsasSeq.getDsseqid();
4200 // need to create or add a new dataset sequence reference to this sequence
4203 dsq = seqRefIds.get(sqid);
4208 // make a new dataset sequence
4209 dsq = sq.createDatasetSequence();
4212 // make up a new dataset reference for this sequence
4213 sqid = seqHash(dsq);
4215 dsq.setVamsasId(uniqueSetSuffix + sqid);
4216 seqRefIds.put(sqid, dsq);
4221 dseqs.addElement(dsq);
4226 ds.addSequence(dsq);
4232 { // make this dataset sequence sq's dataset sequence
4233 sq.setDatasetSequence(dsq);
4234 // and update the current dataset alignment
4239 if (!dseqs.contains(dsq))
4246 if (ds.findIndex(dsq) < 0)
4248 ds.addSequence(dsq);
4255 // TODO: refactor this as a merge dataset sequence function
4256 // now check that sq (the dataset sequence) sequence really is the union of
4257 // all references to it
4258 // boolean pre = sq.getStart() < dsq.getStart();
4259 // boolean post = sq.getEnd() > dsq.getEnd();
4263 StringBuffer sb = new StringBuffer();
4264 String newres = jalview.analysis.AlignSeq.extractGaps(
4265 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4266 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4267 && newres.length() > dsq.getLength())
4269 // Update with the longer sequence.
4273 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4274 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4275 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4276 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4278 dsq.setSequence(newres);
4280 // TODO: merges will never happen if we 'know' we have the real dataset
4281 // sequence - this should be detected when id==dssid
4283 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4284 // + (pre ? "prepended" : "") + " "
4285 // + (post ? "appended" : ""));
4290 java.util.Hashtable datasetIds = null;
4292 java.util.IdentityHashMap dataset2Ids = null;
4294 private Alignment getDatasetFor(String datasetId)
4296 if (datasetIds == null)
4298 datasetIds = new Hashtable();
4301 if (datasetIds.containsKey(datasetId))
4303 return (Alignment) datasetIds.get(datasetId);
4308 private void addDatasetRef(String datasetId, Alignment dataset)
4310 if (datasetIds == null)
4312 datasetIds = new Hashtable();
4314 datasetIds.put(datasetId, dataset);
4318 * make a new dataset ID for this jalview dataset alignment
4323 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4325 if (dataset.getDataset() != null)
4327 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4329 String datasetId = makeHashCode(dataset, null);
4330 if (datasetId == null)
4332 // make a new datasetId and record it
4333 if (dataset2Ids == null)
4335 dataset2Ids = new IdentityHashMap();
4339 datasetId = (String) dataset2Ids.get(dataset);
4341 if (datasetId == null)
4343 datasetId = "ds" + dataset2Ids.size() + 1;
4344 dataset2Ids.put(dataset, datasetId);
4350 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4352 for (int d = 0; d < sequence.getDBRefCount(); d++)
4354 DBRef dr = sequence.getDBRef(d);
4355 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4356 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4357 .getVersion(), sequence.getDBRef(d).getAccessionId());
4358 if (dr.getMapping() != null)
4360 entry.setMap(addMapping(dr.getMapping()));
4362 datasetSequence.addDBRef(entry);
4366 private jalview.datamodel.Mapping addMapping(Mapping m)
4368 SequenceI dsto = null;
4369 // Mapping m = dr.getMapping();
4370 int fr[] = new int[m.getMapListFromCount() * 2];
4371 Enumeration f = m.enumerateMapListFrom();
4372 for (int _i = 0; f.hasMoreElements(); _i += 2)
4374 MapListFrom mf = (MapListFrom) f.nextElement();
4375 fr[_i] = mf.getStart();
4376 fr[_i + 1] = mf.getEnd();
4378 int fto[] = new int[m.getMapListToCount() * 2];
4379 f = m.enumerateMapListTo();
4380 for (int _i = 0; f.hasMoreElements(); _i += 2)
4382 MapListTo mf = (MapListTo) f.nextElement();
4383 fto[_i] = mf.getStart();
4384 fto[_i + 1] = mf.getEnd();
4386 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4387 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4388 if (m.getMappingChoice() != null)
4390 MappingChoice mc = m.getMappingChoice();
4391 if (mc.getDseqFor() != null)
4393 String dsfor = "" + mc.getDseqFor();
4394 if (seqRefIds.containsKey(dsfor))
4399 jmap.setTo(seqRefIds.get(dsfor));
4403 frefedSequence.add(new Object[]
4410 * local sequence definition
4412 Sequence ms = mc.getSequence();
4413 jalview.datamodel.Sequence djs = null;
4414 String sqid = ms.getDsseqid();
4415 if (sqid != null && sqid.length() > 0)
4418 * recover dataset sequence
4420 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4425 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4426 sqid = ((Object) ms).toString(); // make up a new hascode for
4427 // undefined dataset sequence hash
4428 // (unlikely to happen)
4434 * make a new dataset sequence and add it to refIds hash
4436 djs = new jalview.datamodel.Sequence(ms.getName(),
4438 djs.setStart(jmap.getMap().getToLowest());
4439 djs.setEnd(jmap.getMap().getToHighest());
4440 djs.setVamsasId(uniqueSetSuffix + sqid);
4442 seqRefIds.put(sqid, djs);
4445 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4454 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4455 boolean keepSeqRefs)
4458 jalview.schemabinding.version2.JalviewModel jm = saveState(ap, null,
4464 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4468 uniqueSetSuffix = "";
4469 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4474 if (this.frefedSequence == null)
4476 frefedSequence = new Vector();
4479 viewportsAdded = new Hashtable();
4481 AlignFrame af = loadFromObject(jm, null, false, null);
4482 af.alignPanels.clear();
4483 af.closeMenuItem_actionPerformed(true);
4486 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4487 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4488 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4489 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4490 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4493 return af.alignPanel;
4497 * flag indicating if hashtables should be cleared on finalization TODO this
4498 * flag may not be necessary
4500 private final boolean _cleartables = true;
4502 private Hashtable jvids2vobj;
4507 * @see java.lang.Object#finalize()
4510 protected void finalize() throws Throwable
4512 // really make sure we have no buried refs left.
4517 this.seqRefIds = null;
4518 this.seqsToIds = null;
4522 private void warn(String msg)
4527 private void warn(String msg, Exception e)
4529 if (Cache.log != null)
4533 Cache.log.warn(msg, e);
4537 Cache.log.warn(msg);
4542 System.err.println("Warning: " + msg);
4545 e.printStackTrace();
4550 private void debug(String string)
4552 debug(string, null);
4555 private void debug(String msg, Exception e)
4557 if (Cache.log != null)
4561 Cache.log.debug(msg, e);
4565 Cache.log.debug(msg);
4570 System.err.println("Warning: " + msg);
4573 e.printStackTrace();
4579 * set the object to ID mapping tables used to write/recover objects and XML
4580 * ID strings for the jalview project. If external tables are provided then
4581 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4582 * object goes out of scope. - also populates the datasetIds hashtable with
4583 * alignment objects containing dataset sequences
4586 * Map from ID strings to jalview datamodel
4588 * Map from jalview datamodel to ID strings
4592 public void setObjectMappingTables(Hashtable vobj2jv,
4593 IdentityHashMap jv2vobj)
4595 this.jv2vobj = jv2vobj;
4596 this.vobj2jv = vobj2jv;
4597 Iterator ds = jv2vobj.keySet().iterator();
4599 while (ds.hasNext())
4601 Object jvobj = ds.next();
4602 id = jv2vobj.get(jvobj).toString();
4603 if (jvobj instanceof jalview.datamodel.Alignment)
4605 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4607 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4610 else if (jvobj instanceof jalview.datamodel.Sequence)
4612 // register sequence object so the XML parser can recover it.
4613 if (seqRefIds == null)
4615 seqRefIds = new HashMap<String, SequenceI>();
4617 if (seqsToIds == null)
4619 seqsToIds = new IdentityHashMap<SequenceI, String>();
4621 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4622 seqsToIds.put((SequenceI) jvobj, id);
4624 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4626 if (annotationIds == null)
4628 annotationIds = new Hashtable();
4631 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4632 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4633 if (jvann.annotationId == null)
4635 jvann.annotationId = anid;
4637 if (!jvann.annotationId.equals(anid))
4639 // TODO verify that this is the correct behaviour
4640 this.warn("Overriding Annotation ID for " + anid
4641 + " from different id : " + jvann.annotationId);
4642 jvann.annotationId = anid;
4645 else if (jvobj instanceof String)
4647 if (jvids2vobj == null)
4649 jvids2vobj = new Hashtable();
4650 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4655 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4661 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4662 * objects created from the project archive. If string is null (default for
4663 * construction) then suffix will be set automatically.
4667 public void setUniqueSetSuffix(String string)
4669 uniqueSetSuffix = string;
4674 * uses skipList2 as the skipList for skipping views on sequence sets
4675 * associated with keys in the skipList
4679 public void setSkipList(Hashtable skipList2)
4681 skipList = skipList2;