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.datamodel.ViewerData;
31 import jalview.datamodel.ViewerData.StructureData;
32 import jalview.schemabinding.version2.AlcodMap;
33 import jalview.schemabinding.version2.Alcodon;
34 import jalview.schemabinding.version2.AlcodonFrame;
35 import jalview.schemabinding.version2.Annotation;
36 import jalview.schemabinding.version2.AnnotationColours;
37 import jalview.schemabinding.version2.AnnotationElement;
38 import jalview.schemabinding.version2.CalcIdParam;
39 import jalview.schemabinding.version2.DBRef;
40 import jalview.schemabinding.version2.Features;
41 import jalview.schemabinding.version2.Group;
42 import jalview.schemabinding.version2.HiddenColumns;
43 import jalview.schemabinding.version2.JGroup;
44 import jalview.schemabinding.version2.JSeq;
45 import jalview.schemabinding.version2.JalviewModel;
46 import jalview.schemabinding.version2.JalviewModelSequence;
47 import jalview.schemabinding.version2.MapListFrom;
48 import jalview.schemabinding.version2.MapListTo;
49 import jalview.schemabinding.version2.Mapping;
50 import jalview.schemabinding.version2.MappingChoice;
51 import jalview.schemabinding.version2.OtherData;
52 import jalview.schemabinding.version2.PdbentryItem;
53 import jalview.schemabinding.version2.Pdbids;
54 import jalview.schemabinding.version2.Property;
55 import jalview.schemabinding.version2.Sequence;
56 import jalview.schemabinding.version2.SequenceSet;
57 import jalview.schemabinding.version2.SequenceSetProperties;
58 import jalview.schemabinding.version2.Setting;
59 import jalview.schemabinding.version2.StructureState;
60 import jalview.schemabinding.version2.ThresholdLine;
61 import jalview.schemabinding.version2.Tree;
62 import jalview.schemabinding.version2.UserColours;
63 import jalview.schemabinding.version2.Viewport;
64 import jalview.schemes.AnnotationColourGradient;
65 import jalview.schemes.ColourSchemeI;
66 import jalview.schemes.ColourSchemeProperty;
67 import jalview.schemes.GraduatedColor;
68 import jalview.schemes.ResidueColourScheme;
69 import jalview.schemes.ResidueProperties;
70 import jalview.schemes.UserColourScheme;
71 import jalview.structure.StructureSelectionManager;
72 import jalview.structures.models.AAStructureBindingModel;
73 import jalview.util.MessageManager;
74 import jalview.util.Platform;
75 import jalview.util.jarInputStreamProvider;
76 import jalview.viewmodel.AlignmentViewport;
77 import jalview.ws.jws2.Jws2Discoverer;
78 import jalview.ws.jws2.dm.AAConSettings;
79 import jalview.ws.jws2.jabaws2.Jws2Instance;
80 import jalview.ws.params.ArgumentI;
81 import jalview.ws.params.AutoCalcSetting;
82 import jalview.ws.params.WsParamSetI;
84 import java.awt.Rectangle;
85 import java.io.BufferedReader;
86 import java.io.DataInputStream;
87 import java.io.DataOutputStream;
89 import java.io.FileInputStream;
90 import java.io.FileOutputStream;
91 import java.io.IOException;
92 import java.io.InputStreamReader;
93 import java.io.OutputStreamWriter;
94 import java.io.PrintWriter;
95 import java.lang.reflect.InvocationTargetException;
96 import java.net.MalformedURLException;
98 import java.util.ArrayList;
99 import java.util.Enumeration;
100 import java.util.HashMap;
101 import java.util.HashSet;
102 import java.util.Hashtable;
103 import java.util.IdentityHashMap;
104 import java.util.Iterator;
105 import java.util.LinkedHashMap;
106 import java.util.List;
107 import java.util.Map;
108 import java.util.Map.Entry;
109 import java.util.Set;
110 import java.util.StringTokenizer;
111 import java.util.Vector;
112 import java.util.jar.JarEntry;
113 import java.util.jar.JarInputStream;
114 import java.util.jar.JarOutputStream;
116 import javax.swing.JInternalFrame;
117 import javax.swing.JOptionPane;
118 import javax.swing.SwingUtilities;
120 import org.exolab.castor.xml.Unmarshaller;
123 * Write out the current jalview desktop state as a Jalview XML stream.
125 * Note: the vamsas objects referred to here are primitive versions of the
126 * VAMSAS project schema elements - they are not the same and most likely never
130 * @version $Revision: 1.134 $
132 public class Jalview2XML
135 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
136 * of sequence objects are created.
138 IdentityHashMap<SequenceI, String> seqsToIds = null;
141 * jalview XML Sequence ID to jalview sequence object reference (both dataset
142 * and alignment sequences. Populated as XML reps of sequence objects are
145 Map<String, SequenceI> seqRefIds = null;
147 Vector frefedSequence = null;
149 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
152 * create/return unique hash string for sq
155 * @return new or existing unique string for sq
157 String seqHash(SequenceI sq)
159 if (seqsToIds == null)
163 if (seqsToIds.containsKey(sq))
165 return seqsToIds.get(sq);
169 // create sequential key
170 String key = "sq" + (seqsToIds.size() + 1);
171 key = makeHashCode(sq, key); // check we don't have an external reference
173 seqsToIds.put(sq, key);
182 if (seqRefIds != null)
186 if (seqsToIds != null)
196 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
197 // seqRefIds = new Hashtable();
198 // seqsToIds = new IdentityHashMap();
204 if (seqsToIds == null)
206 seqsToIds = new IdentityHashMap<SequenceI, String>();
208 if (seqRefIds == null)
210 seqRefIds = new HashMap<String, SequenceI>();
218 public Jalview2XML(boolean raiseGUI)
220 this.raiseGUI = raiseGUI;
223 public void resolveFrefedSequences()
225 if (frefedSequence.size() > 0)
227 int r = 0, rSize = frefedSequence.size();
230 Object[] ref = (Object[]) frefedSequence.elementAt(r);
233 String sref = (String) ref[0];
234 if (seqRefIds.containsKey(sref))
236 if (ref[1] instanceof jalview.datamodel.Mapping)
238 SequenceI seq = seqRefIds.get(sref);
239 while (seq.getDatasetSequence() != null)
241 seq = seq.getDatasetSequence();
243 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
247 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
249 SequenceI seq = seqRefIds.get(sref);
250 while (seq.getDatasetSequence() != null)
252 seq = seq.getDatasetSequence();
255 && ref[2] instanceof jalview.datamodel.Mapping)
257 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
258 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
259 seq, mp.getTo(), mp.getMap());
264 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
265 + ref[2].getClass() + " type objects.");
271 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
272 + ref[1].getClass() + " type objects.");
275 frefedSequence.remove(r);
281 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
283 + " with objecttype "
284 + ref[1].getClass());
291 frefedSequence.remove(r);
299 * This maintains a list of viewports, the key being the seqSetId. Important
300 * to set historyItem and redoList for multiple views
302 Hashtable viewportsAdded;
304 Hashtable annotationIds = new Hashtable();
306 String uniqueSetSuffix = "";
309 * List of pdbfiles added to Jar
311 List<String> pdbfiles = null;
313 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
314 public void saveState(File statefile)
316 FileOutputStream fos = null;
319 fos = new FileOutputStream(statefile);
320 JarOutputStream jout = new JarOutputStream(fos);
323 } catch (Exception e)
325 // TODO: inform user of the problem - they need to know if their data was
327 if (errorMessage == null)
329 errorMessage = "Couldn't write Jalview Archive to output file '"
330 + statefile + "' - See console error log for details";
334 errorMessage += "(output file was '" + statefile + "')";
344 } catch (IOException e)
354 * Writes a jalview project archive to the given Jar output stream.
358 public void saveState(JarOutputStream jout)
360 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
367 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
372 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
373 // //////////////////////////////////////////////////
375 Vector shortNames = new Vector();
378 for (int i = frames.length - 1; i > -1; i--)
380 if (frames[i] instanceof AlignFrame)
382 AlignFrame af = (AlignFrame) frames[i];
385 && skipList.containsKey(af.getViewport()
386 .getSequenceSetId()))
391 String shortName = af.getTitle();
393 if (shortName.indexOf(File.separatorChar) > -1)
395 shortName = shortName.substring(shortName
396 .lastIndexOf(File.separatorChar) + 1);
401 while (shortNames.contains(shortName))
403 if (shortName.endsWith("_" + (count - 1)))
405 shortName = shortName
406 .substring(0, shortName.lastIndexOf("_"));
409 shortName = shortName.concat("_" + count);
413 shortNames.addElement(shortName);
415 if (!shortName.endsWith(".xml"))
417 shortName = shortName + ".xml";
420 int ap, apSize = af.alignPanels.size();
422 for (ap = 0; ap < apSize; ap++)
424 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
426 String fileName = apSize == 1 ? shortName : ap + shortName;
427 if (!fileName.endsWith(".xml"))
429 fileName = fileName + ".xml";
432 saveState(apanel, fileName, jout);
434 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
436 if (!dsses.containsKey(dssid))
438 dsses.put(dssid, af);
445 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
451 } catch (Exception foo)
456 } catch (Exception ex)
458 // TODO: inform user of the problem - they need to know if their data was
460 if (errorMessage == null)
462 errorMessage = "Couldn't write Jalview Archive - see error output for details";
464 ex.printStackTrace();
468 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
469 public boolean saveAlignment(AlignFrame af, String jarFile,
474 int ap, apSize = af.alignPanels.size();
475 FileOutputStream fos = new FileOutputStream(jarFile);
476 JarOutputStream jout = new JarOutputStream(fos);
477 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
478 for (ap = 0; ap < apSize; ap++)
480 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
482 String jfileName = apSize == 1 ? fileName : fileName + ap;
483 if (!jfileName.endsWith(".xml"))
485 jfileName = jfileName + ".xml";
487 saveState(apanel, jfileName, jout);
488 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
490 if (!dsses.containsKey(dssid))
492 dsses.put(dssid, af);
495 writeDatasetFor(dsses, fileName, jout);
499 } catch (Exception foo)
505 } catch (Exception ex)
507 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
508 ex.printStackTrace();
513 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
514 String fileName, JarOutputStream jout)
517 for (String dssids : dsses.keySet())
519 AlignFrame _af = dsses.get(dssids);
520 String jfileName = fileName + " Dataset for " + _af.getTitle();
521 if (!jfileName.endsWith(".xml"))
523 jfileName = jfileName + ".xml";
525 saveState(_af.alignPanel, jfileName, true, jout);
530 * create a JalviewModel from an alignment view and marshall it to a
534 * panel to create jalview model for
536 * name of alignment panel written to output stream
542 public JalviewModel saveState(AlignmentPanel ap, String fileName,
543 JarOutputStream jout)
545 return saveState(ap, fileName, false, jout);
549 * create a JalviewModel from an alignment view and marshall it to a
553 * panel to create jalview model for
555 * name of alignment panel written to output stream
557 * when true, only write the dataset for the alignment, not the data
558 * associated with the view.
564 public JalviewModel saveState(AlignmentPanel ap, String fileName,
565 boolean storeDS, JarOutputStream jout)
568 List<String> viewIds = new ArrayList<String>();
569 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
571 AlignViewport av = ap.av;
573 JalviewModel object = new JalviewModel();
574 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
576 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
577 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
578 "Development Build"));
580 jalview.datamodel.AlignmentI jal = av.getAlignment();
582 if (av.hasHiddenRows())
584 jal = jal.getHiddenSequences().getFullAlignment();
587 SequenceSet vamsasSet = new SequenceSet();
589 JalviewModelSequence jms = new JalviewModelSequence();
591 vamsasSet.setGapChar(jal.getGapCharacter() + "");
593 if (jal.getDataset() != null)
595 // dataset id is the dataset's hashcode
596 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
599 // switch jal and the dataset
600 jal = jal.getDataset();
603 if (jal.getProperties() != null)
605 Enumeration en = jal.getProperties().keys();
606 while (en.hasMoreElements())
608 String key = en.nextElement().toString();
609 SequenceSetProperties ssp = new SequenceSetProperties();
611 ssp.setValue(jal.getProperties().get(key).toString());
612 vamsasSet.addSequenceSetProperties(ssp);
617 Set<String> calcIdSet = new HashSet<String>();
621 jalview.datamodel.SequenceI jds, jdatasq;
622 for (int i = 0; i < jal.getHeight(); i++)
624 jds = jal.getSequenceAt(i);
625 jdatasq = jds.getDatasetSequence() == null ? jds : jds
626 .getDatasetSequence();
629 if (seqRefIds.get(id) != null)
631 // This happens for two reasons: 1. multiple views are being serialised.
632 // 2. the hashCode has collided with another sequence's code. This DOES
633 // HAPPEN! (PF00072.15.stk does this)
634 // JBPNote: Uncomment to debug writing out of files that do not read
635 // back in due to ArrayOutOfBoundExceptions.
636 // System.err.println("vamsasSeq backref: "+id+"");
637 // System.err.println(jds.getName()+"
638 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
639 // System.err.println("Hashcode: "+seqHash(jds));
640 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
641 // System.err.println(rsq.getName()+"
642 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
643 // System.err.println("Hashcode: "+seqHash(rsq));
647 vamsasSeq = createVamsasSequence(id, jds);
648 vamsasSet.addSequence(vamsasSeq);
649 seqRefIds.put(id, jds);
653 jseq.setStart(jds.getStart());
654 jseq.setEnd(jds.getEnd());
655 jseq.setColour(av.getSequenceColour(jds).getRGB());
657 jseq.setId(id); // jseq id should be a string not a number
660 // Store any sequences this sequence represents
661 if (av.hasHiddenRows())
663 jseq.setHidden(av.getAlignment().getHiddenSequences()
666 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
668 jalview.datamodel.SequenceI[] reps = av
669 .getRepresentedSequences(jal.getSequenceAt(i))
670 .getSequencesInOrder(jal);
672 for (int h = 0; h < reps.length; h++)
674 if (reps[h] != jal.getSequenceAt(i))
676 jseq.addHiddenSequences(jal.findIndex(reps[h]));
683 if (jdatasq.getSequenceFeatures() != null)
685 jalview.datamodel.SequenceFeature[] sf = jdatasq
686 .getSequenceFeatures();
688 while (index < sf.length)
690 Features features = new Features();
692 features.setBegin(sf[index].getBegin());
693 features.setEnd(sf[index].getEnd());
694 features.setDescription(sf[index].getDescription());
695 features.setType(sf[index].getType());
696 features.setFeatureGroup(sf[index].getFeatureGroup());
697 features.setScore(sf[index].getScore());
698 if (sf[index].links != null)
700 for (int l = 0; l < sf[index].links.size(); l++)
702 OtherData keyValue = new OtherData();
703 keyValue.setKey("LINK_" + l);
704 keyValue.setValue(sf[index].links.elementAt(l).toString());
705 features.addOtherData(keyValue);
708 if (sf[index].otherDetails != null)
711 Enumeration keys = sf[index].otherDetails.keys();
712 while (keys.hasMoreElements())
714 key = keys.nextElement().toString();
715 OtherData keyValue = new OtherData();
716 keyValue.setKey(key);
717 keyValue.setValue(sf[index].otherDetails.get(key).toString());
718 features.addOtherData(keyValue);
722 jseq.addFeatures(features);
727 if (jdatasq.getPDBId() != null)
729 Enumeration en = jdatasq.getPDBId().elements();
730 while (en.hasMoreElements())
732 Pdbids pdb = new Pdbids();
733 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
736 pdb.setId(entry.getId());
737 pdb.setType(entry.getType());
740 * Store any structure views associated with this sequence. This
741 * section copes with duplicate entries in the project, so a dataset
742 * only view *should* be coped with sensibly.
744 // This must have been loaded, is it still visible?
745 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
746 String matchedFile = null;
747 for (int f = frames.length - 1; f > -1; f--)
749 if (frames[f] instanceof StructureViewerBase)
751 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
752 matchedFile = saveStructureState(ap, jds, pdb, entry,
753 viewIds, matchedFile, viewFrame);
757 if (matchedFile != null || entry.getFile() != null)
759 if (entry.getFile() != null)
762 matchedFile = entry.getFile();
764 pdb.setFile(matchedFile); // entry.getFile());
765 if (pdbfiles == null)
767 pdbfiles = new ArrayList<String>();
770 if (!pdbfiles.contains(entry.getId()))
772 pdbfiles.add(entry.getId());
773 DataInputStream dis = null;
776 File file = new File(matchedFile);
777 if (file.exists() && jout != null)
779 byte[] data = new byte[(int) file.length()];
780 jout.putNextEntry(new JarEntry(entry.getId()));
781 dis = new DataInputStream(
782 new FileInputStream(file));
785 DataOutputStream dout = new DataOutputStream(jout);
786 dout.write(data, 0, data.length);
790 } catch (Exception ex)
792 ex.printStackTrace();
800 } catch (IOException e)
810 if (entry.getProperty() != null)
812 PdbentryItem item = new PdbentryItem();
813 Hashtable properties = entry.getProperty();
814 Enumeration en2 = properties.keys();
815 while (en2.hasMoreElements())
817 Property prop = new Property();
818 String key = en2.nextElement().toString();
820 prop.setValue(properties.get(key).toString());
821 item.addProperty(prop);
823 pdb.addPdbentryItem(item);
833 if (!storeDS && av.hasHiddenRows())
835 jal = av.getAlignment();
838 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
840 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
841 for (int i = 0; i < jac.length; i++)
843 AlcodonFrame alc = new AlcodonFrame();
844 vamsasSet.addAlcodonFrame(alc);
845 for (int p = 0; p < jac[i].aaWidth; p++)
847 Alcodon cmap = new Alcodon();
848 if (jac[i].codons[p] != null)
850 // Null codons indicate a gapped column in the translated peptide
852 cmap.setPos1(jac[i].codons[p][0]);
853 cmap.setPos2(jac[i].codons[p][1]);
854 cmap.setPos3(jac[i].codons[p][2]);
856 alc.addAlcodon(cmap);
858 if (jac[i].getProtMappings() != null
859 && jac[i].getProtMappings().length > 0)
861 SequenceI[] dnas = jac[i].getdnaSeqs();
862 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
863 for (int m = 0; m < pmaps.length; m++)
865 AlcodMap alcmap = new AlcodMap();
866 alcmap.setDnasq(seqHash(dnas[m]));
867 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
869 alc.addAlcodMap(alcmap);
876 // /////////////////////////////////
877 if (!storeDS && av.currentTree != null)
879 // FIND ANY ASSOCIATED TREES
880 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
881 if (Desktop.desktop != null)
883 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
885 for (int t = 0; t < frames.length; t++)
887 if (frames[t] instanceof TreePanel)
889 TreePanel tp = (TreePanel) frames[t];
891 if (tp.treeCanvas.av.getAlignment() == jal)
893 Tree tree = new Tree();
894 tree.setTitle(tp.getTitle());
895 tree.setCurrentTree((av.currentTree == tp.getTree()));
896 tree.setNewick(tp.getTree().toString());
897 tree.setThreshold(tp.treeCanvas.threshold);
899 tree.setFitToWindow(tp.fitToWindow.getState());
900 tree.setFontName(tp.getTreeFont().getName());
901 tree.setFontSize(tp.getTreeFont().getSize());
902 tree.setFontStyle(tp.getTreeFont().getStyle());
903 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
905 tree.setShowBootstrap(tp.bootstrapMenu.getState());
906 tree.setShowDistances(tp.distanceMenu.getState());
908 tree.setHeight(tp.getHeight());
909 tree.setWidth(tp.getWidth());
910 tree.setXpos(tp.getX());
911 tree.setYpos(tp.getY());
912 tree.setId(makeHashCode(tp, null));
921 * store forward refs from an annotationRow to any groups
923 IdentityHashMap groupRefs = new IdentityHashMap();
926 for (SequenceI sq : jal.getSequences())
928 // Store annotation on dataset sequences only
929 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
930 if (aa != null && aa.length > 0)
932 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
939 if (jal.getAlignmentAnnotation() != null)
941 // Store the annotation shown on the alignment.
942 jalview.datamodel.AlignmentAnnotation[] aa = jal
943 .getAlignmentAnnotation();
944 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
949 if (jal.getGroups() != null)
951 JGroup[] groups = new JGroup[jal.getGroups().size()];
953 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
955 groups[++i] = new JGroup();
957 groups[i].setStart(sg.getStartRes());
958 groups[i].setEnd(sg.getEndRes());
959 groups[i].setName(sg.getName());
960 if (groupRefs.containsKey(sg))
962 // group has references so set it's ID field
963 groups[i].setId(groupRefs.get(sg).toString());
967 if (sg.cs.conservationApplied())
969 groups[i].setConsThreshold(sg.cs.getConservationInc());
971 if (sg.cs instanceof jalview.schemes.UserColourScheme)
973 groups[i].setColour(setUserColourScheme(sg.cs, userColours,
979 .setColour(ColourSchemeProperty.getColourName(sg.cs));
982 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
984 groups[i].setColour("AnnotationColourGradient");
985 groups[i].setAnnotationColours(constructAnnotationColours(
986 (jalview.schemes.AnnotationColourGradient) sg.cs,
989 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
992 .setColour(setUserColourScheme(sg.cs, userColours, jms));
996 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
999 groups[i].setPidThreshold(sg.cs.getThreshold());
1002 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
1003 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
1004 groups[i].setDisplayText(sg.getDisplayText());
1005 groups[i].setColourText(sg.getColourText());
1006 groups[i].setTextCol1(sg.textColour.getRGB());
1007 groups[i].setTextCol2(sg.textColour2.getRGB());
1008 groups[i].setTextColThreshold(sg.thresholdTextColour);
1009 groups[i].setShowUnconserved(sg.getShowNonconserved());
1010 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1011 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1012 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1013 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1014 for (int s = 0; s < sg.getSize(); s++)
1016 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1018 groups[i].addSeq(seqHash(seq));
1022 jms.setJGroup(groups);
1026 // /////////SAVE VIEWPORT
1027 Viewport view = new Viewport();
1028 view.setTitle(ap.alignFrame.getTitle());
1029 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1030 av.getSequenceSetId()));
1031 view.setId(av.getViewId());
1032 view.setViewName(av.viewName);
1033 view.setGatheredViews(av.gatherViewsHere);
1035 if (ap.av.explodedPosition != null)
1037 view.setXpos(av.explodedPosition.x);
1038 view.setYpos(av.explodedPosition.y);
1039 view.setWidth(av.explodedPosition.width);
1040 view.setHeight(av.explodedPosition.height);
1044 view.setXpos(ap.alignFrame.getBounds().x);
1045 view.setYpos(ap.alignFrame.getBounds().y);
1046 view.setWidth(ap.alignFrame.getBounds().width);
1047 view.setHeight(ap.alignFrame.getBounds().height);
1050 view.setStartRes(av.startRes);
1051 view.setStartSeq(av.startSeq);
1053 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1055 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1058 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1060 AnnotationColours ac = constructAnnotationColours(
1061 (jalview.schemes.AnnotationColourGradient) av
1062 .getGlobalColourScheme(),
1065 view.setAnnotationColours(ac);
1066 view.setBgColour("AnnotationColourGradient");
1070 view.setBgColour(ColourSchemeProperty.getColourName(av
1071 .getGlobalColourScheme()));
1074 ColourSchemeI cs = av.getGlobalColourScheme();
1078 if (cs.conservationApplied())
1080 view.setConsThreshold(cs.getConservationInc());
1081 if (cs instanceof jalview.schemes.UserColourScheme)
1083 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1087 if (cs instanceof ResidueColourScheme)
1089 view.setPidThreshold(cs.getThreshold());
1093 view.setConservationSelected(av.getConservationSelected());
1094 view.setPidSelected(av.getAbovePIDThreshold());
1095 view.setFontName(av.font.getName());
1096 view.setFontSize(av.font.getSize());
1097 view.setFontStyle(av.font.getStyle());
1098 view.setRenderGaps(av.renderGaps);
1099 view.setShowAnnotation(av.getShowAnnotation());
1100 view.setShowBoxes(av.getShowBoxes());
1101 view.setShowColourText(av.getColourText());
1102 view.setShowFullId(av.getShowJVSuffix());
1103 view.setRightAlignIds(av.isRightAlignIds());
1104 view.setShowSequenceFeatures(av.showSequenceFeatures);
1105 view.setShowText(av.getShowText());
1106 view.setShowUnconserved(av.getShowUnconserved());
1107 view.setWrapAlignment(av.getWrapAlignment());
1108 view.setTextCol1(av.textColour.getRGB());
1109 view.setTextCol2(av.textColour2.getRGB());
1110 view.setTextColThreshold(av.thresholdTextColour);
1111 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1112 view.setShowSequenceLogo(av.isShowSequenceLogo());
1113 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1114 view.setShowGroupConsensus(av.isShowGroupConsensus());
1115 view.setShowGroupConservation(av.isShowGroupConservation());
1116 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1117 view.setShowDbRefTooltip(av.isShowDbRefs());
1118 view.setFollowHighlight(av.followHighlight);
1119 view.setFollowSelection(av.followSelection);
1120 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1121 if (av.getFeaturesDisplayed() != null)
1123 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1125 String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder;
1127 Vector settingsAdded = new Vector();
1128 Object gstyle = null;
1129 GraduatedColor gcol = null;
1130 if (renderOrder != null)
1132 for (int ro = 0; ro < renderOrder.length; ro++)
1134 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1135 .getFeatureStyle(renderOrder[ro]);
1136 Setting setting = new Setting();
1137 setting.setType(renderOrder[ro]);
1138 if (gstyle instanceof GraduatedColor)
1140 gcol = (GraduatedColor) gstyle;
1141 setting.setColour(gcol.getMaxColor().getRGB());
1142 setting.setMincolour(gcol.getMinColor().getRGB());
1143 setting.setMin(gcol.getMin());
1144 setting.setMax(gcol.getMax());
1145 setting.setColourByLabel(gcol.isColourByLabel());
1146 setting.setAutoScale(gcol.isAutoScale());
1147 setting.setThreshold(gcol.getThresh());
1148 setting.setThreshstate(gcol.getThreshType());
1152 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1153 .getColour(renderOrder[ro]).getRGB());
1156 setting.setDisplay(av.getFeaturesDisplayed()
1157 .containsKey(renderOrder[ro]));
1158 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1159 .getOrder(renderOrder[ro]);
1162 setting.setOrder(rorder);
1164 fs.addSetting(setting);
1165 settingsAdded.addElement(renderOrder[ro]);
1169 // Make sure we save none displayed feature settings
1170 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureColours
1171 .keySet().iterator();
1172 while (en.hasNext())
1174 String key = en.next().toString();
1175 if (settingsAdded.contains(key))
1180 Setting setting = new Setting();
1181 setting.setType(key);
1182 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1183 .getColour(key).getRGB());
1185 setting.setDisplay(false);
1186 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1190 setting.setOrder(rorder);
1192 fs.addSetting(setting);
1193 settingsAdded.addElement(key);
1195 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups
1196 .keySet().iterator();
1197 Vector groupsAdded = new Vector();
1198 while (en.hasNext())
1200 String grp = en.next().toString();
1201 if (groupsAdded.contains(grp))
1205 Group g = new Group();
1207 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1208 .getFeatureRenderer().featureGroups.get(grp))
1211 groupsAdded.addElement(grp);
1213 jms.setFeatureSettings(fs);
1217 if (av.hasHiddenColumns())
1219 if (av.getColumnSelection() == null
1220 || av.getColumnSelection().getHiddenColumns() == null)
1222 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1226 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1229 int[] region = (int[]) av.getColumnSelection()
1230 .getHiddenColumns().elementAt(c);
1231 HiddenColumns hc = new HiddenColumns();
1232 hc.setStart(region[0]);
1233 hc.setEnd(region[1]);
1234 view.addHiddenColumns(hc);
1238 if (calcIdSet.size() > 0)
1240 for (String calcId : calcIdSet)
1242 if (calcId.trim().length() > 0)
1244 CalcIdParam cidp = createCalcIdParam(calcId, av);
1245 // Some calcIds have no parameters.
1248 view.addCalcIdParam(cidp);
1254 jms.addViewport(view);
1256 object.setJalviewModelSequence(jms);
1257 object.getVamsasModel().addSequenceSet(vamsasSet);
1259 if (jout != null && fileName != null)
1261 // We may not want to write the object to disk,
1262 // eg we can copy the alignViewport to a new view object
1263 // using save and then load
1266 JarEntry entry = new JarEntry(fileName);
1267 jout.putNextEntry(entry);
1268 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1270 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1272 marshaller.marshal(object);
1275 } catch (Exception ex)
1277 // TODO: raise error in GUI if marshalling failed.
1278 ex.printStackTrace();
1285 * Save the state of a structure viewer
1290 * the archive XML element under which to save the state
1293 * @param matchedFile
1297 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1298 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1299 String matchedFile, StructureViewerBase viewFrame)
1301 final AAStructureBindingModel bindingModel = viewFrame
1303 for (int peid = 0; peid < bindingModel
1304 .getPdbCount(); peid++)
1306 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1307 final String pdbId = pdbentry.getId();
1308 if (!pdbId.equals(entry.getId())
1309 && !(entry.getId().length() > 4 && entry.getId()
1311 .startsWith(pdbId.toLowerCase())))
1315 if (matchedFile == null)
1317 matchedFile = pdbentry.getFile();
1319 else if (!matchedFile.equals(pdbentry
1323 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1324 + pdbentry.getFile());
1328 // can get at it if the ID
1329 // match is ambiguous (e.g.
1331 String statestring = viewFrame.getStateInfo();
1333 for (int smap = 0; smap < viewFrame.getBinding()
1334 .getSequence()[peid].length; smap++)
1336 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1337 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1339 StructureState state = new StructureState();
1340 state.setVisible(true);
1341 state.setXpos(viewFrame.getX());
1342 state.setYpos(viewFrame.getY());
1343 state.setWidth(viewFrame.getWidth());
1344 state.setHeight(viewFrame.getHeight());
1345 final String viewId = viewFrame.getViewId();
1346 state.setViewId(viewId);
1347 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1348 state.setColourwithAlignPanel(viewFrame
1349 .isUsedforcolourby(ap));
1350 state.setColourByJmol(viewFrame.isColouredByViewer());
1352 * Only store each structure viewer's state once in each XML document.
1354 if (!viewIds.contains(viewId))
1356 viewIds.add(viewId);
1357 state.setContent(statestring.replaceAll("\n", ""));
1361 state.setContent("# duplicate state");
1363 pdb.addStructureState(state);
1370 private AnnotationColours constructAnnotationColours(
1371 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1372 JalviewModelSequence jms)
1374 AnnotationColours ac = new AnnotationColours();
1375 ac.setAboveThreshold(acg.getAboveThreshold());
1376 ac.setThreshold(acg.getAnnotationThreshold());
1377 ac.setAnnotation(acg.getAnnotation());
1378 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1380 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1385 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1389 ac.setMaxColour(acg.getMaxColour().getRGB());
1390 ac.setMinColour(acg.getMinColour().getRGB());
1391 ac.setPerSequence(acg.isSeqAssociated());
1392 ac.setPredefinedColours(acg.isPredefinedColours());
1396 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1397 IdentityHashMap groupRefs, AlignmentViewport av,
1398 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1401 for (int i = 0; i < aa.length; i++)
1403 Annotation an = new Annotation();
1405 if (aa[i].annotationId != null)
1407 annotationIds.put(aa[i].annotationId, aa[i]);
1410 an.setId(aa[i].annotationId);
1412 an.setVisible(aa[i].visible);
1414 an.setDescription(aa[i].description);
1416 if (aa[i].sequenceRef != null)
1418 // TODO later annotation sequenceRef should be the XML ID of the
1419 // sequence rather than its display name
1420 an.setSequenceRef(aa[i].sequenceRef.getName());
1422 if (aa[i].groupRef != null)
1424 Object groupIdr = groupRefs.get(aa[i].groupRef);
1425 if (groupIdr == null)
1427 // make a locally unique String
1428 groupRefs.put(aa[i].groupRef,
1429 groupIdr = ("" + System.currentTimeMillis()
1430 + aa[i].groupRef.getName() + groupRefs.size()));
1432 an.setGroupRef(groupIdr.toString());
1435 // store all visualization attributes for annotation
1436 an.setGraphHeight(aa[i].graphHeight);
1437 an.setCentreColLabels(aa[i].centreColLabels);
1438 an.setScaleColLabels(aa[i].scaleColLabel);
1439 an.setShowAllColLabels(aa[i].showAllColLabels);
1440 an.setBelowAlignment(aa[i].belowAlignment);
1442 if (aa[i].graph > 0)
1445 an.setGraphType(aa[i].graph);
1446 an.setGraphGroup(aa[i].graphGroup);
1447 if (aa[i].getThreshold() != null)
1449 ThresholdLine line = new ThresholdLine();
1450 line.setLabel(aa[i].getThreshold().label);
1451 line.setValue(aa[i].getThreshold().value);
1452 line.setColour(aa[i].getThreshold().colour.getRGB());
1453 an.setThresholdLine(line);
1461 an.setLabel(aa[i].label);
1463 if (aa[i] == av.getAlignmentQualityAnnot()
1464 || aa[i] == av.getAlignmentConservationAnnotation()
1465 || aa[i] == av.getAlignmentConsensusAnnotation()
1466 || aa[i].autoCalculated)
1468 // new way of indicating autocalculated annotation -
1469 an.setAutoCalculated(aa[i].autoCalculated);
1471 if (aa[i].hasScore())
1473 an.setScore(aa[i].getScore());
1476 if (aa[i].getCalcId() != null)
1478 calcIdSet.add(aa[i].getCalcId());
1479 an.setCalcId(aa[i].getCalcId());
1481 if (aa[i].hasProperties())
1483 for (String pr : aa[i].getProperties())
1485 Property prop = new Property();
1487 prop.setValue(aa[i].getProperty(pr));
1488 an.addProperty(prop);
1491 AnnotationElement ae;
1492 if (aa[i].annotations != null)
1494 an.setScoreOnly(false);
1495 for (int a = 0; a < aa[i].annotations.length; a++)
1497 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1502 ae = new AnnotationElement();
1503 if (aa[i].annotations[a].description != null)
1505 ae.setDescription(aa[i].annotations[a].description);
1507 if (aa[i].annotations[a].displayCharacter != null)
1509 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1512 if (!Float.isNaN(aa[i].annotations[a].value))
1514 ae.setValue(aa[i].annotations[a].value);
1518 if (aa[i].annotations[a].secondaryStructure > ' ')
1520 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1524 if (aa[i].annotations[a].colour != null
1525 && aa[i].annotations[a].colour != java.awt.Color.black)
1527 ae.setColour(aa[i].annotations[a].colour.getRGB());
1530 an.addAnnotationElement(ae);
1531 if (aa[i].autoCalculated)
1533 // only write one non-null entry into the annotation row -
1534 // sufficient to get the visualization attributes necessary to
1542 an.setScoreOnly(true);
1544 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1546 // skip autocalculated annotation - these are only provided for
1548 vamsasSet.addAnnotation(an);
1554 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1556 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1557 if (settings != null)
1559 CalcIdParam vCalcIdParam = new CalcIdParam();
1560 vCalcIdParam.setCalcId(calcId);
1561 vCalcIdParam.addServiceURL(settings.getServiceURI());
1562 // generic URI allowing a third party to resolve another instance of the
1563 // service used for this calculation
1564 for (String urls : settings.getServiceURLs())
1566 vCalcIdParam.addServiceURL(urls);
1568 vCalcIdParam.setVersion("1.0");
1569 if (settings.getPreset() != null)
1571 WsParamSetI setting = settings.getPreset();
1572 vCalcIdParam.setName(setting.getName());
1573 vCalcIdParam.setDescription(setting.getDescription());
1577 vCalcIdParam.setName("");
1578 vCalcIdParam.setDescription("Last used parameters");
1580 // need to be able to recover 1) settings 2) user-defined presets or
1581 // recreate settings from preset 3) predefined settings provided by
1582 // service - or settings that can be transferred (or discarded)
1583 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1585 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1586 // todo - decide if updateImmediately is needed for any projects.
1588 return vCalcIdParam;
1593 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1596 if (calcIdParam.getVersion().equals("1.0"))
1598 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1599 .getPreferredServiceFor(calcIdParam.getServiceURL());
1600 if (service != null)
1602 WsParamSetI parmSet = null;
1605 parmSet = service.getParamStore().parseServiceParameterFile(
1606 calcIdParam.getName(), calcIdParam.getDescription(),
1607 calcIdParam.getServiceURL(),
1608 calcIdParam.getParameters().replace("|\\n|", "\n"));
1609 } catch (IOException x)
1611 warn("Couldn't parse parameter data for "
1612 + calcIdParam.getCalcId(), x);
1615 List<ArgumentI> argList = null;
1616 if (calcIdParam.getName().length() > 0)
1618 parmSet = service.getParamStore()
1619 .getPreset(calcIdParam.getName());
1620 if (parmSet != null)
1622 // TODO : check we have a good match with settings in AACon -
1623 // otherwise we'll need to create a new preset
1628 argList = parmSet.getArguments();
1631 AAConSettings settings = new AAConSettings(
1632 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1633 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1634 calcIdParam.isNeedsUpdate());
1639 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1643 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1647 * External mapping between jalview objects and objects yielding a valid and
1648 * unique object ID string. This is null for normal Jalview project IO, but
1649 * non-null when a jalview project is being read or written as part of a
1652 IdentityHashMap jv2vobj = null;
1655 * Construct a unique ID for jvobj using either existing bindings or if none
1656 * exist, the result of the hashcode call for the object.
1659 * jalview data object
1660 * @return unique ID for referring to jvobj
1662 private String makeHashCode(Object jvobj, String altCode)
1664 if (jv2vobj != null)
1666 Object id = jv2vobj.get(jvobj);
1669 return id.toString();
1671 // check string ID mappings
1672 if (jvids2vobj != null && jvobj instanceof String)
1674 id = jvids2vobj.get(jvobj);
1678 return id.toString();
1680 // give up and warn that something has gone wrong
1681 warn("Cannot find ID for object in external mapping : " + jvobj);
1687 * return local jalview object mapped to ID, if it exists
1691 * @return null or object bound to idcode
1693 private Object retrieveExistingObj(String idcode)
1695 if (idcode != null && vobj2jv != null)
1697 return vobj2jv.get(idcode);
1703 * binding from ID strings from external mapping table to jalview data model
1706 private Hashtable vobj2jv;
1708 private Sequence createVamsasSequence(String id, SequenceI jds)
1710 return createVamsasSequence(true, id, jds, null);
1713 private Sequence createVamsasSequence(boolean recurse, String id,
1714 SequenceI jds, SequenceI parentseq)
1716 Sequence vamsasSeq = new Sequence();
1717 vamsasSeq.setId(id);
1718 vamsasSeq.setName(jds.getName());
1719 vamsasSeq.setSequence(jds.getSequenceAsString());
1720 vamsasSeq.setDescription(jds.getDescription());
1721 jalview.datamodel.DBRefEntry[] dbrefs = null;
1722 if (jds.getDatasetSequence() != null)
1724 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1725 if (jds.getDatasetSequence().getDBRef() != null)
1727 dbrefs = jds.getDatasetSequence().getDBRef();
1732 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1733 // dataset sequences only
1734 dbrefs = jds.getDBRef();
1738 for (int d = 0; d < dbrefs.length; d++)
1740 DBRef dbref = new DBRef();
1741 dbref.setSource(dbrefs[d].getSource());
1742 dbref.setVersion(dbrefs[d].getVersion());
1743 dbref.setAccessionId(dbrefs[d].getAccessionId());
1744 if (dbrefs[d].hasMap())
1746 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1748 dbref.setMapping(mp);
1750 vamsasSeq.addDBRef(dbref);
1756 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1757 SequenceI parentseq, SequenceI jds, boolean recurse)
1760 if (jmp.getMap() != null)
1764 jalview.util.MapList mlst = jmp.getMap();
1765 int r[] = mlst.getFromRanges();
1766 for (int s = 0; s < r.length; s += 2)
1768 MapListFrom mfrom = new MapListFrom();
1769 mfrom.setStart(r[s]);
1770 mfrom.setEnd(r[s + 1]);
1771 mp.addMapListFrom(mfrom);
1773 r = mlst.getToRanges();
1774 for (int s = 0; s < r.length; s += 2)
1776 MapListTo mto = new MapListTo();
1778 mto.setEnd(r[s + 1]);
1779 mp.addMapListTo(mto);
1781 mp.setMapFromUnit(mlst.getFromRatio());
1782 mp.setMapToUnit(mlst.getToRatio());
1783 if (jmp.getTo() != null)
1785 MappingChoice mpc = new MappingChoice();
1787 && (parentseq != jmp.getTo() || parentseq
1788 .getDatasetSequence() != jmp.getTo()))
1790 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1796 SequenceI ps = null;
1797 if (parentseq != jmp.getTo()
1798 && parentseq.getDatasetSequence() != jmp.getTo())
1800 // chaining dbref rather than a handshaking one
1801 jmpid = seqHash(ps = jmp.getTo());
1805 jmpid = seqHash(ps = parentseq);
1807 mpc.setDseqFor(jmpid);
1808 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1810 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1811 seqRefIds.put(mpc.getDseqFor(), ps);
1815 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1818 mp.setMappingChoice(mpc);
1824 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
1825 List<UserColourScheme> userColours, JalviewModelSequence jms)
1828 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1829 boolean newucs = false;
1830 if (!userColours.contains(ucs))
1832 userColours.add(ucs);
1835 id = "ucs" + userColours.indexOf(ucs);
1838 // actually create the scheme's entry in the XML model
1839 java.awt.Color[] colours = ucs.getColours();
1840 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1841 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1843 for (int i = 0; i < colours.length; i++)
1845 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1846 col.setName(ResidueProperties.aa[i]);
1847 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1848 jbucs.addColour(col);
1850 if (ucs.getLowerCaseColours() != null)
1852 colours = ucs.getLowerCaseColours();
1853 for (int i = 0; i < colours.length; i++)
1855 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1856 col.setName(ResidueProperties.aa[i].toLowerCase());
1857 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1858 jbucs.addColour(col);
1863 uc.setUserColourScheme(jbucs);
1864 jms.addUserColours(uc);
1870 jalview.schemes.UserColourScheme getUserColourScheme(
1871 JalviewModelSequence jms, String id)
1873 UserColours[] uc = jms.getUserColours();
1874 UserColours colours = null;
1876 for (int i = 0; i < uc.length; i++)
1878 if (uc[i].getId().equals(id))
1886 java.awt.Color[] newColours = new java.awt.Color[24];
1888 for (int i = 0; i < 24; i++)
1890 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1891 .getUserColourScheme().getColour(i).getRGB(), 16));
1894 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1897 if (colours.getUserColourScheme().getColourCount() > 24)
1899 newColours = new java.awt.Color[23];
1900 for (int i = 0; i < 23; i++)
1902 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1903 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1905 ucs.setLowerCaseColours(newColours);
1912 * contains last error message (if any) encountered by XML loader.
1914 String errorMessage = null;
1917 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1918 * exceptions are raised during project XML parsing
1920 public boolean attemptversion1parse = true;
1923 * Load a jalview project archive from a jar file
1926 * - HTTP URL or filename
1928 public AlignFrame loadJalviewAlign(final String file)
1931 jalview.gui.AlignFrame af = null;
1935 // create list to store references for any new Jmol viewers created
1936 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1937 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1938 // Workaround is to make sure caller implements the JarInputStreamProvider
1940 // so we can re-open the jar input stream for each entry.
1942 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1943 af = loadJalviewAlign(jprovider);
1945 } catch (MalformedURLException e)
1947 errorMessage = "Invalid URL format for '" + file + "'";
1953 SwingUtilities.invokeAndWait(new Runnable()
1957 setLoadingFinishedForNewStructureViewers();
1960 } catch (Exception x)
1968 private jarInputStreamProvider createjarInputStreamProvider(
1969 final String file) throws MalformedURLException
1972 errorMessage = null;
1973 uniqueSetSuffix = null;
1975 viewportsAdded = null;
1976 frefedSequence = null;
1978 if (file.startsWith("http://"))
1980 url = new URL(file);
1982 final URL _url = url;
1983 return new jarInputStreamProvider()
1987 public JarInputStream getJarInputStream() throws IOException
1991 return new JarInputStream(_url.openStream());
1995 return new JarInputStream(new FileInputStream(file));
2000 public String getFilename()
2008 * Recover jalview session from a jalview project archive. Caller may
2009 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2010 * themselves. Any null fields will be initialised with default values,
2011 * non-null fields are left alone.
2016 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2018 errorMessage = null;
2019 if (uniqueSetSuffix == null)
2021 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2023 if (seqRefIds == null)
2025 seqRefIds = new HashMap<String, SequenceI>();
2027 if (viewportsAdded == null)
2029 viewportsAdded = new Hashtable();
2031 if (frefedSequence == null)
2033 frefedSequence = new Vector();
2036 jalview.gui.AlignFrame af = null, _af = null;
2037 Hashtable gatherToThisFrame = new Hashtable();
2038 final String file = jprovider.getFilename();
2041 JarInputStream jin = null;
2042 JarEntry jarentry = null;
2047 jin = jprovider.getJarInputStream();
2048 for (int i = 0; i < entryCount; i++)
2050 jarentry = jin.getNextJarEntry();
2053 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2055 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
2056 JalviewModel object = new JalviewModel();
2058 Unmarshaller unmar = new Unmarshaller(object);
2059 unmar.setValidation(false);
2060 object = (JalviewModel) unmar.unmarshal(in);
2061 if (true) // !skipViewport(object))
2063 _af = loadFromObject(object, file, true, jprovider);
2064 if (object.getJalviewModelSequence().getViewportCount() > 0)
2067 if (af.viewport.gatherViewsHere)
2069 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2075 else if (jarentry != null)
2077 // Some other file here.
2080 } while (jarentry != null);
2081 resolveFrefedSequences();
2082 } catch (java.io.FileNotFoundException ex)
2084 ex.printStackTrace();
2085 errorMessage = "Couldn't locate Jalview XML file : " + file;
2086 System.err.println("Exception whilst loading jalview XML file : "
2088 } catch (java.net.UnknownHostException ex)
2090 ex.printStackTrace();
2091 errorMessage = "Couldn't locate Jalview XML file : " + file;
2092 System.err.println("Exception whilst loading jalview XML file : "
2094 } catch (Exception ex)
2096 System.err.println("Parsing as Jalview Version 2 file failed.");
2097 ex.printStackTrace(System.err);
2098 if (attemptversion1parse)
2100 // Is Version 1 Jar file?
2103 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2104 } catch (Exception ex2)
2106 System.err.println("Exception whilst loading as jalviewXMLV1:");
2107 ex2.printStackTrace();
2111 if (Desktop.instance != null)
2113 Desktop.instance.stopLoading();
2117 System.out.println("Successfully loaded archive file");
2120 ex.printStackTrace();
2122 System.err.println("Exception whilst loading jalview XML file : "
2124 } catch (OutOfMemoryError e)
2126 // Don't use the OOM Window here
2127 errorMessage = "Out of memory loading jalview XML file";
2128 System.err.println("Out of memory whilst loading jalview XML file");
2129 e.printStackTrace();
2132 if (Desktop.instance != null)
2134 Desktop.instance.stopLoading();
2137 Enumeration en = gatherToThisFrame.elements();
2138 while (en.hasMoreElements())
2140 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2142 if (errorMessage != null)
2150 * check errorMessage for a valid error message and raise an error box in the
2151 * GUI or write the current errorMessage to stderr and then clear the error
2154 protected void reportErrors()
2156 reportErrors(false);
2159 protected void reportErrors(final boolean saving)
2161 if (errorMessage != null)
2163 final String finalErrorMessage = errorMessage;
2166 javax.swing.SwingUtilities.invokeLater(new Runnable()
2171 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2172 finalErrorMessage, "Error "
2173 + (saving ? "saving" : "loading")
2174 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2180 System.err.println("Problem loading Jalview file: " + errorMessage);
2183 errorMessage = null;
2186 Hashtable<String, String> alreadyLoadedPDB;
2189 * when set, local views will be updated from view stored in JalviewXML
2190 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2191 * sync if this is set to true.
2193 private final boolean updateLocalViews = false;
2195 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2197 if (alreadyLoadedPDB == null)
2199 alreadyLoadedPDB = new Hashtable();
2202 if (alreadyLoadedPDB.containsKey(pdbId))
2204 return alreadyLoadedPDB.get(pdbId).toString();
2209 JarInputStream jin = jprovider.getJarInputStream();
2211 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2212 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2213 * FileInputStream(jprovider)); }
2216 JarEntry entry = null;
2219 entry = jin.getNextJarEntry();
2220 } while (entry != null && !entry.getName().equals(pdbId));
2223 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2224 File outFile = File.createTempFile("jalview_pdb", ".txt");
2225 outFile.deleteOnExit();
2226 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2229 while ((data = in.readLine()) != null)
2236 } catch (Exception foo)
2241 String t = outFile.getAbsolutePath();
2242 alreadyLoadedPDB.put(pdbId, t);
2247 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2249 } catch (Exception ex)
2251 ex.printStackTrace();
2257 private class JvAnnotRow
2259 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2266 * persisted version of annotation row from which to take vis properties
2268 public jalview.datamodel.AlignmentAnnotation template;
2271 * original position of the annotation row in the alignment
2277 * Load alignment frame from jalview XML DOM object
2282 * filename source string
2283 * @param loadTreesAndStructures
2284 * when false only create Viewport
2286 * data source provider
2287 * @return alignment frame created from view stored in DOM
2289 AlignFrame loadFromObject(JalviewModel object, String file,
2290 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2292 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2293 Sequence[] vamsasSeq = vamsasSet.getSequence();
2295 JalviewModelSequence jms = object.getJalviewModelSequence();
2297 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2300 // ////////////////////////////////
2303 Vector hiddenSeqs = null;
2304 jalview.datamodel.Sequence jseq;
2306 ArrayList tmpseqs = new ArrayList();
2308 boolean multipleView = false;
2310 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2311 int vi = 0; // counter in vamsasSeq array
2312 for (int i = 0; i < jseqs.length; i++)
2314 String seqId = jseqs[i].getId();
2316 if (seqRefIds.get(seqId) != null)
2318 tmpseqs.add(seqRefIds.get(seqId));
2319 multipleView = true;
2323 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2324 vamsasSeq[vi].getSequence());
2325 jseq.setDescription(vamsasSeq[vi].getDescription());
2326 jseq.setStart(jseqs[i].getStart());
2327 jseq.setEnd(jseqs[i].getEnd());
2328 jseq.setVamsasId(uniqueSetSuffix + seqId);
2329 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2334 if (jseqs[i].getHidden())
2336 if (hiddenSeqs == null)
2338 hiddenSeqs = new Vector();
2341 hiddenSeqs.addElement(seqRefIds.get(seqId));
2347 // Create the alignment object from the sequence set
2348 // ///////////////////////////////
2349 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2352 tmpseqs.toArray(orderedSeqs);
2354 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2357 // / Add the alignment properties
2358 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2360 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2361 al.setProperty(ssp.getKey(), ssp.getValue());
2365 // SequenceFeatures are added to the DatasetSequence,
2366 // so we must create or recover the dataset before loading features
2367 // ///////////////////////////////
2368 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2370 // older jalview projects do not have a dataset id.
2371 al.setDataset(null);
2375 // recover dataset - passing on flag indicating if this a 'viewless'
2376 // sequence set (a.k.a. a stored dataset for the project)
2377 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2378 .getViewportCount() == 0);
2380 // ///////////////////////////////
2382 Hashtable pdbloaded = new Hashtable();
2385 // load sequence features, database references and any associated PDB
2386 // structures for the alignment
2387 for (int i = 0; i < vamsasSeq.length; i++)
2389 if (jseqs[i].getFeaturesCount() > 0)
2391 Features[] features = jseqs[i].getFeatures();
2392 for (int f = 0; f < features.length; f++)
2394 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2395 features[f].getType(), features[f].getDescription(),
2396 features[f].getStatus(), features[f].getBegin(),
2397 features[f].getEnd(), features[f].getFeatureGroup());
2399 sf.setScore(features[f].getScore());
2400 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2402 OtherData keyValue = features[f].getOtherData(od);
2403 if (keyValue.getKey().startsWith("LINK"))
2405 sf.addLink(keyValue.getValue());
2409 sf.setValue(keyValue.getKey(), keyValue.getValue());
2414 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2417 if (vamsasSeq[i].getDBRefCount() > 0)
2419 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2421 if (jseqs[i].getPdbidsCount() > 0)
2423 Pdbids[] ids = jseqs[i].getPdbids();
2424 for (int p = 0; p < ids.length; p++)
2426 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2427 entry.setId(ids[p].getId());
2428 entry.setType(ids[p].getType());
2429 if (ids[p].getFile() != null)
2431 if (!pdbloaded.containsKey(ids[p].getFile()))
2433 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2437 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2440 StructureSelectionManager.getStructureSelectionManager(
2442 .registerPDBEntry(entry);
2443 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2447 } // end !multipleview
2449 // ///////////////////////////////
2450 // LOAD SEQUENCE MAPPINGS
2452 if (vamsasSet.getAlcodonFrameCount() > 0)
2454 // TODO Potentially this should only be done once for all views of an
2456 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2457 for (int i = 0; i < alc.length; i++)
2459 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2460 alc[i].getAlcodonCount());
2461 if (alc[i].getAlcodonCount() > 0)
2463 Alcodon[] alcods = alc[i].getAlcodon();
2464 for (int p = 0; p < cf.codons.length; p++)
2466 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2467 && alcods[p].hasPos3())
2469 // translated codons require three valid positions
2470 cf.codons[p] = new int[3];
2471 cf.codons[p][0] = (int) alcods[p].getPos1();
2472 cf.codons[p][1] = (int) alcods[p].getPos2();
2473 cf.codons[p][2] = (int) alcods[p].getPos3();
2477 cf.codons[p] = null;
2481 if (alc[i].getAlcodMapCount() > 0)
2483 AlcodMap[] maps = alc[i].getAlcodMap();
2484 for (int m = 0; m < maps.length; m++)
2486 SequenceI dnaseq = seqRefIds
2487 .get(maps[m].getDnasq());
2489 jalview.datamodel.Mapping mapping = null;
2490 // attach to dna sequence reference.
2491 if (maps[m].getMapping() != null)
2493 mapping = addMapping(maps[m].getMapping());
2497 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2502 frefedSequence.add(new Object[]
2503 { maps[m].getDnasq(), cf, mapping });
2507 al.addCodonFrame(cf);
2512 // ////////////////////////////////
2514 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2516 * store any annotations which forward reference a group's ID
2518 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2520 if (vamsasSet.getAnnotationCount() > 0)
2522 Annotation[] an = vamsasSet.getAnnotation();
2524 for (int i = 0; i < an.length; i++)
2527 * test if annotation is automatically calculated for this view only
2529 boolean autoForView = false;
2530 if (an[i].getLabel().equals("Quality")
2531 || an[i].getLabel().equals("Conservation")
2532 || an[i].getLabel().equals("Consensus"))
2534 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2536 if (!an[i].hasAutoCalculated())
2538 an[i].setAutoCalculated(true);
2542 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2544 // remove ID - we don't recover annotation from other views for
2545 // view-specific annotation
2549 // set visiblity for other annotation in this view
2550 if (an[i].getId() != null
2551 && annotationIds.containsKey(an[i].getId()))
2553 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2554 .get(an[i].getId());
2555 // in principle Visible should always be true for annotation displayed
2556 // in multiple views
2557 if (an[i].hasVisible())
2559 jda.visible = an[i].getVisible();
2562 al.addAnnotation(jda);
2566 // Construct new annotation from model.
2567 AnnotationElement[] ae = an[i].getAnnotationElement();
2568 jalview.datamodel.Annotation[] anot = null;
2569 java.awt.Color firstColour = null;
2571 if (!an[i].getScoreOnly())
2573 anot = new jalview.datamodel.Annotation[al.getWidth()];
2574 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2576 anpos = ae[aa].getPosition();
2578 if (anpos >= anot.length)
2583 anot[anpos] = new jalview.datamodel.Annotation(
2585 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2586 (ae[aa].getSecondaryStructure() == null || ae[aa]
2587 .getSecondaryStructure().length() == 0) ? ' '
2588 : ae[aa].getSecondaryStructure().charAt(0),
2592 // JBPNote: Consider verifying dataflow for IO of secondary
2593 // structure annotation read from Stockholm files
2594 // this was added to try to ensure that
2595 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2597 // anot[ae[aa].getPosition()].displayCharacter = "";
2599 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2600 if (firstColour == null)
2602 firstColour = anot[anpos].colour;
2606 jalview.datamodel.AlignmentAnnotation jaa = null;
2608 if (an[i].getGraph())
2610 float llim = 0, hlim = 0;
2611 // if (autoForView || an[i].isAutoCalculated()) {
2614 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2615 an[i].getDescription(), anot, llim, hlim,
2616 an[i].getGraphType());
2618 jaa.graphGroup = an[i].getGraphGroup();
2619 jaa._linecolour = firstColour;
2620 if (an[i].getThresholdLine() != null)
2622 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2623 .getThresholdLine().getValue(), an[i]
2624 .getThresholdLine().getLabel(), new java.awt.Color(
2625 an[i].getThresholdLine().getColour())));
2628 if (autoForView || an[i].isAutoCalculated())
2630 // Hardwire the symbol display line to ensure that labels for
2631 // histograms are displayed
2637 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2638 an[i].getDescription(), anot);
2639 jaa._linecolour = firstColour;
2641 // register new annotation
2642 if (an[i].getId() != null)
2644 annotationIds.put(an[i].getId(), jaa);
2645 jaa.annotationId = an[i].getId();
2647 // recover sequence association
2648 if (an[i].getSequenceRef() != null)
2650 if (al.findName(an[i].getSequenceRef()) != null)
2652 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2654 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2657 // and make a note of any group association
2658 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2660 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2661 .get(an[i].getGroupRef());
2664 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2665 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2670 if (an[i].hasScore())
2672 jaa.setScore(an[i].getScore());
2674 if (an[i].hasVisible())
2676 jaa.visible = an[i].getVisible();
2679 if (an[i].hasCentreColLabels())
2681 jaa.centreColLabels = an[i].getCentreColLabels();
2684 if (an[i].hasScaleColLabels())
2686 jaa.scaleColLabel = an[i].getScaleColLabels();
2688 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2690 // newer files have an 'autoCalculated' flag and store calculation
2691 // state in viewport properties
2692 jaa.autoCalculated = true; // means annotation will be marked for
2693 // update at end of load.
2695 if (an[i].hasGraphHeight())
2697 jaa.graphHeight = an[i].getGraphHeight();
2699 if (an[i].hasBelowAlignment())
2701 jaa.belowAlignment = an[i].isBelowAlignment();
2703 jaa.setCalcId(an[i].getCalcId());
2704 if (an[i].getPropertyCount() > 0)
2706 for (jalview.schemabinding.version2.Property prop : an[i]
2709 jaa.setProperty(prop.getName(), prop.getValue());
2712 if (jaa.autoCalculated)
2714 autoAlan.add(new JvAnnotRow(i, jaa));
2717 // if (!autoForView)
2719 // add autocalculated group annotation and any user created annotation
2721 al.addAnnotation(jaa);
2725 // ///////////////////////
2727 // Create alignment markup and styles for this view
2728 if (jms.getJGroupCount() > 0)
2730 JGroup[] groups = jms.getJGroup();
2731 boolean addAnnotSchemeGroup = false;
2732 for (int i = 0; i < groups.length; i++)
2734 ColourSchemeI cs = null;
2736 if (groups[i].getColour() != null)
2738 if (groups[i].getColour().startsWith("ucs"))
2740 cs = getUserColourScheme(jms, groups[i].getColour());
2742 else if (groups[i].getColour().equals("AnnotationColourGradient")
2743 && groups[i].getAnnotationColours() != null)
2745 addAnnotSchemeGroup = true;
2750 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2755 cs.setThreshold(groups[i].getPidThreshold(), true);
2759 Vector seqs = new Vector();
2761 for (int s = 0; s < groups[i].getSeqCount(); s++)
2763 String seqId = groups[i].getSeq(s) + "";
2764 jalview.datamodel.SequenceI ts = seqRefIds
2769 seqs.addElement(ts);
2773 if (seqs.size() < 1)
2778 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2779 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2780 groups[i].getDisplayText(), groups[i].getColourText(),
2781 groups[i].getStart(), groups[i].getEnd());
2783 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2785 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2786 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2787 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2788 .isShowUnconserved() : false);
2789 sg.thresholdTextColour = groups[i].getTextColThreshold();
2790 if (groups[i].hasShowConsensusHistogram())
2792 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2795 if (groups[i].hasShowSequenceLogo())
2797 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2799 if (groups[i].hasNormaliseSequenceLogo())
2801 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2803 if (groups[i].hasIgnoreGapsinConsensus())
2805 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2807 if (groups[i].getConsThreshold() != 0)
2809 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2810 "All", ResidueProperties.propHash, 3,
2811 sg.getSequences(null), 0, sg.getWidth() - 1);
2813 c.verdict(false, 25);
2814 sg.cs.setConservation(c);
2817 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2819 // re-instate unique group/annotation row reference
2820 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2821 .get(groups[i].getId());
2824 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2827 if (jaa.autoCalculated)
2829 // match up and try to set group autocalc alignment row for this
2831 if (jaa.label.startsWith("Consensus for "))
2833 sg.setConsensus(jaa);
2835 // match up and try to set group autocalc alignment row for this
2837 if (jaa.label.startsWith("Conservation for "))
2839 sg.setConservationRow(jaa);
2846 if (addAnnotSchemeGroup)
2848 // reconstruct the annotation colourscheme
2849 sg.cs = constructAnnotationColour(
2850 groups[i].getAnnotationColours(), null, al, jms, false);
2856 // only dataset in this model, so just return.
2859 // ///////////////////////////////
2862 // If we just load in the same jar file again, the sequenceSetId
2863 // will be the same, and we end up with multiple references
2864 // to the same sequenceSet. We must modify this id on load
2865 // so that each load of the file gives a unique id
2866 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2867 String viewId = (view.getId() == null ? null : view.getId()
2869 AlignFrame af = null;
2870 AlignViewport av = null;
2871 // now check to see if we really need to create a new viewport.
2872 if (multipleView && viewportsAdded.size() == 0)
2874 // We recovered an alignment for which a viewport already exists.
2875 // TODO: fix up any settings necessary for overlaying stored state onto
2876 // state recovered from another document. (may not be necessary).
2877 // we may need a binding from a viewport in memory to one recovered from
2879 // and then recover its containing af to allow the settings to be applied.
2880 // TODO: fix for vamsas demo
2882 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2884 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2885 if (seqsetobj != null)
2887 if (seqsetobj instanceof String)
2889 uniqueSeqSetId = (String) seqsetobj;
2891 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2897 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2903 * indicate that annotation colours are applied across all groups (pre
2904 * Jalview 2.8.1 behaviour)
2906 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2907 object.getVersion());
2909 AlignmentPanel ap = null;
2910 boolean isnewview = true;
2913 // Check to see if this alignment already has a view id == viewId
2914 jalview.gui.AlignmentPanel views[] = Desktop
2915 .getAlignmentPanels(uniqueSeqSetId);
2916 if (views != null && views.length > 0)
2918 for (int v = 0; v < views.length; v++)
2920 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2922 // recover the existing alignpanel, alignframe, viewport
2923 af = views[v].alignFrame;
2926 // TODO: could even skip resetting view settings if we don't want to
2927 // change the local settings from other jalview processes
2936 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
2937 uniqueSeqSetId, viewId, autoAlan);
2942 // /////////////////////////////////////
2943 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2947 for (int t = 0; t < jms.getTreeCount(); t++)
2950 Tree tree = jms.getTree(t);
2952 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2955 tp = af.ShowNewickTree(
2956 new jalview.io.NewickFile(tree.getNewick()),
2957 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2958 tree.getXpos(), tree.getYpos());
2959 if (tree.getId() != null)
2961 // perhaps bind the tree id to something ?
2966 // update local tree attributes ?
2967 // TODO: should check if tp has been manipulated by user - if so its
2968 // settings shouldn't be modified
2969 tp.setTitle(tree.getTitle());
2970 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2971 .getWidth(), tree.getHeight()));
2972 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2975 tp.treeCanvas.av = av; // af.viewport;
2976 tp.treeCanvas.ap = ap; // af.alignPanel;
2981 warn("There was a problem recovering stored Newick tree: \n"
2982 + tree.getNewick());
2986 tp.fitToWindow.setState(tree.getFitToWindow());
2987 tp.fitToWindow_actionPerformed(null);
2989 if (tree.getFontName() != null)
2991 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2992 .getFontStyle(), tree.getFontSize()));
2996 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2997 .getFontStyle(), tree.getFontSize()));
3000 tp.showPlaceholders(tree.getMarkUnlinked());
3001 tp.showBootstrap(tree.getShowBootstrap());
3002 tp.showDistances(tree.getShowDistances());
3004 tp.treeCanvas.threshold = tree.getThreshold();
3006 if (tree.getCurrentTree())
3008 af.viewport.setCurrentTree(tp.getTree());
3012 } catch (Exception ex)
3014 ex.printStackTrace();
3018 // //LOAD STRUCTURES
3019 if (loadTreesAndStructures)
3021 loadStructures(jprovider, jseqs, af, ap);
3023 // and finally return.
3028 * Load and link any saved structure viewers.
3035 protected void loadStructures(jarInputStreamProvider jprovider,
3036 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3039 * Run through all PDB ids on the alignment, and collect mappings between
3040 * distinct view ids and all sequences referring to that view.
3042 Map<String, ViewerData> structureViewers = new LinkedHashMap<String, ViewerData>();
3044 for (int i = 0; i < jseqs.length; i++)
3046 if (jseqs[i].getPdbidsCount() > 0)
3048 Pdbids[] ids = jseqs[i].getPdbids();
3049 for (int p = 0; p < ids.length; p++)
3051 final int structureStateCount = ids[p].getStructureStateCount();
3052 for (int s = 0; s < structureStateCount; s++)
3054 // check to see if we haven't already created this structure view
3055 final StructureState structureState = ids[p].getStructureState(s);
3056 String sviewid = (structureState.getViewId() == null) ? null
3057 : structureState.getViewId()
3059 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3060 // Originally : ids[p].getFile()
3061 // : TODO: verify external PDB file recovery still works in normal
3062 // jalview project load
3063 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3064 jpdb.setId(ids[p].getId());
3066 int x = structureState.getXpos();
3067 int y = structureState.getYpos();
3068 int width = structureState.getWidth();
3069 int height = structureState.getHeight();
3071 // Probably don't need to do this anymore...
3072 // Desktop.desktop.getComponentAt(x, y);
3073 // TODO: NOW: check that this recovers the PDB file correctly.
3074 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3075 jalview.datamodel.SequenceI seq = seqRefIds
3076 .get(jseqs[i].getId() + "");
3077 if (sviewid == null)
3079 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3082 if (!structureViewers.containsKey(sviewid))
3084 structureViewers.put(sviewid, new ViewerData(x, y, width, height,
3085 false, false, true));
3086 // Legacy pre-2.7 conversion JAL-823 :
3087 // do not assume any view has to be linked for colour by
3091 // assemble String[] { pdb files }, String[] { id for each
3092 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3093 // seqs_file 2}, boolean[] {
3094 // linkAlignPanel,superposeWithAlignpanel}} from hash
3095 ViewerData jmoldat = structureViewers.get(sviewid);
3096 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3097 | (structureState.hasAlignwithAlignPanel() ? structureState
3098 .getAlignwithAlignPanel() : false));
3101 * Default colour by linked panel to false if not specified (e.g.
3102 * for pre-2.7 projects)
3104 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3105 colourWithAlignPanel |= (structureState
3106 .hasColourwithAlignPanel() ? structureState
3107 .getColourwithAlignPanel() : false);
3108 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3111 * Default colour by viewer to true if not specified (e.g. for
3114 boolean colourByViewer = jmoldat.isColourByViewer();
3115 colourByViewer &= structureState
3116 .hasColourByJmol() ? structureState
3117 .getColourByJmol() : true;
3118 jmoldat.setColourByViewer(colourByViewer);
3120 if (jmoldat.getStateData().length() < structureState
3121 .getContent().length())
3124 jmoldat.setStateData(structureState.getContent());
3127 if (ids[p].getFile() != null)
3129 File mapkey = new File(ids[p].getFile());
3130 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3131 if (seqstrmaps == null)
3133 jmoldat.getFileData().put(
3135 seqstrmaps = jmoldat.new StructureData(pdbFile,
3138 if (!seqstrmaps.getSeqList().contains(seq))
3140 seqstrmaps.getSeqList().add(seq);
3146 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");
3153 // Instantiate the associated structure views
3154 for (Entry<String, ViewerData> entry : structureViewers.entrySet())
3156 createOrLinkStructureViewer(entry, af, ap);
3166 protected void createOrLinkStructureViewer(
3167 Entry<String, ViewerData> viewerData, AlignFrame af,
3170 final ViewerData svattrib = viewerData.getValue();
3173 * Search for any viewer windows already open from other alignment views
3174 * that exactly match the stored structure state
3176 StructureViewerBase comp = findMatchingViewer(viewerData);
3180 linkStructureViewer(ap, comp, svattrib);
3185 * Pending an XML element for ViewerType, just check if stateData contains
3186 * "chimera" (part of the chimera session filename).
3188 if (svattrib.getStateData().indexOf("chimera") > -1)
3190 createChimeraViewer(viewerData, af);
3194 createJmolViewer(viewerData, af);
3199 * Create a new Chimera viewer.
3204 protected void createChimeraViewer(Entry<String, ViewerData> viewerData,
3207 final ViewerData data = viewerData.getValue();
3208 String chimeraSession = data.getStateData();
3210 if (new File(chimeraSession).exists())
3212 Set<Entry<File, StructureData>> fileData = data.getFileData()
3214 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3215 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3216 for (Entry<File, StructureData> pdb : fileData)
3218 String filePath = pdb.getValue().getFilePath();
3219 String pdbId = pdb.getValue().getPdbId();
3220 pdbs.add(new PDBEntry(filePath, pdbId));
3221 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3222 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3226 boolean colourByChimera = data.isColourByViewer();
3227 boolean colourBySequence = data.isColourWithAlignPanel();
3229 // TODO can/should this be done via StructureViewer (like Jmol)?
3230 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs
3232 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs.size()][]);
3233 new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray,
3235 colourByChimera, colourBySequence);
3239 Cache.log.error("Chimera session file " + chimeraSession
3245 * Create a new Jmol window. First parse the Jmol state to translate filenames
3246 * loaded into the view, and record the order in which files are shown in the
3247 * Jmol view, so we can add the sequence mappings in same order.
3252 protected void createJmolViewer(
3253 final Entry<String, ViewerData> viewerData, AlignFrame af)
3255 final ViewerData svattrib = viewerData.getValue();
3256 String state = svattrib.getStateData();
3257 List<String> pdbfilenames = new ArrayList<String>();
3258 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3259 List<String> pdbids = new ArrayList<String>();
3260 StringBuilder newFileLoc = new StringBuilder(64);
3261 int cp = 0, ncp, ecp;
3262 Map<File, StructureData> oldFiles = svattrib.getFileData();
3263 while ((ncp = state.indexOf("load ", cp)) > -1)
3267 // look for next filename in load statement
3268 newFileLoc.append(state.substring(cp,
3269 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3270 String oldfilenam = state.substring(ncp,
3271 ecp = state.indexOf("\"", ncp));
3272 // recover the new mapping data for this old filename
3273 // have to normalize filename - since Jmol and jalview do
3275 // translation differently.
3276 StructureData filedat = oldFiles.get(new File(oldfilenam));
3277 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3278 pdbfilenames.add(filedat.getFilePath());
3279 pdbids.add(filedat.getPdbId());
3280 seqmaps.add(filedat.getSeqList()
3281 .toArray(new SequenceI[0]));
3282 newFileLoc.append("\"");
3283 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3284 // look for next file statement.
3285 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3289 // just append rest of state
3290 newFileLoc.append(state.substring(cp));
3294 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3295 newFileLoc = new StringBuilder(state);
3296 newFileLoc.append("; load append ");
3297 for (File id : oldFiles.keySet())
3299 // add this and any other pdb files that should be present in
3301 StructureData filedat = oldFiles.get(id);
3302 newFileLoc.append(filedat.getFilePath());
3303 pdbfilenames.add(filedat.getFilePath());
3304 pdbids.add(filedat.getPdbId());
3305 seqmaps.add(filedat.getSeqList()
3306 .toArray(new SequenceI[0]));
3307 newFileLoc.append(" \"");
3308 newFileLoc.append(filedat.getFilePath());
3309 newFileLoc.append("\"");
3312 newFileLoc.append(";");
3315 if (newFileLoc.length() > 0)
3317 int histbug = newFileLoc.indexOf("history = ");
3319 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3320 String val = (diff == -1) ? null : newFileLoc
3321 .substring(histbug, diff);
3322 if (val != null && val.length() >= 4)
3324 if (val.contains("e"))
3326 if (val.trim().equals("true"))
3334 newFileLoc.replace(histbug, diff, val);
3338 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3340 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3341 final SequenceI[][] sq = seqmaps
3342 .toArray(new SequenceI[seqmaps.size()][]);
3343 final String fileloc = newFileLoc.toString();
3344 final String sviewid = viewerData.getKey();
3345 final AlignFrame alf = af;
3346 final Rectangle rect = new Rectangle(svattrib.getX(),
3347 svattrib.getY(), svattrib.getWidth(), svattrib.getHeight());
3350 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3355 JalviewStructureDisplayI sview = null;
3358 // JAL-1333 note - we probably can't migrate Jmol views to UCSF
3360 sview = new StructureViewer(alf.alignPanel
3361 .getStructureSelectionManager()).createView(
3362 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3363 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3364 addNewStructureViewer(sview);
3365 } catch (OutOfMemoryError ex)
3367 new OOMWarning("restoring structure view for PDB id " + id,
3368 (OutOfMemoryError) ex.getCause());
3369 if (sview != null && sview.isVisible())
3371 sview.closeViewer();
3372 sview.setVisible(false);
3378 } catch (InvocationTargetException ex)
3380 warn("Unexpected error when opening Jmol view.", ex);
3382 } catch (InterruptedException e)
3384 // e.printStackTrace();
3390 * Returns any open frame that matches given structure viewer data. The match
3391 * is based on the unique viewId, or (for older project versions) the frame's
3397 protected StructureViewerBase findMatchingViewer(
3398 Entry<String, ViewerData> viewerData)
3400 final String sviewid = viewerData.getKey();
3401 final ViewerData svattrib = viewerData.getValue();
3402 StructureViewerBase comp = null;
3403 JInternalFrame[] frames = getAllFrames();
3404 for (JInternalFrame frame : frames)
3406 if (frame instanceof StructureViewerBase)
3409 * Post jalview 2.4 schema includes structure view id
3412 && ((StructureViewerBase) frame).getViewId().equals(
3415 comp = (AppJmol) frame;
3419 * Otherwise test for matching position and size of viewer frame
3421 else if (frame.getX() == svattrib.getX()
3422 && frame.getY() == svattrib.getY()
3423 && frame.getHeight() == svattrib.getHeight()
3424 && frame.getWidth() == svattrib.getWidth())
3426 comp = (AppJmol) frame;
3435 * Link an AlignmentPanel to an existing structure viewer.
3440 * @param useinViewerSuperpos
3441 * @param usetoColourbyseq
3442 * @param viewerColouring
3444 protected void linkStructureViewer(AlignmentPanel ap,
3445 StructureViewerBase viewer, ViewerData svattrib)
3447 // NOTE: if the jalview project is part of a shared session then
3448 // view synchronization should/could be done here.
3450 final boolean useinViewerSuperpos = svattrib.isAlignWithPanel();
3451 final boolean usetoColourbyseq = svattrib.isColourWithAlignPanel();
3452 final boolean viewerColouring = svattrib.isColourByViewer();
3453 Map<File, StructureData> oldFiles = svattrib.getFileData();
3456 * Add mapping for sequences in this view to an already open viewer
3458 final AAStructureBindingModel binding = viewer.getBinding();
3459 for (File id : oldFiles.keySet())
3461 // add this and any other pdb files that should be present in the
3463 StructureData filedat = oldFiles.get(id);
3464 String pdbFile = filedat.getFilePath();
3465 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3466 binding.getSsm().setMapping(seq, null, pdbFile,
3467 jalview.io.AppletFormatAdapter.FILE);
3468 binding.addSequenceForStructFile(pdbFile, seq);
3470 // and add the AlignmentPanel's reference to the view panel
3471 viewer.addAlignmentPanel(ap);
3472 if (useinViewerSuperpos)
3474 viewer.useAlignmentPanelForSuperposition(ap);
3478 viewer.excludeAlignmentPanelForSuperposition(ap);
3480 if (usetoColourbyseq)
3482 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
3486 viewer.excludeAlignmentPanelForColourbyseq(ap);
3491 * Get all frames within the Desktop.
3495 protected JInternalFrame[] getAllFrames()
3497 JInternalFrame[] frames = null;
3498 // TODO is this necessary - is it safe - risk of hanging?
3503 frames = Desktop.desktop.getAllFrames();
3504 } catch (ArrayIndexOutOfBoundsException e)
3506 // occasional No such child exceptions are thrown here...
3510 } catch (InterruptedException f)
3514 } while (frames == null);
3521 * - minimum version we are comparing against
3523 * - version of data being processsed.
3524 * @return true if version is development/null or evaluates to the same or
3525 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3527 private boolean isVersionStringLaterThan(String supported, String version)
3529 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3530 || version.equalsIgnoreCase("Test")
3531 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3533 System.err.println("Assuming project file with "
3534 + (version == null ? "null" : version)
3535 + " is compatible with Jalview version " + supported);
3540 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3542 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3544 // convert b to decimal to catch bugfix releases within a series
3545 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3546 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3549 if (Float.valueOf(curT) > Float.valueOf(fileT))
3551 // current version is newer than the version that wrote the file
3554 } catch (NumberFormatException nfe)
3557 .println("** WARNING: Version comparison failed for tokens ("
3561 + ")\n** Current: '"
3562 + supported + "' and Version: '" + version + "'");
3565 if (currentV.hasMoreElements())
3567 // fileV has no minor version but identical series to current
3574 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3576 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3578 if (newStructureViewers != null)
3580 sview.getBinding().setFinishedLoadingFromArchive(false);
3581 newStructureViewers.add(sview);
3585 protected void setLoadingFinishedForNewStructureViewers()
3587 if (newStructureViewers != null)
3589 for (JalviewStructureDisplayI sview : newStructureViewers)
3591 sview.getBinding().setFinishedLoadingFromArchive(true);
3593 newStructureViewers.clear();
3594 newStructureViewers = null;
3598 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3599 Alignment al, JalviewModelSequence jms, Viewport view,
3600 String uniqueSeqSetId, String viewId,
3601 ArrayList<JvAnnotRow> autoAlan)
3603 AlignFrame af = null;
3604 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3605 uniqueSeqSetId, viewId);
3607 af.setFileName(file, "Jalview");
3609 for (int i = 0; i < JSEQ.length; i++)
3611 af.viewport.setSequenceColour(af.viewport.getAlignment()
3612 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3615 af.viewport.gatherViewsHere = view.getGatheredViews();
3617 if (view.getSequenceSetId() != null)
3619 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3620 .get(uniqueSeqSetId);
3622 af.viewport.setSequenceSetId(uniqueSeqSetId);
3625 // propagate shared settings to this new view
3626 af.viewport.historyList = av.historyList;
3627 af.viewport.redoList = av.redoList;
3631 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3633 // TODO: check if this method can be called repeatedly without
3634 // side-effects if alignpanel already registered.
3635 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3637 // apply Hidden regions to view.
3638 if (hiddenSeqs != null)
3640 for (int s = 0; s < JSEQ.length; s++)
3642 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3644 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3647 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3649 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3652 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3655 for (int s = 0; s < hiddenSeqs.size(); s++)
3657 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3660 af.viewport.hideSequence(hseqs);
3663 // recover view properties and display parameters
3664 if (view.getViewName() != null)
3666 af.viewport.viewName = view.getViewName();
3667 af.setInitialTabVisible();
3669 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3672 af.viewport.setShowAnnotation(view.getShowAnnotation());
3673 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3675 af.viewport.setColourText(view.getShowColourText());
3677 af.viewport.setConservationSelected(view.getConservationSelected());
3678 af.viewport.setShowJVSuffix(view.getShowFullId());
3679 af.viewport.setRightAlignIds(view.getRightAlignIds());
3680 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3681 .getFontStyle(), view.getFontSize()));
3682 af.alignPanel.fontChanged();
3683 af.viewport.setRenderGaps(view.getRenderGaps());
3684 af.viewport.setWrapAlignment(view.getWrapAlignment());
3685 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3686 af.viewport.setShowAnnotation(view.getShowAnnotation());
3687 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3689 af.viewport.setShowBoxes(view.getShowBoxes());
3691 af.viewport.setShowText(view.getShowText());
3693 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3694 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3695 af.viewport.thresholdTextColour = view.getTextColThreshold();
3696 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3697 .isShowUnconserved() : false);
3698 af.viewport.setStartRes(view.getStartRes());
3699 af.viewport.setStartSeq(view.getStartSeq());
3701 ColourSchemeI cs = null;
3702 // apply colourschemes
3703 if (view.getBgColour() != null)
3705 if (view.getBgColour().startsWith("ucs"))
3707 cs = getUserColourScheme(jms, view.getBgColour());
3709 else if (view.getBgColour().startsWith("Annotation"))
3711 AnnotationColours viewAnnColour = view.getAnnotationColours();
3712 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3719 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3724 cs.setThreshold(view.getPidThreshold(), true);
3725 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3729 af.viewport.setGlobalColourScheme(cs);
3730 af.viewport.setColourAppliesToAllGroups(false);
3732 if (view.getConservationSelected() && cs != null)
3734 cs.setConservationInc(view.getConsThreshold());
3737 af.changeColour(cs);
3739 af.viewport.setColourAppliesToAllGroups(true);
3741 if (view.getShowSequenceFeatures())
3743 af.viewport.showSequenceFeatures = true;
3745 if (view.hasCentreColumnLabels())
3747 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3749 if (view.hasIgnoreGapsinConsensus())
3751 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3754 if (view.hasFollowHighlight())
3756 af.viewport.followHighlight = view.getFollowHighlight();
3758 if (view.hasFollowSelection())
3760 af.viewport.followSelection = view.getFollowSelection();
3762 if (view.hasShowConsensusHistogram())
3764 af.viewport.setShowConsensusHistogram(view
3765 .getShowConsensusHistogram());
3769 af.viewport.setShowConsensusHistogram(true);
3771 if (view.hasShowSequenceLogo())
3773 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3777 af.viewport.setShowSequenceLogo(false);
3779 if (view.hasNormaliseSequenceLogo())
3781 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3783 if (view.hasShowDbRefTooltip())
3785 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3787 if (view.hasShowNPfeatureTooltip())
3789 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3791 if (view.hasShowGroupConsensus())
3793 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3797 af.viewport.setShowGroupConsensus(false);
3799 if (view.hasShowGroupConservation())
3801 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3805 af.viewport.setShowGroupConservation(false);
3808 // recover featre settings
3809 if (jms.getFeatureSettings() != null)
3811 af.viewport.setFeaturesDisplayed(new Hashtable());
3812 String[] renderOrder = new String[jms.getFeatureSettings()
3813 .getSettingCount()];
3814 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3816 Setting setting = jms.getFeatureSettings().getSetting(fs);
3817 if (setting.hasMincolour())
3819 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3820 new java.awt.Color(setting.getMincolour()),
3821 new java.awt.Color(setting.getColour()),
3822 setting.getMin(), setting.getMax()) : new GraduatedColor(
3823 new java.awt.Color(setting.getMincolour()),
3824 new java.awt.Color(setting.getColour()), 0, 1);
3825 if (setting.hasThreshold())
3827 gc.setThresh(setting.getThreshold());
3828 gc.setThreshType(setting.getThreshstate());
3830 gc.setAutoScaled(true); // default
3831 if (setting.hasAutoScale())
3833 gc.setAutoScaled(setting.getAutoScale());
3835 if (setting.hasColourByLabel())
3837 gc.setColourByLabel(setting.getColourByLabel());
3839 // and put in the feature colour table.
3840 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3841 setting.getType(), gc);
3845 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
3847 new java.awt.Color(setting.getColour()));
3849 renderOrder[fs] = setting.getType();
3850 if (setting.hasOrder())
3852 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3853 setting.getType(), setting.getOrder());
3857 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
3859 fs / jms.getFeatureSettings().getSettingCount());
3861 if (setting.getDisplay())
3863 af.viewport.getFeaturesDisplayed().put(setting.getType(), new Integer(
3864 setting.getColour()));
3867 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3869 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3870 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3872 Group grp = jms.getFeatureSettings().getGroup(gs);
3873 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3877 if (view.getHiddenColumnsCount() > 0)
3879 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3881 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3882 .getHiddenColumns(c).getEnd() // +1
3886 if (view.getCalcIdParam() != null)
3888 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3890 if (calcIdParam != null)
3892 if (recoverCalcIdParam(calcIdParam, af.viewport))
3897 warn("Couldn't recover parameters for "
3898 + calcIdParam.getCalcId());
3903 af.setMenusFromViewport(af.viewport);
3904 // TODO: we don't need to do this if the viewport is aready visible.
3905 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3907 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3908 reorderAutoannotation(af, al, autoAlan);
3909 af.alignPanel.alignmentChanged();
3913 private ColourSchemeI constructAnnotationColour(
3914 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3915 JalviewModelSequence jms, boolean checkGroupAnnColour)
3917 boolean propagateAnnColour = false;
3918 ColourSchemeI cs = null;
3919 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3920 if (checkGroupAnnColour && al.getGroups() != null
3921 && al.getGroups().size() > 0)
3923 // pre 2.8.1 behaviour
3924 // check to see if we should transfer annotation colours
3925 propagateAnnColour = true;
3926 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3928 if (sg.cs instanceof AnnotationColourGradient)
3930 propagateAnnColour = false;
3934 // int find annotation
3935 if (annAlignment.getAlignmentAnnotation() != null)
3937 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3939 if (annAlignment.getAlignmentAnnotation()[i].label
3940 .equals(viewAnnColour.getAnnotation()))
3942 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3944 annAlignment.getAlignmentAnnotation()[i]
3945 .setThreshold(new jalview.datamodel.GraphLine(
3946 viewAnnColour.getThreshold(), "Threshold",
3947 java.awt.Color.black)
3952 if (viewAnnColour.getColourScheme().equals("None"))
3954 cs = new AnnotationColourGradient(
3955 annAlignment.getAlignmentAnnotation()[i],
3956 new java.awt.Color(viewAnnColour.getMinColour()),
3957 new java.awt.Color(viewAnnColour.getMaxColour()),
3958 viewAnnColour.getAboveThreshold());
3960 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3962 cs = new AnnotationColourGradient(
3963 annAlignment.getAlignmentAnnotation()[i],
3964 getUserColourScheme(jms,
3965 viewAnnColour.getColourScheme()),
3966 viewAnnColour.getAboveThreshold());
3970 cs = new AnnotationColourGradient(
3971 annAlignment.getAlignmentAnnotation()[i],
3972 ColourSchemeProperty.getColour(al,
3973 viewAnnColour.getColourScheme()),
3974 viewAnnColour.getAboveThreshold());
3976 if (viewAnnColour.hasPerSequence())
3978 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3981 if (viewAnnColour.hasPredefinedColours())
3983 ((AnnotationColourGradient) cs)
3984 .setPredefinedColours(viewAnnColour
3985 .isPredefinedColours());
3987 if (propagateAnnColour && al.getGroups() != null)
3989 // Also use these settings for all the groups
3990 for (int g = 0; g < al.getGroups().size(); g++)
3992 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4000 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4001 * new AnnotationColourGradient(
4002 * annAlignment.getAlignmentAnnotation()[i], new
4003 * java.awt.Color(viewAnnColour. getMinColour()), new
4004 * java.awt.Color(viewAnnColour. getMaxColour()),
4005 * viewAnnColour.getAboveThreshold()); } else
4008 sg.cs = new AnnotationColourGradient(
4009 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4010 viewAnnColour.getAboveThreshold());
4011 if (cs instanceof AnnotationColourGradient)
4013 if (viewAnnColour.hasPerSequence())
4015 ((AnnotationColourGradient) cs)
4016 .setSeqAssociated(viewAnnColour.isPerSequence());
4018 if (viewAnnColour.hasPredefinedColours())
4020 ((AnnotationColourGradient) cs)
4021 .setPredefinedColours(viewAnnColour
4022 .isPredefinedColours());
4038 private void reorderAutoannotation(AlignFrame af, Alignment al,
4039 ArrayList<JvAnnotRow> autoAlan)
4041 // copy over visualization settings for autocalculated annotation in the
4043 if (al.getAlignmentAnnotation() != null)
4046 * Kludge for magic autoannotation names (see JAL-811)
4048 String[] magicNames = new String[]
4049 { "Consensus", "Quality", "Conservation" };
4050 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4051 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4052 for (String nm : magicNames)
4054 visan.put(nm, nullAnnot);
4056 for (JvAnnotRow auan : autoAlan)
4058 visan.put(auan.template.label
4059 + (auan.template.getCalcId() == null ? "" : "\t"
4060 + auan.template.getCalcId()), auan);
4062 int hSize = al.getAlignmentAnnotation().length;
4063 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4064 // work through any autoCalculated annotation already on the view
4065 // removing it if it should be placed in a different location on the
4066 // annotation panel.
4067 List<String> remains = new ArrayList(visan.keySet());
4068 for (int h = 0; h < hSize; h++)
4070 jalview.datamodel.AlignmentAnnotation jalan = al
4071 .getAlignmentAnnotation()[h];
4072 if (jalan.autoCalculated)
4075 JvAnnotRow valan = visan.get(k = jalan.label);
4076 if (jalan.getCalcId() != null)
4078 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4083 // delete the auto calculated row from the alignment
4084 al.deleteAnnotation(jalan, false);
4088 if (valan != nullAnnot)
4090 if (jalan != valan.template)
4092 // newly created autoannotation row instance
4093 // so keep a reference to the visible annotation row
4094 // and copy over all relevant attributes
4095 if (valan.template.graphHeight >= 0)
4098 jalan.graphHeight = valan.template.graphHeight;
4100 jalan.visible = valan.template.visible;
4102 reorder.add(new JvAnnotRow(valan.order, jalan));
4107 // Add any (possibly stale) autocalculated rows that were not appended to
4108 // the view during construction
4109 for (String other : remains)
4111 JvAnnotRow othera = visan.get(other);
4112 if (othera != nullAnnot && othera.template.getCalcId() != null
4113 && othera.template.getCalcId().length() > 0)
4115 reorder.add(othera);
4118 // now put the automatic annotation in its correct place
4119 int s = 0, srt[] = new int[reorder.size()];
4120 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4121 for (JvAnnotRow jvar : reorder)
4124 srt[s++] = jvar.order;
4127 jalview.util.QuickSort.sort(srt, rws);
4128 // and re-insert the annotation at its correct position
4129 for (JvAnnotRow jvar : rws)
4131 al.addAnnotation(jvar.template, jvar.order);
4133 af.alignPanel.adjustAnnotationHeight();
4137 Hashtable skipList = null;
4140 * TODO remove this method
4143 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4144 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4145 * throw new Error("Implementation Error. No skipList defined for this
4146 * Jalview2XML instance."); } return (AlignFrame)
4147 * skipList.get(view.getSequenceSetId()); }
4151 * Check if the Jalview view contained in object should be skipped or not.
4154 * @return true if view's sequenceSetId is a key in skipList
4156 private boolean skipViewport(JalviewModel object)
4158 if (skipList == null)
4163 if (skipList.containsKey(id = object.getJalviewModelSequence()
4164 .getViewport()[0].getSequenceSetId()))
4166 if (Cache.log != null && Cache.log.isDebugEnabled())
4168 Cache.log.debug("Skipping seuqence set id " + id);
4175 public void addToSkipList(AlignFrame af)
4177 if (skipList == null)
4179 skipList = new Hashtable();
4181 skipList.put(af.getViewport().getSequenceSetId(), af);
4184 public void clearSkipList()
4186 if (skipList != null)
4193 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4194 boolean ignoreUnrefed)
4196 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4197 Vector dseqs = null;
4200 // create a list of new dataset sequences
4201 dseqs = new Vector();
4203 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4205 Sequence vamsasSeq = vamsasSet.getSequence(i);
4206 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4208 // create a new dataset
4211 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4212 dseqs.copyInto(dsseqs);
4213 ds = new jalview.datamodel.Alignment(dsseqs);
4214 debug("Created new dataset " + vamsasSet.getDatasetId()
4215 + " for alignment " + System.identityHashCode(al));
4216 addDatasetRef(vamsasSet.getDatasetId(), ds);
4218 // set the dataset for the newly imported alignment.
4219 if (al.getDataset() == null && !ignoreUnrefed)
4228 * sequence definition to create/merge dataset sequence for
4232 * vector to add new dataset sequence to
4234 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4235 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4237 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4239 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
4240 .get(vamsasSeq.getId());
4241 jalview.datamodel.SequenceI dsq = null;
4242 if (sq != null && sq.getDatasetSequence() != null)
4244 dsq = sq.getDatasetSequence();
4246 if (sq == null && ignoreUnrefed)
4250 String sqid = vamsasSeq.getDsseqid();
4253 // need to create or add a new dataset sequence reference to this sequence
4256 dsq = seqRefIds.get(sqid);
4261 // make a new dataset sequence
4262 dsq = sq.createDatasetSequence();
4265 // make up a new dataset reference for this sequence
4266 sqid = seqHash(dsq);
4268 dsq.setVamsasId(uniqueSetSuffix + sqid);
4269 seqRefIds.put(sqid, dsq);
4274 dseqs.addElement(dsq);
4279 ds.addSequence(dsq);
4285 { // make this dataset sequence sq's dataset sequence
4286 sq.setDatasetSequence(dsq);
4287 // and update the current dataset alignment
4292 if (!dseqs.contains(dsq))
4299 if (ds.findIndex(dsq) < 0)
4301 ds.addSequence(dsq);
4308 // TODO: refactor this as a merge dataset sequence function
4309 // now check that sq (the dataset sequence) sequence really is the union of
4310 // all references to it
4311 // boolean pre = sq.getStart() < dsq.getStart();
4312 // boolean post = sq.getEnd() > dsq.getEnd();
4316 StringBuffer sb = new StringBuffer();
4317 String newres = jalview.analysis.AlignSeq.extractGaps(
4318 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4319 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4320 && newres.length() > dsq.getLength())
4322 // Update with the longer sequence.
4326 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4327 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4328 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4329 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4331 dsq.setSequence(newres);
4333 // TODO: merges will never happen if we 'know' we have the real dataset
4334 // sequence - this should be detected when id==dssid
4336 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4337 // + (pre ? "prepended" : "") + " "
4338 // + (post ? "appended" : ""));
4343 java.util.Hashtable datasetIds = null;
4345 java.util.IdentityHashMap dataset2Ids = null;
4347 private Alignment getDatasetFor(String datasetId)
4349 if (datasetIds == null)
4351 datasetIds = new Hashtable();
4354 if (datasetIds.containsKey(datasetId))
4356 return (Alignment) datasetIds.get(datasetId);
4361 private void addDatasetRef(String datasetId, Alignment dataset)
4363 if (datasetIds == null)
4365 datasetIds = new Hashtable();
4367 datasetIds.put(datasetId, dataset);
4371 * make a new dataset ID for this jalview dataset alignment
4376 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4378 if (dataset.getDataset() != null)
4380 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4382 String datasetId = makeHashCode(dataset, null);
4383 if (datasetId == null)
4385 // make a new datasetId and record it
4386 if (dataset2Ids == null)
4388 dataset2Ids = new IdentityHashMap();
4392 datasetId = (String) dataset2Ids.get(dataset);
4394 if (datasetId == null)
4396 datasetId = "ds" + dataset2Ids.size() + 1;
4397 dataset2Ids.put(dataset, datasetId);
4403 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4405 for (int d = 0; d < sequence.getDBRefCount(); d++)
4407 DBRef dr = sequence.getDBRef(d);
4408 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4409 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4410 .getVersion(), sequence.getDBRef(d).getAccessionId());
4411 if (dr.getMapping() != null)
4413 entry.setMap(addMapping(dr.getMapping()));
4415 datasetSequence.addDBRef(entry);
4419 private jalview.datamodel.Mapping addMapping(Mapping m)
4421 SequenceI dsto = null;
4422 // Mapping m = dr.getMapping();
4423 int fr[] = new int[m.getMapListFromCount() * 2];
4424 Enumeration f = m.enumerateMapListFrom();
4425 for (int _i = 0; f.hasMoreElements(); _i += 2)
4427 MapListFrom mf = (MapListFrom) f.nextElement();
4428 fr[_i] = mf.getStart();
4429 fr[_i + 1] = mf.getEnd();
4431 int fto[] = new int[m.getMapListToCount() * 2];
4432 f = m.enumerateMapListTo();
4433 for (int _i = 0; f.hasMoreElements(); _i += 2)
4435 MapListTo mf = (MapListTo) f.nextElement();
4436 fto[_i] = mf.getStart();
4437 fto[_i + 1] = mf.getEnd();
4439 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4440 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4441 if (m.getMappingChoice() != null)
4443 MappingChoice mc = m.getMappingChoice();
4444 if (mc.getDseqFor() != null)
4446 String dsfor = "" + mc.getDseqFor();
4447 if (seqRefIds.containsKey(dsfor))
4452 jmap.setTo(seqRefIds.get(dsfor));
4456 frefedSequence.add(new Object[]
4463 * local sequence definition
4465 Sequence ms = mc.getSequence();
4466 jalview.datamodel.Sequence djs = null;
4467 String sqid = ms.getDsseqid();
4468 if (sqid != null && sqid.length() > 0)
4471 * recover dataset sequence
4473 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4478 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4479 sqid = ((Object) ms).toString(); // make up a new hascode for
4480 // undefined dataset sequence hash
4481 // (unlikely to happen)
4487 * make a new dataset sequence and add it to refIds hash
4489 djs = new jalview.datamodel.Sequence(ms.getName(),
4491 djs.setStart(jmap.getMap().getToLowest());
4492 djs.setEnd(jmap.getMap().getToHighest());
4493 djs.setVamsasId(uniqueSetSuffix + sqid);
4495 seqRefIds.put(sqid, djs);
4498 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4507 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4508 boolean keepSeqRefs)
4511 jalview.schemabinding.version2.JalviewModel jm = saveState(ap, null,
4517 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4521 uniqueSetSuffix = "";
4522 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4527 if (this.frefedSequence == null)
4529 frefedSequence = new Vector();
4532 viewportsAdded = new Hashtable();
4534 AlignFrame af = loadFromObject(jm, null, false, null);
4535 af.alignPanels.clear();
4536 af.closeMenuItem_actionPerformed(true);
4539 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4540 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4541 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4542 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4543 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4546 return af.alignPanel;
4550 * flag indicating if hashtables should be cleared on finalization TODO this
4551 * flag may not be necessary
4553 private final boolean _cleartables = true;
4555 private Hashtable jvids2vobj;
4560 * @see java.lang.Object#finalize()
4563 protected void finalize() throws Throwable
4565 // really make sure we have no buried refs left.
4570 this.seqRefIds = null;
4571 this.seqsToIds = null;
4575 private void warn(String msg)
4580 private void warn(String msg, Exception e)
4582 if (Cache.log != null)
4586 Cache.log.warn(msg, e);
4590 Cache.log.warn(msg);
4595 System.err.println("Warning: " + msg);
4598 e.printStackTrace();
4603 private void debug(String string)
4605 debug(string, null);
4608 private void debug(String msg, Exception e)
4610 if (Cache.log != null)
4614 Cache.log.debug(msg, e);
4618 Cache.log.debug(msg);
4623 System.err.println("Warning: " + msg);
4626 e.printStackTrace();
4632 * set the object to ID mapping tables used to write/recover objects and XML
4633 * ID strings for the jalview project. If external tables are provided then
4634 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4635 * object goes out of scope. - also populates the datasetIds hashtable with
4636 * alignment objects containing dataset sequences
4639 * Map from ID strings to jalview datamodel
4641 * Map from jalview datamodel to ID strings
4645 public void setObjectMappingTables(Hashtable vobj2jv,
4646 IdentityHashMap jv2vobj)
4648 this.jv2vobj = jv2vobj;
4649 this.vobj2jv = vobj2jv;
4650 Iterator ds = jv2vobj.keySet().iterator();
4652 while (ds.hasNext())
4654 Object jvobj = ds.next();
4655 id = jv2vobj.get(jvobj).toString();
4656 if (jvobj instanceof jalview.datamodel.Alignment)
4658 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4660 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4663 else if (jvobj instanceof jalview.datamodel.Sequence)
4665 // register sequence object so the XML parser can recover it.
4666 if (seqRefIds == null)
4668 seqRefIds = new HashMap<String, SequenceI>();
4670 if (seqsToIds == null)
4672 seqsToIds = new IdentityHashMap<SequenceI, String>();
4674 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
4675 seqsToIds.put((SequenceI) jvobj, id);
4677 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4679 if (annotationIds == null)
4681 annotationIds = new Hashtable();
4684 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4685 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4686 if (jvann.annotationId == null)
4688 jvann.annotationId = anid;
4690 if (!jvann.annotationId.equals(anid))
4692 // TODO verify that this is the correct behaviour
4693 this.warn("Overriding Annotation ID for " + anid
4694 + " from different id : " + jvann.annotationId);
4695 jvann.annotationId = anid;
4698 else if (jvobj instanceof String)
4700 if (jvids2vobj == null)
4702 jvids2vobj = new Hashtable();
4703 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4708 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4714 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4715 * objects created from the project archive. If string is null (default for
4716 * construction) then suffix will be set automatically.
4720 public void setUniqueSetSuffix(String string)
4722 uniqueSetSuffix = string;
4727 * uses skipList2 as the skipList for skipping views on sequence sets
4728 * associated with keys in the skipList
4732 public void setSkipList(Hashtable skipList2)
4734 skipList = skipList2;