2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import java.awt.Rectangle;
22 import java.lang.reflect.InvocationTargetException;
25 import java.util.Map.Entry;
26 import java.util.jar.*;
30 import org.exolab.castor.xml.*;
32 import uk.ac.vamsas.objects.utils.MapList;
33 import jalview.bin.Cache;
34 import jalview.datamodel.Alignment;
35 import jalview.datamodel.AlignmentAnnotation;
36 import jalview.datamodel.AlignmentI;
37 import jalview.datamodel.SequenceI;
38 import jalview.schemabinding.version2.*;
39 import jalview.schemes.*;
40 import jalview.structure.StructureSelectionManager;
41 import jalview.util.jarInputStreamProvider;
44 * Write out the current jalview desktop state as a Jalview XML stream.
46 * Note: the vamsas objects referred to here are primitive versions of the
47 * VAMSAS project schema elements - they are not the same and most likely never
51 * @version $Revision: 1.134 $
53 public class Jalview2XML
56 * create/return unique hash string for sq
59 * @return new or existing unique string for sq
61 String seqHash(SequenceI sq)
63 if (seqsToIds == null)
67 if (seqsToIds.containsKey(sq))
69 return (String) seqsToIds.get(sq);
73 // create sequential key
74 String key = "sq" + (seqsToIds.size() + 1);
75 key = makeHashCode(sq, key); // check we don't have an external reference
77 seqsToIds.put(sq, key);
86 if (seqRefIds != null)
90 if (seqsToIds != null)
100 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
101 // seqRefIds = new Hashtable();
102 // seqsToIds = new IdentityHashMap();
108 if (seqsToIds == null)
110 seqsToIds = new IdentityHashMap();
112 if (seqRefIds == null)
114 seqRefIds = new Hashtable();
119 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
120 * of sequence objects are created.
122 java.util.IdentityHashMap seqsToIds = null;
125 * jalview XML Sequence ID to jalview sequence object reference (both dataset
126 * and alignment sequences. Populated as XML reps of sequence objects are
129 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
131 Vector frefedSequence = null;
133 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
139 public Jalview2XML(boolean raiseGUI)
141 this.raiseGUI = raiseGUI;
144 public void resolveFrefedSequences()
146 if (frefedSequence.size() > 0)
148 int r = 0, rSize = frefedSequence.size();
151 Object[] ref = (Object[]) frefedSequence.elementAt(r);
154 String sref = (String) ref[0];
155 if (seqRefIds.containsKey(sref))
157 if (ref[1] instanceof jalview.datamodel.Mapping)
159 SequenceI seq = (SequenceI) seqRefIds.get(sref);
160 while (seq.getDatasetSequence() != null)
162 seq = seq.getDatasetSequence();
164 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
168 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
170 SequenceI seq = (SequenceI) seqRefIds.get(sref);
171 while (seq.getDatasetSequence() != null)
173 seq = seq.getDatasetSequence();
176 && ref[2] instanceof jalview.datamodel.Mapping)
178 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
179 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
180 seq, mp.getTo(), mp.getMap());
185 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
186 + ref[2].getClass() + " type objects.");
192 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
193 + ref[1].getClass() + " type objects.");
196 frefedSequence.remove(r);
202 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
204 + " with objecttype "
205 + ref[1].getClass());
212 frefedSequence.remove(r);
220 * This maintains a list of viewports, the key being the seqSetId. Important
221 * to set historyItem and redoList for multiple views
223 Hashtable viewportsAdded;
225 Hashtable annotationIds = new Hashtable();
227 String uniqueSetSuffix = "";
230 * List of pdbfiles added to Jar
232 Vector pdbfiles = null;
234 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
235 public void SaveState(File statefile)
239 FileOutputStream fos = new FileOutputStream(statefile);
240 JarOutputStream jout = new JarOutputStream(fos);
243 } catch (Exception e)
245 // TODO: inform user of the problem - they need to know if their data was
247 if (errorMessage == null)
249 errorMessage = "Couldn't write Jalview Archive to output file '"
250 + statefile + "' - See console error log for details";
254 errorMessage += "(output file was '" + statefile + "')";
262 * Writes a jalview project archive to the given Jar output stream.
266 public void SaveState(JarOutputStream jout)
268 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
278 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
279 // //////////////////////////////////////////////////
280 // NOTE ALSO new PrintWriter must be used for each new JarEntry
281 PrintWriter out = null;
283 Vector shortNames = new Vector();
286 for (int i = frames.length - 1; i > -1; i--)
288 if (frames[i] instanceof AlignFrame)
290 AlignFrame af = (AlignFrame) frames[i];
293 && skipList.containsKey(af.getViewport()
294 .getSequenceSetId()))
299 String shortName = af.getTitle();
301 if (shortName.indexOf(File.separatorChar) > -1)
303 shortName = shortName.substring(shortName
304 .lastIndexOf(File.separatorChar) + 1);
309 while (shortNames.contains(shortName))
311 if (shortName.endsWith("_" + (count - 1)))
313 shortName = shortName
314 .substring(0, shortName.lastIndexOf("_"));
317 shortName = shortName.concat("_" + count);
321 shortNames.addElement(shortName);
323 if (!shortName.endsWith(".xml"))
325 shortName = shortName + ".xml";
328 int ap, apSize = af.alignPanels.size();
329 for (ap = 0; ap < apSize; ap++)
331 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
333 String fileName = apSize == 1 ? shortName : ap + shortName;
334 if (!fileName.endsWith(".xml"))
336 fileName = fileName + ".xml";
339 SaveState(apanel, fileName, jout);
346 } catch (Exception foo)
351 } catch (Exception ex)
353 // TODO: inform user of the problem - they need to know if their data was
355 if (errorMessage == null)
357 errorMessage = "Couldn't write Jalview Archive - see error output for details";
359 ex.printStackTrace();
363 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
364 public boolean SaveAlignment(AlignFrame af, String jarFile,
369 int ap, apSize = af.alignPanels.size();
370 FileOutputStream fos = new FileOutputStream(jarFile);
371 JarOutputStream jout = new JarOutputStream(fos);
372 for (ap = 0; ap < apSize; ap++)
374 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
376 String jfileName = apSize == 1 ? fileName : fileName + ap;
377 if (!jfileName.endsWith(".xml"))
379 jfileName = jfileName + ".xml";
381 SaveState(apanel, jfileName, jout);
387 } catch (Exception foo)
393 } catch (Exception ex)
395 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
396 ex.printStackTrace();
402 * create a JalviewModel from an algnment view and marshall it to a
406 * panel to create jalview model for
408 * name of alignment panel written to output stream
414 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
415 JarOutputStream jout)
418 Vector jmolViewIds = new Vector(); //
419 Vector userColours = new Vector();
421 AlignViewport av = ap.av;
423 JalviewModel object = new JalviewModel();
424 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
426 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
427 object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
429 jalview.datamodel.AlignmentI jal = av.alignment;
431 if (av.hasHiddenRows)
433 jal = jal.getHiddenSequences().getFullAlignment();
436 SequenceSet vamsasSet = new SequenceSet();
438 JalviewModelSequence jms = new JalviewModelSequence();
440 vamsasSet.setGapChar(jal.getGapCharacter() + "");
442 if (jal.getDataset() != null)
444 // dataset id is the dataset's hashcode
445 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
447 if (jal.getProperties() != null)
449 Enumeration en = jal.getProperties().keys();
450 while (en.hasMoreElements())
452 String key = en.nextElement().toString();
453 SequenceSetProperties ssp = new SequenceSetProperties();
455 ssp.setValue(jal.getProperties().get(key).toString());
456 vamsasSet.addSequenceSetProperties(ssp);
464 jalview.datamodel.SequenceI jds;
465 for (int i = 0; i < jal.getHeight(); i++)
467 jds = jal.getSequenceAt(i);
470 if (seqRefIds.get(id) != null)
472 // This happens for two reasons: 1. multiple views are being serialised.
473 // 2. the hashCode has collided with another sequence's code. This DOES
474 // HAPPEN! (PF00072.15.stk does this)
475 // JBPNote: Uncomment to debug writing out of files that do not read
476 // back in due to ArrayOutOfBoundExceptions.
477 // System.err.println("vamsasSeq backref: "+id+"");
478 // System.err.println(jds.getName()+"
479 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
480 // System.err.println("Hashcode: "+seqHash(jds));
481 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
482 // System.err.println(rsq.getName()+"
483 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
484 // System.err.println("Hashcode: "+seqHash(rsq));
488 vamsasSeq = createVamsasSequence(id, jds);
489 vamsasSet.addSequence(vamsasSeq);
490 seqRefIds.put(id, jds);
494 jseq.setStart(jds.getStart());
495 jseq.setEnd(jds.getEnd());
496 jseq.setColour(av.getSequenceColour(jds).getRGB());
498 jseq.setId(id); // jseq id should be a string not a number
500 if (av.hasHiddenRows)
502 jseq.setHidden(av.alignment.getHiddenSequences().isHidden(jds));
504 if (av.hiddenRepSequences != null
505 && av.hiddenRepSequences.containsKey(jal.getSequenceAt(i)))
507 jalview.datamodel.SequenceI[] reps = ((jalview.datamodel.SequenceGroup) av.hiddenRepSequences
508 .get(jal.getSequenceAt(i))).getSequencesInOrder(jal);
510 for (int h = 0; h < reps.length; h++)
512 if (reps[h] != jal.getSequenceAt(i))
514 jseq.addHiddenSequences(jal.findIndex(reps[h]));
520 if (jds.getDatasetSequence().getSequenceFeatures() != null)
522 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
523 .getSequenceFeatures();
525 while (index < sf.length)
527 Features features = new Features();
529 features.setBegin(sf[index].getBegin());
530 features.setEnd(sf[index].getEnd());
531 features.setDescription(sf[index].getDescription());
532 features.setType(sf[index].getType());
533 features.setFeatureGroup(sf[index].getFeatureGroup());
534 features.setScore(sf[index].getScore());
535 if (sf[index].links != null)
537 for (int l = 0; l < sf[index].links.size(); l++)
539 OtherData keyValue = new OtherData();
540 keyValue.setKey("LINK_" + l);
541 keyValue.setValue(sf[index].links.elementAt(l).toString());
542 features.addOtherData(keyValue);
545 if (sf[index].otherDetails != null)
548 Enumeration keys = sf[index].otherDetails.keys();
549 while (keys.hasMoreElements())
551 key = keys.nextElement().toString();
552 OtherData keyValue = new OtherData();
553 keyValue.setKey(key);
554 keyValue.setValue(sf[index].otherDetails.get(key).toString());
555 features.addOtherData(keyValue);
559 jseq.addFeatures(features);
564 if (jds.getDatasetSequence().getPDBId() != null)
566 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
567 while (en.hasMoreElements())
569 Pdbids pdb = new Pdbids();
570 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
573 pdb.setId(entry.getId());
574 pdb.setType(entry.getType());
577 // This must have been loaded, is it still visible?
578 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
579 String matchedFile = null;
580 for (int f = frames.length - 1; f > -1; f--)
582 if (frames[f] instanceof AppJmol)
584 jmol = (AppJmol) frames[f];
585 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
587 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
588 && !(entry.getId().length() > 4 && entry
592 jmol.jmb.pdbentry[peid].getId()
595 if (matchedFile == null)
597 matchedFile = jmol.jmb.pdbentry[peid].getFile();
599 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
603 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
604 + jmol.jmb.pdbentry[peid].getFile());
608 // can get at it if the ID
609 // match is ambiguous (e.g.
611 String statestring = jmol.jmb.viewer.getStateInfo();
613 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
615 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
616 if (jds==jmol.jmb.sequence[peid][smap])
618 StructureState state = new StructureState();
619 state.setVisible(true);
620 state.setXpos(jmol.getX());
621 state.setYpos(jmol.getY());
622 state.setWidth(jmol.getWidth());
623 state.setHeight(jmol.getHeight());
624 state.setViewId(jmol.getViewId());
625 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
626 state.setColourwithAlignPanel(jmol
627 .isUsedforcolourby(ap));
628 state.setColourByJmol(jmol.isColouredByJmol());
629 if (!jmolViewIds.contains(state.getViewId()))
631 // Make sure we only store a Jmol state once in each XML
633 jmolViewIds.addElement(state.getViewId());
634 state.setContent(statestring.replaceAll("\n", ""));
638 state.setContent("# duplicate state");
640 pdb.addStructureState(state);
647 if (matchedFile != null || entry.getFile() != null)
649 if (entry.getFile() != null)
652 matchedFile = entry.getFile();
654 pdb.setFile(matchedFile); // entry.getFile());
655 if (pdbfiles == null)
657 pdbfiles = new Vector();
660 if (!pdbfiles.contains(entry.getId()))
662 pdbfiles.addElement(entry.getId());
665 File file = new File(matchedFile);
666 if (file.exists() && jout != null)
668 byte[] data = new byte[(int) file.length()];
669 jout.putNextEntry(new JarEntry(entry.getId()));
670 DataInputStream dis = new DataInputStream(
671 new FileInputStream(file));
674 DataOutputStream dout = new DataOutputStream(jout);
675 dout.write(data, 0, data.length);
679 } catch (Exception ex)
681 ex.printStackTrace();
687 if (entry.getProperty() != null)
689 PdbentryItem item = new PdbentryItem();
690 Hashtable properties = entry.getProperty();
691 Enumeration en2 = properties.keys();
692 while (en2.hasMoreElements())
694 Property prop = new Property();
695 String key = en2.nextElement().toString();
697 prop.setValue(properties.get(key).toString());
698 item.addProperty(prop);
700 pdb.addPdbentryItem(item);
710 if (av.hasHiddenRows)
715 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
717 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
718 for (int i = 0; i < jac.length; i++)
720 AlcodonFrame alc = new AlcodonFrame();
721 vamsasSet.addAlcodonFrame(alc);
722 for (int p = 0; p < jac[i].aaWidth; p++)
724 Alcodon cmap = new Alcodon();
725 if (jac[i].codons[p] != null)
727 // Null codons indicate a gapped column in the translated peptide
729 cmap.setPos1(jac[i].codons[p][0]);
730 cmap.setPos2(jac[i].codons[p][1]);
731 cmap.setPos3(jac[i].codons[p][2]);
733 alc.addAlcodon(cmap);
735 if (jac[i].getProtMappings() != null
736 && jac[i].getProtMappings().length > 0)
738 SequenceI[] dnas = jac[i].getdnaSeqs();
739 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
740 for (int m = 0; m < pmaps.length; m++)
742 AlcodMap alcmap = new AlcodMap();
743 alcmap.setDnasq(seqHash(dnas[m]));
744 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
746 alc.addAlcodMap(alcmap);
753 // /////////////////////////////////
754 if (av.currentTree != null)
756 // FIND ANY ASSOCIATED TREES
757 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
758 if (Desktop.desktop != null)
760 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
762 for (int t = 0; t < frames.length; t++)
764 if (frames[t] instanceof TreePanel)
766 TreePanel tp = (TreePanel) frames[t];
768 if (tp.treeCanvas.av.alignment == jal)
770 Tree tree = new Tree();
771 tree.setTitle(tp.getTitle());
772 tree.setCurrentTree((av.currentTree == tp.getTree()));
773 tree.setNewick(tp.getTree().toString());
774 tree.setThreshold(tp.treeCanvas.threshold);
776 tree.setFitToWindow(tp.fitToWindow.getState());
777 tree.setFontName(tp.getTreeFont().getName());
778 tree.setFontSize(tp.getTreeFont().getSize());
779 tree.setFontStyle(tp.getTreeFont().getStyle());
780 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
782 tree.setShowBootstrap(tp.bootstrapMenu.getState());
783 tree.setShowDistances(tp.distanceMenu.getState());
785 tree.setHeight(tp.getHeight());
786 tree.setWidth(tp.getWidth());
787 tree.setXpos(tp.getX());
788 tree.setYpos(tp.getY());
789 tree.setId(makeHashCode(tp, null));
799 * store forward refs from an annotationRow to any groups
801 IdentityHashMap groupRefs = new IdentityHashMap();
802 if (jal.getAlignmentAnnotation() != null)
804 jalview.datamodel.AlignmentAnnotation[] aa = jal
805 .getAlignmentAnnotation();
807 for (int i = 0; i < aa.length; i++)
809 Annotation an = new Annotation();
811 if (aa[i].annotationId != null)
813 annotationIds.put(aa[i].annotationId, aa[i]);
816 an.setId(aa[i].annotationId);
818 an.setVisible(aa[i].visible);
820 an.setDescription(aa[i].description);
822 if (aa[i].sequenceRef != null)
824 // TODO later annotation sequenceRef should be the XML ID of the
825 // sequence rather than its display name
826 an.setSequenceRef(aa[i].sequenceRef.getName());
828 if (aa[i].groupRef != null)
830 Object groupIdr = groupRefs.get(aa[i].groupRef);
831 if (groupIdr == null)
833 // make a locally unique String
834 groupRefs.put(aa[i].groupRef,
835 groupIdr = ("" + System.currentTimeMillis()
836 + aa[i].groupRef.getName() + groupRefs.size()));
838 an.setGroupRef(groupIdr.toString());
841 // store all visualization attributes for annotation
842 an.setGraphHeight(aa[i].graphHeight);
843 an.setCentreColLabels(aa[i].centreColLabels);
844 an.setScaleColLabels(aa[i].scaleColLabel);
845 an.setShowAllColLabels(aa[i].showAllColLabels);
850 an.setGraphType(aa[i].graph);
851 an.setGraphGroup(aa[i].graphGroup);
852 if (aa[i].getThreshold() != null)
854 ThresholdLine line = new ThresholdLine();
855 line.setLabel(aa[i].getThreshold().label);
856 line.setValue(aa[i].getThreshold().value);
857 line.setColour(aa[i].getThreshold().colour.getRGB());
858 an.setThresholdLine(line);
866 an.setLabel(aa[i].label);
868 if (aa[i] == av.quality || aa[i] == av.conservation
869 || aa[i] == av.consensus || aa[i].autoCalculated)
871 // new way of indicating autocalculated annotation -
872 an.setAutoCalculated(aa[i].autoCalculated);
874 if (aa[i].hasScore())
876 an.setScore(aa[i].getScore());
878 AnnotationElement ae;
879 if (aa[i].annotations != null)
881 an.setScoreOnly(false);
882 for (int a = 0; a < aa[i].annotations.length; a++)
884 if ((aa[i] == null) || (aa[i].annotations[a] == null))
889 ae = new AnnotationElement();
890 if (aa[i].annotations[a].description != null)
891 ae.setDescription(aa[i].annotations[a].description);
892 if (aa[i].annotations[a].displayCharacter != null)
893 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
895 if (!Float.isNaN(aa[i].annotations[a].value))
896 ae.setValue(aa[i].annotations[a].value);
899 if (aa[i].annotations[a].secondaryStructure != ' '
900 && aa[i].annotations[a].secondaryStructure != '\0')
901 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
904 if (aa[i].annotations[a].colour != null
905 && aa[i].annotations[a].colour != java.awt.Color.black)
907 ae.setColour(aa[i].annotations[a].colour.getRGB());
910 an.addAnnotationElement(ae);
911 if (aa[i].autoCalculated)
913 // only write one non-null entry into the annotation row -
914 // sufficient to get the visualization attributes necessary to
922 an.setScoreOnly(true);
924 vamsasSet.addAnnotation(an);
928 if (jal.getGroups() != null)
930 JGroup[] groups = new JGroup[jal.getGroups().size()];
932 for (int i = 0; i < groups.length; i++)
934 groups[i] = new JGroup();
936 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) jal
937 .getGroups().elementAt(i);
938 groups[i].setStart(sg.getStartRes());
939 groups[i].setEnd(sg.getEndRes());
940 groups[i].setName(sg.getName());
941 if (groupRefs.containsKey(sg))
943 // group has references so set it's ID field
944 groups[i].setId(groupRefs.get(sg).toString());
948 if (sg.cs.conservationApplied())
950 groups[i].setConsThreshold(sg.cs.getConservationInc());
952 if (sg.cs instanceof jalview.schemes.UserColourScheme)
954 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
960 .setColour(ColourSchemeProperty.getColourName(sg.cs));
963 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
966 .setColour(ColourSchemeProperty
967 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
970 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
973 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
977 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
980 groups[i].setPidThreshold(sg.cs.getThreshold());
983 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
984 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
985 groups[i].setDisplayText(sg.getDisplayText());
986 groups[i].setColourText(sg.getColourText());
987 groups[i].setTextCol1(sg.textColour.getRGB());
988 groups[i].setTextCol2(sg.textColour2.getRGB());
989 groups[i].setTextColThreshold(sg.thresholdTextColour);
990 groups[i].setShowUnconserved(sg.getShowNonconserved());
991 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
992 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
993 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
994 for (int s = 0; s < sg.getSize(); s++)
996 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
998 groups[i].addSeq(seqHash(seq));
1002 jms.setJGroup(groups);
1005 // /////////SAVE VIEWPORT
1006 Viewport view = new Viewport();
1007 view.setTitle(ap.alignFrame.getTitle());
1008 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1009 av.getSequenceSetId()));
1010 view.setId(av.getViewId());
1011 view.setViewName(av.viewName);
1012 view.setGatheredViews(av.gatherViewsHere);
1014 if (ap.av.explodedPosition != null)
1016 view.setXpos(av.explodedPosition.x);
1017 view.setYpos(av.explodedPosition.y);
1018 view.setWidth(av.explodedPosition.width);
1019 view.setHeight(av.explodedPosition.height);
1023 view.setXpos(ap.alignFrame.getBounds().x);
1024 view.setYpos(ap.alignFrame.getBounds().y);
1025 view.setWidth(ap.alignFrame.getBounds().width);
1026 view.setHeight(ap.alignFrame.getBounds().height);
1029 view.setStartRes(av.startRes);
1030 view.setStartSeq(av.startSeq);
1032 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1034 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1037 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1039 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1040 .getGlobalColourScheme();
1042 AnnotationColours ac = new AnnotationColours();
1043 ac.setAboveThreshold(acg.getAboveThreshold());
1044 ac.setThreshold(acg.getAnnotationThreshold());
1045 ac.setAnnotation(acg.getAnnotation());
1046 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1048 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1053 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1057 ac.setMaxColour(acg.getMaxColour().getRGB());
1058 ac.setMinColour(acg.getMinColour().getRGB());
1059 view.setAnnotationColours(ac);
1060 view.setBgColour("AnnotationColourGradient");
1064 view.setBgColour(ColourSchemeProperty.getColourName(av
1065 .getGlobalColourScheme()));
1068 ColourSchemeI cs = av.getGlobalColourScheme();
1072 if (cs.conservationApplied())
1074 view.setConsThreshold(cs.getConservationInc());
1075 if (cs instanceof jalview.schemes.UserColourScheme)
1077 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1081 if (cs instanceof ResidueColourScheme)
1083 view.setPidThreshold(cs.getThreshold());
1087 view.setConservationSelected(av.getConservationSelected());
1088 view.setPidSelected(av.getAbovePIDThreshold());
1089 view.setFontName(av.font.getName());
1090 view.setFontSize(av.font.getSize());
1091 view.setFontStyle(av.font.getStyle());
1092 view.setRenderGaps(av.renderGaps);
1093 view.setShowAnnotation(av.getShowAnnotation());
1094 view.setShowBoxes(av.getShowBoxes());
1095 view.setShowColourText(av.getColourText());
1096 view.setShowFullId(av.getShowJVSuffix());
1097 view.setRightAlignIds(av.rightAlignIds);
1098 view.setShowSequenceFeatures(av.showSequenceFeatures);
1099 view.setShowText(av.getShowText());
1100 view.setShowUnconserved(av.getShowUnconserved());
1101 view.setWrapAlignment(av.getWrapAlignment());
1102 view.setTextCol1(av.textColour.getRGB());
1103 view.setTextCol2(av.textColour2.getRGB());
1104 view.setTextColThreshold(av.thresholdTextColour);
1105 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1106 view.setShowSequenceLogo(av.isShowSequenceLogo());
1107 view.setShowGroupConsensus(av.isShowGroupConsensus());
1108 view.setShowGroupConservation(av.isShowGroupConservation());
1109 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1110 view.setShowDbRefTooltip(av.isShowDbRefs());
1111 view.setFollowHighlight(av.followHighlight);
1112 view.setFollowSelection(av.followSelection);
1113 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1114 if (av.featuresDisplayed != null)
1116 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1118 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1120 Vector settingsAdded = new Vector();
1121 Object gstyle = null;
1122 GraduatedColor gcol = null;
1123 if (renderOrder != null)
1125 for (int ro = 0; ro < renderOrder.length; ro++)
1127 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1128 .getFeatureStyle(renderOrder[ro]);
1129 Setting setting = new Setting();
1130 setting.setType(renderOrder[ro]);
1131 if (gstyle instanceof GraduatedColor)
1133 gcol = (GraduatedColor) gstyle;
1134 setting.setColour(gcol.getMaxColor().getRGB());
1135 setting.setMincolour(gcol.getMinColor().getRGB());
1136 setting.setMin(gcol.getMin());
1137 setting.setMax(gcol.getMax());
1138 setting.setColourByLabel(gcol.isColourByLabel());
1139 setting.setAutoScale(gcol.isAutoScale());
1140 setting.setThreshold(gcol.getThresh());
1141 setting.setThreshstate(gcol.getThreshType());
1145 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1146 .getColour(renderOrder[ro]).getRGB());
1149 setting.setDisplay(av.featuresDisplayed
1150 .containsKey(renderOrder[ro]));
1151 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1152 .getOrder(renderOrder[ro]);
1155 setting.setOrder(rorder);
1157 fs.addSetting(setting);
1158 settingsAdded.addElement(renderOrder[ro]);
1162 // Make sure we save none displayed feature settings
1163 Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1165 while (en.hasMoreElements())
1167 String key = en.nextElement().toString();
1168 if (settingsAdded.contains(key))
1173 Setting setting = new Setting();
1174 setting.setType(key);
1175 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1176 .getColour(key).getRGB());
1178 setting.setDisplay(false);
1179 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1183 setting.setOrder(rorder);
1185 fs.addSetting(setting);
1186 settingsAdded.addElement(key);
1188 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys();
1189 Vector groupsAdded = new Vector();
1190 while (en.hasMoreElements())
1192 String grp = en.nextElement().toString();
1193 if (groupsAdded.contains(grp))
1197 Group g = new Group();
1199 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1200 .get(grp)).booleanValue());
1202 groupsAdded.addElement(grp);
1204 jms.setFeatureSettings(fs);
1208 if (av.hasHiddenColumns)
1210 if (av.getColumnSelection() == null
1211 || av.getColumnSelection().getHiddenColumns() == null)
1213 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1217 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1220 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1222 HiddenColumns hc = new HiddenColumns();
1223 hc.setStart(region[0]);
1224 hc.setEnd(region[1]);
1225 view.addHiddenColumns(hc);
1230 jms.addViewport(view);
1232 object.setJalviewModelSequence(jms);
1233 object.getVamsasModel().addSequenceSet(vamsasSet);
1235 if (jout != null && fileName != null)
1237 // We may not want to write the object to disk,
1238 // eg we can copy the alignViewport to a new view object
1239 // using save and then load
1242 JarEntry entry = new JarEntry(fileName);
1243 jout.putNextEntry(entry);
1244 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1246 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1248 marshaller.marshal(object);
1251 } catch (Exception ex)
1253 // TODO: raise error in GUI if marshalling failed.
1254 ex.printStackTrace();
1261 * External mapping between jalview objects and objects yielding a valid and
1262 * unique object ID string. This is null for normal Jalview project IO, but
1263 * non-null when a jalview project is being read or written as part of a
1266 IdentityHashMap jv2vobj = null;
1269 * Construct a unique ID for jvobj using either existing bindings or if none
1270 * exist, the result of the hashcode call for the object.
1273 * jalview data object
1274 * @return unique ID for referring to jvobj
1276 private String makeHashCode(Object jvobj, String altCode)
1278 if (jv2vobj != null)
1280 Object id = jv2vobj.get(jvobj);
1283 return id.toString();
1285 // check string ID mappings
1286 if (jvids2vobj != null && jvobj instanceof String)
1288 id = jvids2vobj.get(jvobj);
1292 return id.toString();
1294 // give up and warn that something has gone wrong
1295 warn("Cannot find ID for object in external mapping : " + jvobj);
1301 * return local jalview object mapped to ID, if it exists
1305 * @return null or object bound to idcode
1307 private Object retrieveExistingObj(String idcode)
1309 if (idcode != null && vobj2jv != null)
1311 return vobj2jv.get(idcode);
1317 * binding from ID strings from external mapping table to jalview data model
1320 private Hashtable vobj2jv;
1322 private Sequence createVamsasSequence(String id, SequenceI jds)
1324 return createVamsasSequence(true, id, jds, null);
1327 private Sequence createVamsasSequence(boolean recurse, String id,
1328 SequenceI jds, SequenceI parentseq)
1330 Sequence vamsasSeq = new Sequence();
1331 vamsasSeq.setId(id);
1332 vamsasSeq.setName(jds.getName());
1333 vamsasSeq.setSequence(jds.getSequenceAsString());
1334 vamsasSeq.setDescription(jds.getDescription());
1335 jalview.datamodel.DBRefEntry[] dbrefs = null;
1336 if (jds.getDatasetSequence() != null)
1338 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1339 if (jds.getDatasetSequence().getDBRef() != null)
1341 dbrefs = jds.getDatasetSequence().getDBRef();
1346 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1347 // dataset sequences only
1348 dbrefs = jds.getDBRef();
1352 for (int d = 0; d < dbrefs.length; d++)
1354 DBRef dbref = new DBRef();
1355 dbref.setSource(dbrefs[d].getSource());
1356 dbref.setVersion(dbrefs[d].getVersion());
1357 dbref.setAccessionId(dbrefs[d].getAccessionId());
1358 if (dbrefs[d].hasMap())
1360 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1362 dbref.setMapping(mp);
1364 vamsasSeq.addDBRef(dbref);
1370 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1371 SequenceI parentseq, SequenceI jds, boolean recurse)
1374 if (jmp.getMap() != null)
1378 jalview.util.MapList mlst = jmp.getMap();
1379 int r[] = mlst.getFromRanges();
1380 for (int s = 0; s < r.length; s += 2)
1382 MapListFrom mfrom = new MapListFrom();
1383 mfrom.setStart(r[s]);
1384 mfrom.setEnd(r[s + 1]);
1385 mp.addMapListFrom(mfrom);
1387 r = mlst.getToRanges();
1388 for (int s = 0; s < r.length; s += 2)
1390 MapListTo mto = new MapListTo();
1392 mto.setEnd(r[s + 1]);
1393 mp.addMapListTo(mto);
1395 mp.setMapFromUnit(mlst.getFromRatio());
1396 mp.setMapToUnit(mlst.getToRatio());
1397 if (jmp.getTo() != null)
1399 MappingChoice mpc = new MappingChoice();
1401 && (parentseq != jmp.getTo() || parentseq
1402 .getDatasetSequence() != jmp.getTo()))
1404 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1410 SequenceI ps = null;
1411 if (parentseq != jmp.getTo()
1412 && parentseq.getDatasetSequence() != jmp.getTo())
1414 // chaining dbref rather than a handshaking one
1415 jmpid = seqHash(ps = jmp.getTo());
1419 jmpid = seqHash(ps = parentseq);
1421 mpc.setDseqFor(jmpid);
1422 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1424 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1425 seqRefIds.put(mpc.getDseqFor(), ps);
1429 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1432 mp.setMappingChoice(mpc);
1438 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1439 Vector userColours, JalviewModelSequence jms)
1442 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1443 boolean newucs = false;
1444 if (!userColours.contains(ucs))
1446 userColours.add(ucs);
1449 id = "ucs" + userColours.indexOf(ucs);
1452 // actually create the scheme's entry in the XML model
1453 java.awt.Color[] colours = ucs.getColours();
1454 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1455 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1457 for (int i = 0; i < colours.length; i++)
1459 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1460 col.setName(ResidueProperties.aa[i]);
1461 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1462 jbucs.addColour(col);
1464 if (ucs.getLowerCaseColours() != null)
1466 colours = ucs.getLowerCaseColours();
1467 for (int i = 0; i < colours.length; i++)
1469 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1470 col.setName(ResidueProperties.aa[i].toLowerCase());
1471 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1472 jbucs.addColour(col);
1477 uc.setUserColourScheme(jbucs);
1478 jms.addUserColours(uc);
1484 jalview.schemes.UserColourScheme GetUserColourScheme(
1485 JalviewModelSequence jms, String id)
1487 UserColours[] uc = jms.getUserColours();
1488 UserColours colours = null;
1490 for (int i = 0; i < uc.length; i++)
1492 if (uc[i].getId().equals(id))
1500 java.awt.Color[] newColours = new java.awt.Color[24];
1502 for (int i = 0; i < 24; i++)
1504 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1505 .getUserColourScheme().getColour(i).getRGB(), 16));
1508 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1511 if (colours.getUserColourScheme().getColourCount() > 24)
1513 newColours = new java.awt.Color[23];
1514 for (int i = 0; i < 23; i++)
1516 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1517 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1519 ucs.setLowerCaseColours(newColours);
1526 * contains last error message (if any) encountered by XML loader.
1528 String errorMessage = null;
1531 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1532 * exceptions are raised during project XML parsing
1534 public boolean attemptversion1parse = true;
1537 * Load a jalview project archive from a jar file
1540 * - HTTP URL or filename
1542 public AlignFrame LoadJalviewAlign(final String file)
1545 jalview.gui.AlignFrame af = null;
1549 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1550 // Workaround is to make sure caller implements the JarInputStreamProvider
1552 // so we can re-open the jar input stream for each entry.
1554 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1555 af = LoadJalviewAlign(jprovider);
1556 } catch (MalformedURLException e)
1558 errorMessage = "Invalid URL format for '" + file + "'";
1564 private jarInputStreamProvider createjarInputStreamProvider(
1565 final String file) throws MalformedURLException
1568 errorMessage = null;
1569 uniqueSetSuffix = null;
1571 viewportsAdded = null;
1572 frefedSequence = null;
1574 if (file.startsWith("http://"))
1576 url = new URL(file);
1578 final URL _url = url;
1579 return new jarInputStreamProvider()
1582 public JarInputStream getJarInputStream() throws IOException
1586 return new JarInputStream(_url.openStream());
1590 return new JarInputStream(new FileInputStream(file));
1594 public String getFilename()
1602 * Recover jalview session from a jalview project archive. Caller may
1603 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1604 * themselves. Any null fields will be initialised with default values,
1605 * non-null fields are left alone.
1610 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1612 errorMessage = null;
1613 if (uniqueSetSuffix == null)
1615 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1617 if (seqRefIds == null)
1619 seqRefIds = new Hashtable();
1621 if (viewportsAdded == null)
1623 viewportsAdded = new Hashtable();
1625 if (frefedSequence == null)
1627 frefedSequence = new Vector();
1630 jalview.gui.AlignFrame af = null;
1631 Hashtable gatherToThisFrame = new Hashtable();
1632 final String file = jprovider.getFilename();
1635 JarInputStream jin = null;
1636 JarEntry jarentry = null;
1641 jin = jprovider.getJarInputStream();
1642 for (int i = 0; i < entryCount; i++)
1644 jarentry = jin.getNextJarEntry();
1647 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1649 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1650 JalviewModel object = new JalviewModel();
1652 Unmarshaller unmar = new Unmarshaller(object);
1653 unmar.setValidation(false);
1654 object = (JalviewModel) unmar.unmarshal(in);
1655 if (true) // !skipViewport(object))
1657 af = LoadFromObject(object, file, true, jprovider);
1658 if (af.viewport.gatherViewsHere)
1660 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1665 else if (jarentry != null)
1667 // Some other file here.
1670 } while (jarentry != null);
1671 resolveFrefedSequences();
1672 } catch (java.io.FileNotFoundException ex)
1674 ex.printStackTrace();
1675 errorMessage = "Couldn't locate Jalview XML file : " + file;
1676 System.err.println("Exception whilst loading jalview XML file : "
1678 } catch (java.net.UnknownHostException ex)
1680 ex.printStackTrace();
1681 errorMessage = "Couldn't locate Jalview XML file : " + file;
1682 System.err.println("Exception whilst loading jalview XML file : "
1684 } catch (Exception ex)
1686 System.err.println("Parsing as Jalview Version 2 file failed.");
1687 ex.printStackTrace(System.err);
1688 if (attemptversion1parse)
1690 // Is Version 1 Jar file?
1693 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1694 } catch (Exception ex2)
1696 System.err.println("Exception whilst loading as jalviewXMLV1:");
1697 ex2.printStackTrace();
1701 if (Desktop.instance != null)
1703 Desktop.instance.stopLoading();
1707 System.out.println("Successfully loaded archive file");
1710 ex.printStackTrace();
1712 System.err.println("Exception whilst loading jalview XML file : "
1714 } catch (OutOfMemoryError e)
1716 // Don't use the OOM Window here
1717 errorMessage = "Out of memory loading jalview XML file";
1718 System.err.println("Out of memory whilst loading jalview XML file");
1719 e.printStackTrace();
1722 if (Desktop.instance != null)
1724 Desktop.instance.stopLoading();
1727 Enumeration en = gatherToThisFrame.elements();
1728 while (en.hasMoreElements())
1730 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1732 if (errorMessage != null)
1740 * check errorMessage for a valid error message and raise an error box in the
1741 * GUI or write the current errorMessage to stderr and then clear the error
1744 protected void reportErrors()
1746 reportErrors(false);
1749 protected void reportErrors(final boolean saving)
1751 if (errorMessage != null)
1753 final String finalErrorMessage = errorMessage;
1756 javax.swing.SwingUtilities.invokeLater(new Runnable()
1760 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1761 finalErrorMessage, "Error "
1762 + (saving ? "saving" : "loading")
1763 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1769 System.err.println("Problem loading Jalview file: " + errorMessage);
1772 errorMessage = null;
1775 Hashtable alreadyLoadedPDB;
1778 * when set, local views will be updated from view stored in JalviewXML
1779 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1780 * sync if this is set to true.
1782 private boolean updateLocalViews = false;
1784 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1786 if (alreadyLoadedPDB == null)
1787 alreadyLoadedPDB = new Hashtable();
1789 if (alreadyLoadedPDB.containsKey(pdbId))
1790 return alreadyLoadedPDB.get(pdbId).toString();
1794 JarInputStream jin = jprovider.getJarInputStream();
1796 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1797 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1798 * FileInputStream(jprovider)); }
1801 JarEntry entry = null;
1804 entry = jin.getNextJarEntry();
1805 } while (entry != null && !entry.getName().equals(pdbId));
1808 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1809 File outFile = File.createTempFile("jalview_pdb", ".txt");
1810 outFile.deleteOnExit();
1811 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1814 while ((data = in.readLine()) != null)
1821 } catch (Exception foo)
1826 String t=outFile.toURI().getPath().substring(1);
1827 alreadyLoadedPDB.put(pdbId, t);
1832 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1834 } catch (Exception ex)
1836 ex.printStackTrace();
1842 private class JvAnnotRow
1844 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1851 * persisted version of annotation row from which to take vis properties
1853 public jalview.datamodel.AlignmentAnnotation template;
1856 * original position of the annotation row in the alignment
1862 * Load alignment frame from jalview XML DOM object
1867 * filename source string
1868 * @param loadTreesAndStructures
1869 * when false only create Viewport
1871 * data source provider
1872 * @return alignment frame created from view stored in DOM
1874 AlignFrame LoadFromObject(JalviewModel object, String file,
1875 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
1877 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1878 Sequence[] vamsasSeq = vamsasSet.getSequence();
1880 JalviewModelSequence jms = object.getJalviewModelSequence();
1882 Viewport view = jms.getViewport(0);
1883 // ////////////////////////////////
1886 Vector hiddenSeqs = null;
1887 jalview.datamodel.Sequence jseq;
1889 ArrayList tmpseqs = new ArrayList();
1891 boolean multipleView = false;
1893 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1894 int vi = 0; // counter in vamsasSeq array
1895 for (int i = 0; i < JSEQ.length; i++)
1897 String seqId = JSEQ[i].getId();
1899 if (seqRefIds.get(seqId) != null)
1901 tmpseqs.add((jalview.datamodel.Sequence) seqRefIds.get(seqId));
1902 multipleView = true;
1906 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
1907 vamsasSeq[vi].getSequence());
1908 jseq.setDescription(vamsasSeq[vi].getDescription());
1909 jseq.setStart(JSEQ[i].getStart());
1910 jseq.setEnd(JSEQ[i].getEnd());
1911 jseq.setVamsasId(uniqueSetSuffix + seqId);
1912 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
1917 if (JSEQ[i].getHidden())
1919 if (hiddenSeqs == null)
1921 hiddenSeqs = new Vector();
1924 hiddenSeqs.addElement((jalview.datamodel.Sequence) seqRefIds
1931 // Create the alignment object from the sequence set
1932 // ///////////////////////////////
1933 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
1936 tmpseqs.toArray(orderedSeqs);
1938 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
1941 // / Add the alignment properties
1942 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
1944 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
1945 al.setProperty(ssp.getKey(), ssp.getValue());
1949 // SequenceFeatures are added to the DatasetSequence,
1950 // so we must create or recover the dataset before loading features
1951 // ///////////////////////////////
1952 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
1954 // older jalview projects do not have a dataset id.
1955 al.setDataset(null);
1959 recoverDatasetFor(vamsasSet, al);
1961 // ///////////////////////////////
1963 Hashtable pdbloaded = new Hashtable();
1966 // load sequence features, database references and any associated PDB
1967 // structures for the alignment
1968 for (int i = 0; i < vamsasSeq.length; i++)
1970 if (JSEQ[i].getFeaturesCount() > 0)
1972 Features[] features = JSEQ[i].getFeatures();
1973 for (int f = 0; f < features.length; f++)
1975 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
1976 features[f].getType(), features[f].getDescription(),
1977 features[f].getStatus(), features[f].getBegin(),
1978 features[f].getEnd(), features[f].getFeatureGroup());
1980 sf.setScore(features[f].getScore());
1981 for (int od = 0; od < features[f].getOtherDataCount(); od++)
1983 OtherData keyValue = features[f].getOtherData(od);
1984 if (keyValue.getKey().startsWith("LINK"))
1986 sf.addLink(keyValue.getValue());
1990 sf.setValue(keyValue.getKey(), keyValue.getValue());
1995 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
1998 if (vamsasSeq[i].getDBRefCount() > 0)
2000 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2002 if (JSEQ[i].getPdbidsCount() > 0)
2004 Pdbids[] ids = JSEQ[i].getPdbids();
2005 for (int p = 0; p < ids.length; p++)
2007 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2008 entry.setId(ids[p].getId());
2009 entry.setType(ids[p].getType());
2010 if (ids[p].getFile() != null)
2012 if (!pdbloaded.containsKey(ids[p].getFile()))
2014 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2018 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2022 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2026 } // end !multipleview
2028 // ///////////////////////////////
2029 // LOAD SEQUENCE MAPPINGS
2031 if (vamsasSet.getAlcodonFrameCount() > 0)
2033 // TODO Potentially this should only be done once for all views of an
2035 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2036 for (int i = 0; i < alc.length; i++)
2038 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2039 alc[i].getAlcodonCount());
2040 if (alc[i].getAlcodonCount() > 0)
2042 Alcodon[] alcods = alc[i].getAlcodon();
2043 for (int p = 0; p < cf.codons.length; p++)
2045 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2046 && alcods[p].hasPos3())
2048 // translated codons require three valid positions
2049 cf.codons[p] = new int[3];
2050 cf.codons[p][0] = (int) alcods[p].getPos1();
2051 cf.codons[p][1] = (int) alcods[p].getPos2();
2052 cf.codons[p][2] = (int) alcods[p].getPos3();
2056 cf.codons[p] = null;
2060 if (alc[i].getAlcodMapCount() > 0)
2062 AlcodMap[] maps = alc[i].getAlcodMap();
2063 for (int m = 0; m < maps.length; m++)
2065 SequenceI dnaseq = (SequenceI) seqRefIds
2066 .get(maps[m].getDnasq());
2068 jalview.datamodel.Mapping mapping = null;
2069 // attach to dna sequence reference.
2070 if (maps[m].getMapping() != null)
2072 mapping = addMapping(maps[m].getMapping());
2076 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2081 frefedSequence.add(new Object[]
2082 { maps[m].getDnasq(), cf, mapping });
2086 al.addCodonFrame(cf);
2091 // ////////////////////////////////
2093 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2095 * store any annotations which forward reference a group's ID
2097 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2099 if (vamsasSet.getAnnotationCount() > 0)
2101 Annotation[] an = vamsasSet.getAnnotation();
2103 for (int i = 0; i < an.length; i++)
2106 * test if annotation is automatically calculated for this view only
2108 boolean autoForView = false;
2109 if (an[i].getLabel().equals("Quality")
2110 || an[i].getLabel().equals("Conservation")
2111 || an[i].getLabel().equals("Consensus"))
2113 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2115 if (!an[i].hasAutoCalculated())
2117 an[i].setAutoCalculated(true);
2121 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2123 // remove ID - we don't recover annotation from other views for
2124 // view-specific annotation
2128 // set visiblity for other annotation in this view
2129 if (an[i].getId() != null
2130 && annotationIds.containsKey(an[i].getId()))
2132 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2133 .get(an[i].getId());
2134 // in principle Visible should always be true for annotation displayed
2135 // in multiple views
2136 if (an[i].hasVisible())
2137 jda.visible = an[i].getVisible();
2139 al.addAnnotation(jda);
2143 // Construct new annotation from model.
2144 AnnotationElement[] ae = an[i].getAnnotationElement();
2145 jalview.datamodel.Annotation[] anot = null;
2147 if (!an[i].getScoreOnly())
2149 anot = new jalview.datamodel.Annotation[al.getWidth()];
2150 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2152 if (ae[aa].getPosition() >= anot.length)
2155 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2157 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2158 (ae[aa].getSecondaryStructure() == null || ae[aa]
2159 .getSecondaryStructure().length() == 0) ? ' '
2160 : ae[aa].getSecondaryStructure().charAt(0),
2164 // JBPNote: Consider verifying dataflow for IO of secondary
2165 // structure annotation read from Stockholm files
2166 // this was added to try to ensure that
2167 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2169 // anot[ae[aa].getPosition()].displayCharacter = "";
2171 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2172 ae[aa].getColour());
2175 jalview.datamodel.AlignmentAnnotation jaa = null;
2177 if (an[i].getGraph())
2179 float llim = 0, hlim = 0;
2180 // if (autoForView || an[i].isAutoCalculated()) {
2183 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2184 an[i].getDescription(), anot, llim, hlim,
2185 an[i].getGraphType());
2187 jaa.graphGroup = an[i].getGraphGroup();
2189 if (an[i].getThresholdLine() != null)
2191 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2192 .getThresholdLine().getValue(), an[i]
2193 .getThresholdLine().getLabel(), new java.awt.Color(
2194 an[i].getThresholdLine().getColour())));
2197 if (autoForView || an[i].isAutoCalculated())
2199 // Hardwire the symbol display line to ensure that labels for
2200 // histograms are displayed
2206 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2207 an[i].getDescription(), anot);
2211 // register new annotation
2212 if (an[i].getId() != null)
2214 annotationIds.put(an[i].getId(), jaa);
2215 jaa.annotationId = an[i].getId();
2217 // recover sequence association
2218 if (an[i].getSequenceRef() != null)
2220 if (al.findName(an[i].getSequenceRef()) != null)
2222 jaa.createSequenceMapping(
2223 al.findName(an[i].getSequenceRef()), 1, true);
2224 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
2229 // and make a note of any group association
2230 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2232 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2233 .get(an[i].getGroupRef());
2236 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2237 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2242 if (an[i].hasScore())
2244 jaa.setScore(an[i].getScore());
2246 if (an[i].hasVisible())
2247 jaa.visible = an[i].getVisible();
2249 if (an[i].hasCentreColLabels())
2250 jaa.centreColLabels = an[i].getCentreColLabels();
2252 if (an[i].hasScaleColLabels())
2254 jaa.scaleColLabel = an[i].getScaleColLabels();
2256 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2258 // newer files have an 'autoCalculated' flag and store calculation
2259 // state in viewport properties
2260 jaa.autoCalculated = true; // means annotation will be marked for
2261 // update at end of load.
2263 if (an[i].hasGraphHeight())
2265 jaa.graphHeight = an[i].getGraphHeight();
2267 if (jaa.autoCalculated)
2269 autoAlan.add(new JvAnnotRow(i, jaa));
2272 // if (!autoForView)
2274 // add autocalculated group annotation and any user created annotation
2276 al.addAnnotation(jaa);
2281 // ///////////////////////
2283 // Create alignment markup and styles for this view
2284 if (jms.getJGroupCount() > 0)
2286 JGroup[] groups = jms.getJGroup();
2288 for (int i = 0; i < groups.length; i++)
2290 ColourSchemeI cs = null;
2292 if (groups[i].getColour() != null)
2294 if (groups[i].getColour().startsWith("ucs"))
2296 cs = GetUserColourScheme(jms, groups[i].getColour());
2300 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2305 cs.setThreshold(groups[i].getPidThreshold(), true);
2309 Vector seqs = new Vector();
2311 for (int s = 0; s < groups[i].getSeqCount(); s++)
2313 String seqId = groups[i].getSeq(s) + "";
2314 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2319 seqs.addElement(ts);
2323 if (seqs.size() < 1)
2328 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2329 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2330 groups[i].getDisplayText(), groups[i].getColourText(),
2331 groups[i].getStart(), groups[i].getEnd());
2333 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2335 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2336 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2337 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2338 .isShowUnconserved() : false);
2339 sg.thresholdTextColour = groups[i].getTextColThreshold();
2340 if (groups[i].hasShowConsensusHistogram())
2342 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2345 if (groups[i].hasShowSequenceLogo())
2347 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2349 if (groups[i].hasIgnoreGapsinConsensus())
2351 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2353 if (groups[i].getConsThreshold() != 0)
2355 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2356 "All", ResidueProperties.propHash, 3,
2357 sg.getSequences(null), 0, sg.getWidth() - 1);
2359 c.verdict(false, 25);
2360 sg.cs.setConservation(c);
2363 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2365 // re-instate unique group/annotation row reference
2366 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2367 .get(groups[i].getId());
2370 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2373 if (jaa.autoCalculated)
2375 // match up and try to set group autocalc alignment row for this
2377 if (jaa.label.startsWith("Consensus for "))
2379 sg.setConsensus(jaa);
2381 // match up and try to set group autocalc alignment row for this
2383 if (jaa.label.startsWith("Conservation for "))
2385 sg.setConservationRow(jaa);
2396 // ///////////////////////////////
2399 // If we just load in the same jar file again, the sequenceSetId
2400 // will be the same, and we end up with multiple references
2401 // to the same sequenceSet. We must modify this id on load
2402 // so that each load of the file gives a unique id
2403 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2404 String viewId = (view.getId() == null ? null : view.getId()
2406 AlignFrame af = null;
2407 AlignViewport av = null;
2408 // now check to see if we really need to create a new viewport.
2409 if (multipleView && viewportsAdded.size() == 0)
2411 // We recovered an alignment for which a viewport already exists.
2412 // TODO: fix up any settings necessary for overlaying stored state onto
2413 // state recovered from another document. (may not be necessary).
2414 // we may need a binding from a viewport in memory to one recovered from
2416 // and then recover its containing af to allow the settings to be applied.
2417 // TODO: fix for vamsas demo
2419 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2421 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2422 if (seqsetobj != null)
2424 if (seqsetobj instanceof String)
2426 uniqueSeqSetId = (String) seqsetobj;
2428 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2434 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2439 AlignmentPanel ap = null;
2440 boolean isnewview = true;
2443 // Check to see if this alignment already has a view id == viewId
2444 jalview.gui.AlignmentPanel views[] = Desktop
2445 .getAlignmentPanels(uniqueSeqSetId);
2446 if (views != null && views.length > 0)
2448 for (int v = 0; v < views.length; v++)
2450 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2452 // recover the existing alignpanel, alignframe, viewport
2453 af = views[v].alignFrame;
2456 // TODO: could even skip resetting view settings if we don't want to
2457 // change the local settings from other jalview processes
2466 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2467 uniqueSeqSetId, viewId, autoAlan);
2472 // /////////////////////////////////////
2473 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2477 for (int t = 0; t < jms.getTreeCount(); t++)
2480 Tree tree = jms.getTree(t);
2482 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2485 tp = af.ShowNewickTree(
2486 new jalview.io.NewickFile(tree.getNewick()),
2487 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2488 tree.getXpos(), tree.getYpos());
2489 if (tree.getId() != null)
2491 // perhaps bind the tree id to something ?
2496 // update local tree attributes ?
2497 // TODO: should check if tp has been manipulated by user - if so its
2498 // settings shouldn't be modified
2499 tp.setTitle(tree.getTitle());
2500 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2501 .getWidth(), tree.getHeight()));
2502 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2505 tp.treeCanvas.av = av; // af.viewport;
2506 tp.treeCanvas.ap = ap; // af.alignPanel;
2511 warn("There was a problem recovering stored Newick tree: \n"
2512 + tree.getNewick());
2516 tp.fitToWindow.setState(tree.getFitToWindow());
2517 tp.fitToWindow_actionPerformed(null);
2519 if (tree.getFontName() != null)
2521 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2522 .getFontStyle(), tree.getFontSize()));
2526 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2527 .getFontStyle(), tree.getFontSize()));
2530 tp.showPlaceholders(tree.getMarkUnlinked());
2531 tp.showBootstrap(tree.getShowBootstrap());
2532 tp.showDistances(tree.getShowDistances());
2534 tp.treeCanvas.threshold = tree.getThreshold();
2536 if (tree.getCurrentTree())
2538 af.viewport.setCurrentTree(tp.getTree());
2542 } catch (Exception ex)
2544 ex.printStackTrace();
2548 // //LOAD STRUCTURES
2549 if (loadTreesAndStructures)
2551 // run through all PDB ids on the alignment, and collect mappings between
2552 // jmol view ids and all sequences referring to it
2553 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2555 for (int i = 0; i < JSEQ.length; i++)
2557 if (JSEQ[i].getPdbidsCount() > 0)
2559 Pdbids[] ids = JSEQ[i].getPdbids();
2560 for (int p = 0; p < ids.length; p++)
2562 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2564 // check to see if we haven't already created this structure view
2565 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2566 : ids[p].getStructureState(s).getViewId()
2568 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2569 // Originally : ids[p].getFile()
2570 // : TODO: verify external PDB file recovery still works in normal
2571 // jalview project load
2572 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2573 jpdb.setId(ids[p].getId());
2575 int x = ids[p].getStructureState(s).getXpos();
2576 int y = ids[p].getStructureState(s).getYpos();
2577 int width = ids[p].getStructureState(s).getWidth();
2578 int height = ids[p].getStructureState(s).getHeight();
2580 // Probably don't need to do this anymore...
2581 // Desktop.desktop.getComponentAt(x, y);
2582 // TODO: NOW: check that this recovers the PDB file correctly.
2583 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2584 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2585 .get(JSEQ[i].getId() + "");
2586 if (sviewid == null)
2588 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2591 if (!jmolViewIds.containsKey(sviewid))
2593 jmolViewIds.put(sviewid, new Object[]
2595 { x, y, width, height }, "",
2596 new Hashtable<String, Object[]>(), new boolean[]
2597 { false, false, true } });
2598 // Legacy pre-2.7 conversion JAL-823 :
2599 // do not assume any view has to be linked for colour by
2603 // assemble String[] { pdb files }, String[] { id for each
2604 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2605 // seqs_file 2}, boolean[] {
2606 // linkAlignPanel,superposeWithAlignpanel}} from hash
2607 Object[] jmoldat = (Object[]) jmolViewIds.get(sviewid);
2608 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2609 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2610 s).getAlignwithAlignPanel() : false;
2611 // never colour by linked panel if not specified
2612 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2613 .hasColourwithAlignPanel() ? ids[p]
2614 .getStructureState(s).getColourwithAlignPanel()
2616 // default for pre-2.7 projects is that Jmol colouring is enabled
2617 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2618 .hasColourByJmol() ? ids[p].getStructureState(s)
2619 .getColourByJmol() : true;
2621 if (((String) jmoldat[1]).length() < ids[p]
2622 .getStructureState(s).getContent().length())
2625 jmoldat[1] = ids[p].getStructureState(s).getContent();
2628 if (ids[p].getFile() != null)
2630 File mapkey=new File(ids[p].getFile());
2631 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2633 if (seqstrmaps == null)
2635 ((Hashtable) jmoldat[2]).put(
2637 seqstrmaps = new Object[]
2638 { pdbFile, ids[p].getId(), new Vector(),
2641 if (!((Vector) seqstrmaps[2]).contains(seq))
2643 ((Vector) seqstrmaps[2]).addElement(seq);
2644 // ((Vector)seqstrmaps[3]).addElement(n) :
2645 // in principle, chains
2646 // should be stored here : do we need to
2647 // TODO: store and recover seq/pdb_id :
2653 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");
2662 // Instantiate the associated Jmol views
2663 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2665 String sviewid = entry.getKey();
2666 Object[] svattrib = entry.getValue();
2667 int[] geom = (int[]) svattrib[0];
2668 String state = (String) svattrib[1];
2669 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2670 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2671 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2672 // collate the pdbfile -> sequence mappings from this view
2673 Vector<String> pdbfilenames = new Vector<String>();
2674 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2675 Vector<String> pdbids = new Vector<String>();
2677 // Search to see if we've already created this Jmol view
2678 AppJmol comp = null;
2679 JInternalFrame[] frames = null;
2684 frames = Desktop.desktop.getAllFrames();
2685 } catch (ArrayIndexOutOfBoundsException e)
2687 // occasional No such child exceptions are thrown here...
2692 } catch (Exception f)
2697 } while (frames == null);
2698 // search for any Jmol windows already open from other
2699 // alignment views that exactly match the stored structure state
2700 for (int f = 0; comp == null && f < frames.length; f++)
2702 if (frames[f] instanceof AppJmol)
2705 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2707 // post jalview 2.4 schema includes structure view id
2708 comp = (AppJmol) frames[f];
2710 else if (frames[f].getX() == x && frames[f].getY() == y
2711 && frames[f].getHeight() == height
2712 && frames[f].getWidth() == width)
2714 comp = (AppJmol) frames[f];
2721 // create a new Jmol window.
2722 // First parse the Jmol state to translate filenames loaded into the
2723 // view, and record the order in which files are shown in the Jmol
2724 // view, so we can add the sequence mappings in same order.
2725 StringBuffer newFileLoc = null;
2726 int cp = 0, ncp, ecp;
2727 while ((ncp = state.indexOf("load ", cp)) > -1)
2729 if (newFileLoc == null)
2731 newFileLoc = new StringBuffer();
2734 // look for next filename in load statement
2735 newFileLoc.append(state.substring(cp,
2736 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2737 String oldfilenam = state.substring(ncp,
2738 ecp = state.indexOf("\"", ncp));
2739 // recover the new mapping data for this old filename
2740 // have to normalize filename - since Jmol and jalview do filename
2741 // translation differently.
2742 Object[] filedat = oldFiles.get(new File(oldfilenam));
2743 newFileLoc.append(((String) filedat[0]));
2744 pdbfilenames.addElement((String) filedat[0]);
2745 pdbids.addElement((String) filedat[1]);
2746 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2747 .toArray(new SequenceI[0]));
2748 newFileLoc.append("\"");
2749 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2750 // look for next file statement.
2751 } while ((ncp=state.indexOf("/*file*/",cp))>-1);
2755 // just append rest of state
2756 newFileLoc.append(state.substring(cp));
2761 .print("Ignoring incomplete Jmol state for PDB ids: ");
2762 newFileLoc = new StringBuffer(state);
2763 newFileLoc.append("; load append ");
2764 for (File id : oldFiles.keySet())
2766 // add this and any other pdb files that should be present in
2768 Object[] filedat = oldFiles.get(id);
2770 newFileLoc.append(((String) filedat[0]));
2771 pdbfilenames.addElement((String) filedat[0]);
2772 pdbids.addElement((String) filedat[1]);
2773 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2774 .toArray(new SequenceI[0]));
2775 newFileLoc.append(" \"");
2776 newFileLoc.append((String) filedat[0]);
2777 newFileLoc.append("\"");
2780 newFileLoc.append(";");
2783 if (newFileLoc != null)
2785 int histbug = newFileLoc.indexOf("history = ");
2787 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2789 String val = (diff == -1) ? null : newFileLoc.substring(
2791 if (val != null && val.length() >= 4)
2793 if (val.contains("e"))
2795 if (val.trim().equals("true"))
2803 newFileLoc.replace(histbug, diff, val);
2806 // TODO: assemble String[] { pdb files }, String[] { id for each
2807 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2808 // seqs_file 2}} from hash
2809 final String[] pdbf = (String[]) pdbfilenames
2810 .toArray(new String[pdbfilenames.size()]), id = (String[]) pdbids
2811 .toArray(new String[pdbids.size()]);
2812 final SequenceI[][] sq = (SequenceI[][]) seqmaps
2813 .toArray(new SequenceI[seqmaps.size()][]);
2814 final String fileloc = newFileLoc.toString(), vid = sviewid;
2815 final AlignFrame alf = af;
2816 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2820 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2824 AppJmol sview = null;
2827 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2828 useinJmolsuperpos, usetoColourbyseq,
2829 jmolColouring, fileloc, rect, vid);
2830 } catch (OutOfMemoryError ex)
2832 new OOMWarning("restoring structure view for PDB id "
2833 + id, (OutOfMemoryError) ex.getCause());
2834 if (sview != null && sview.isVisible())
2836 sview.closeViewer();
2837 sview.setVisible(false);
2843 } catch (InvocationTargetException ex)
2845 warn("Unexpected error when opening Jmol view.", ex);
2847 } catch (InterruptedException e)
2849 // e.printStackTrace();
2855 // if (comp != null)
2857 // NOTE: if the jalview project is part of a shared session then
2858 // view synchronization should/could be done here.
2860 // add mapping for sequences in this view to an already open Jmol
2862 for (File id : oldFiles.keySet())
2864 // add this and any other pdb files that should be present in the
2866 Object[] filedat = oldFiles.get(id);
2867 String pdbFile = (String) filedat[0];
2868 SequenceI[] seq = (SequenceI[]) ((Vector<SequenceI>) filedat[2])
2869 .toArray(new SequenceI[0]);
2870 ((AppJmol) comp).jmb.ssm.setMapping(seq, null, pdbFile,
2871 jalview.io.AppletFormatAdapter.FILE);
2872 ((AppJmol) comp).jmb.addSequenceForStructFile(pdbFile, seq);
2874 // and add the AlignmentPanel's reference to the Jmol view
2875 ((AppJmol) comp).addAlignmentPanel(ap);
2876 if (useinJmolsuperpos)
2878 ((AppJmol) comp).useAlignmentPanelForSuperposition(ap);
2882 ((AppJmol) comp).excludeAlignmentPanelForSuperposition(ap);
2884 if (usetoColourbyseq)
2886 ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap,
2891 ((AppJmol) comp).excludeAlignmentPanelForColourbyseq(ap);
2897 // and finally return.
2901 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
2902 Alignment al, JalviewModelSequence jms, Viewport view,
2903 String uniqueSeqSetId, String viewId,
2904 ArrayList<JvAnnotRow> autoAlan)
2906 AlignFrame af = null;
2907 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
2908 uniqueSeqSetId, viewId);
2910 af.setFileName(file, "Jalview");
2912 for (int i = 0; i < JSEQ.length; i++)
2914 af.viewport.setSequenceColour(af.viewport.alignment.getSequenceAt(i),
2915 new java.awt.Color(JSEQ[i].getColour()));
2918 af.viewport.gatherViewsHere = view.getGatheredViews();
2920 if (view.getSequenceSetId() != null)
2922 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
2923 .get(uniqueSeqSetId);
2925 af.viewport.sequenceSetID = uniqueSeqSetId;
2928 // propagate shared settings to this new view
2929 af.viewport.historyList = av.historyList;
2930 af.viewport.redoList = av.redoList;
2934 viewportsAdded.put(uniqueSeqSetId, af.viewport);
2936 // TODO: check if this method can be called repeatedly without
2937 // side-effects if alignpanel already registered.
2938 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
2940 // apply Hidden regions to view.
2941 if (hiddenSeqs != null)
2943 for (int s = 0; s < JSEQ.length; s++)
2945 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
2947 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
2950 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
2952 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
2955 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
2958 for (int s = 0; s < hiddenSeqs.size(); s++)
2960 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
2963 af.viewport.hideSequence(hseqs);
2966 // recover view properties and display parameters
2967 if (view.getViewName() != null)
2969 af.viewport.viewName = view.getViewName();
2970 af.setInitialTabVisible();
2972 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
2975 af.viewport.setShowAnnotation(view.getShowAnnotation());
2976 af.viewport.setAbovePIDThreshold(view.getPidSelected());
2978 af.viewport.setColourText(view.getShowColourText());
2980 af.viewport.setConservationSelected(view.getConservationSelected());
2981 af.viewport.setShowJVSuffix(view.getShowFullId());
2982 af.viewport.rightAlignIds = view.getRightAlignIds();
2983 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
2984 .getFontStyle(), view.getFontSize()));
2985 af.alignPanel.fontChanged();
2986 af.viewport.setRenderGaps(view.getRenderGaps());
2987 af.viewport.setWrapAlignment(view.getWrapAlignment());
2988 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
2989 af.viewport.setShowAnnotation(view.getShowAnnotation());
2990 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
2992 af.viewport.setShowBoxes(view.getShowBoxes());
2994 af.viewport.setShowText(view.getShowText());
2996 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
2997 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
2998 af.viewport.thresholdTextColour = view.getTextColThreshold();
2999 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3000 .isShowUnconserved() : false);
3001 af.viewport.setStartRes(view.getStartRes());
3002 af.viewport.setStartSeq(view.getStartSeq());
3004 ColourSchemeI cs = null;
3005 // apply colourschemes
3006 if (view.getBgColour() != null)
3008 if (view.getBgColour().startsWith("ucs"))
3010 cs = GetUserColourScheme(jms, view.getBgColour());
3012 else if (view.getBgColour().startsWith("Annotation"))
3014 // int find annotation
3015 if (af.viewport.alignment.getAlignmentAnnotation() != null)
3017 for (int i = 0; i < af.viewport.alignment
3018 .getAlignmentAnnotation().length; i++)
3020 if (af.viewport.alignment.getAlignmentAnnotation()[i].label
3021 .equals(view.getAnnotationColours().getAnnotation()))
3023 if (af.viewport.alignment.getAlignmentAnnotation()[i]
3024 .getThreshold() == null)
3026 af.viewport.alignment.getAlignmentAnnotation()[i]
3027 .setThreshold(new jalview.datamodel.GraphLine(view
3028 .getAnnotationColours().getThreshold(),
3029 "Threshold", java.awt.Color.black)
3034 if (view.getAnnotationColours().getColourScheme()
3037 cs = new AnnotationColourGradient(
3038 af.viewport.alignment.getAlignmentAnnotation()[i],
3039 new java.awt.Color(view.getAnnotationColours()
3040 .getMinColour()), new java.awt.Color(view
3041 .getAnnotationColours().getMaxColour()),
3042 view.getAnnotationColours().getAboveThreshold());
3044 else if (view.getAnnotationColours().getColourScheme()
3047 cs = new AnnotationColourGradient(
3048 af.viewport.alignment.getAlignmentAnnotation()[i],
3049 GetUserColourScheme(jms, view
3050 .getAnnotationColours().getColourScheme()),
3051 view.getAnnotationColours().getAboveThreshold());
3055 cs = new AnnotationColourGradient(
3056 af.viewport.alignment.getAlignmentAnnotation()[i],
3057 ColourSchemeProperty.getColour(al, view
3058 .getAnnotationColours().getColourScheme()),
3059 view.getAnnotationColours().getAboveThreshold());
3062 // Also use these settings for all the groups
3063 if (al.getGroups() != null)
3065 for (int g = 0; g < al.getGroups().size(); g++)
3067 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
3068 .getGroups().elementAt(g);
3077 * (view.getAnnotationColours().getColourScheme().equals("None"
3078 * )) { sg.cs = new AnnotationColourGradient(
3079 * af.viewport.alignment.getAlignmentAnnotation()[i], new
3080 * java.awt.Color(view.getAnnotationColours().
3081 * getMinColour()), new
3082 * java.awt.Color(view.getAnnotationColours().
3084 * view.getAnnotationColours().getAboveThreshold()); } else
3087 sg.cs = new AnnotationColourGradient(
3088 af.viewport.alignment.getAlignmentAnnotation()[i],
3089 sg.cs, view.getAnnotationColours()
3090 .getAboveThreshold());
3104 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3109 cs.setThreshold(view.getPidThreshold(), true);
3110 cs.setConsensus(af.viewport.hconsensus);
3114 af.viewport.setGlobalColourScheme(cs);
3115 af.viewport.setColourAppliesToAllGroups(false);
3117 if (view.getConservationSelected() && cs != null)
3119 cs.setConservationInc(view.getConsThreshold());
3122 af.changeColour(cs);
3124 af.viewport.setColourAppliesToAllGroups(true);
3126 if (view.getShowSequenceFeatures())
3128 af.viewport.showSequenceFeatures = true;
3130 if (view.hasCentreColumnLabels())
3132 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3134 if (view.hasIgnoreGapsinConsensus())
3136 af.viewport.ignoreGapsInConsensusCalculation = view
3137 .getIgnoreGapsinConsensus();
3139 if (view.hasFollowHighlight())
3141 af.viewport.followHighlight = view.getFollowHighlight();
3143 if (view.hasFollowSelection())
3145 af.viewport.followSelection = view.getFollowSelection();
3147 if (view.hasShowConsensusHistogram())
3149 af.viewport.setShowConsensusHistogram(view
3150 .getShowConsensusHistogram());
3154 af.viewport.setShowConsensusHistogram(true);
3156 if (view.hasShowSequenceLogo())
3158 af.viewport.showSequenceLogo = view.getShowSequenceLogo();
3162 af.viewport.showSequenceLogo = false;
3164 if (view.hasShowDbRefTooltip())
3166 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3168 if (view.hasShowNPfeatureTooltip())
3170 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3172 if (view.hasShowGroupConsensus())
3174 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3178 af.viewport.setShowGroupConsensus(false);
3180 if (view.hasShowGroupConservation())
3182 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3186 af.viewport.setShowGroupConservation(false);
3189 // recover featre settings
3190 if (jms.getFeatureSettings() != null)
3192 af.viewport.featuresDisplayed = new Hashtable();
3193 String[] renderOrder = new String[jms.getFeatureSettings()
3194 .getSettingCount()];
3195 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3197 Setting setting = jms.getFeatureSettings().getSetting(fs);
3198 if (setting.hasMincolour())
3200 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3201 new java.awt.Color(setting.getMincolour()),
3202 new java.awt.Color(setting.getColour()),
3203 setting.getMin(), setting.getMax()) : new GraduatedColor(
3204 new java.awt.Color(setting.getMincolour()),
3205 new java.awt.Color(setting.getColour()), 0, 1);
3206 if (setting.hasThreshold())
3208 gc.setThresh(setting.getThreshold());
3209 gc.setThreshType(setting.getThreshstate());
3211 gc.setAutoScaled(true); // default
3212 if (setting.hasAutoScale())
3214 gc.setAutoScaled(setting.getAutoScale());
3216 if (setting.hasColourByLabel())
3218 gc.setColourByLabel(setting.getColourByLabel());
3220 // and put in the feature colour table.
3221 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3222 setting.getType(), gc);
3226 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3228 new java.awt.Color(setting.getColour()));
3230 renderOrder[fs] = setting.getType();
3231 if (setting.hasOrder())
3232 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3233 setting.getType(), setting.getOrder());
3235 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3237 fs / jms.getFeatureSettings().getSettingCount());
3238 if (setting.getDisplay())
3240 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3241 setting.getColour()));
3244 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3246 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3247 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3249 Group grp = jms.getFeatureSettings().getGroup(gs);
3250 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3254 if (view.getHiddenColumnsCount() > 0)
3256 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3258 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3259 .getHiddenColumns(c).getEnd() // +1
3264 af.setMenusFromViewport(af.viewport);
3265 // TODO: we don't need to do this if the viewport is aready visible.
3266 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3268 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3269 reorderAutoannotation(af, al, autoAlan);
3273 private void reorderAutoannotation(AlignFrame af, Alignment al,
3274 ArrayList<JvAnnotRow> autoAlan)
3276 // copy over visualization settings for autocalculated annotation in the
3278 if (al.getAlignmentAnnotation() != null)
3281 * Kludge for magic autoannotation names (see JAL-811)
3283 String[] magicNames = new String[]
3284 { "Consensus", "Quality", "Conservation" };
3285 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3286 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3287 for (String nm : magicNames)
3289 visan.put(nm, nullAnnot);
3291 for (JvAnnotRow auan : autoAlan)
3293 visan.put(auan.template.label, auan);
3295 int hSize = al.getAlignmentAnnotation().length;
3296 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3297 for (int h = 0; h < hSize; h++)
3299 jalview.datamodel.AlignmentAnnotation jalan = al
3300 .getAlignmentAnnotation()[h];
3301 if (jalan.autoCalculated)
3303 JvAnnotRow valan = visan.get(jalan.label);
3306 // delete the auto calculated row from the alignment
3307 al.deleteAnnotation(al.getAlignmentAnnotation()[h], false);
3310 if (valan != nullAnnot)
3312 if (jalan != valan.template)
3314 // newly created autoannotation row instance
3315 // so keep a reference to the visible annotation row
3316 // and copy over all relevant attributes
3317 if (valan.template.graphHeight >= 0)
3320 jalan.graphHeight = valan.template.graphHeight;
3322 jalan.visible = valan.template.visible;
3324 reorder.add(new JvAnnotRow(valan.order, jalan));
3329 int s = 0, srt[] = new int[reorder.size()];
3330 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3331 for (JvAnnotRow jvar : reorder)
3334 srt[s++] = jvar.order;
3337 jalview.util.QuickSort.sort(srt, rws);
3338 // and re-insert the annotation at its correct position
3339 for (JvAnnotRow jvar : rws)
3341 al.addAnnotation(jvar.template, jvar.order);
3343 af.alignPanel.adjustAnnotationHeight();
3347 Hashtable skipList = null;
3350 * TODO remove this method
3353 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3354 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3355 * throw new Error("Implementation Error. No skipList defined for this
3356 * Jalview2XML instance."); } return (AlignFrame)
3357 * skipList.get(view.getSequenceSetId()); }
3361 * Check if the Jalview view contained in object should be skipped or not.
3364 * @return true if view's sequenceSetId is a key in skipList
3366 private boolean skipViewport(JalviewModel object)
3368 if (skipList == null)
3373 if (skipList.containsKey(id = object.getJalviewModelSequence()
3374 .getViewport()[0].getSequenceSetId()))
3376 if (Cache.log != null && Cache.log.isDebugEnabled())
3378 Cache.log.debug("Skipping seuqence set id " + id);
3385 public void AddToSkipList(AlignFrame af)
3387 if (skipList == null)
3389 skipList = new Hashtable();
3391 skipList.put(af.getViewport().getSequenceSetId(), af);
3394 public void clearSkipList()
3396 if (skipList != null)
3403 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3405 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3406 Vector dseqs = null;
3409 // create a list of new dataset sequences
3410 dseqs = new Vector();
3412 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3414 Sequence vamsasSeq = vamsasSet.getSequence(i);
3415 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3417 // create a new dataset
3420 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3421 dseqs.copyInto(dsseqs);
3422 ds = new jalview.datamodel.Alignment(dsseqs);
3423 debug("Created new dataset " + vamsasSet.getDatasetId()
3424 + " for alignment " + System.identityHashCode(al));
3425 addDatasetRef(vamsasSet.getDatasetId(), ds);
3427 // set the dataset for the newly imported alignment.
3428 if (al.getDataset() == null)
3437 * sequence definition to create/merge dataset sequence for
3441 * vector to add new dataset sequence to
3443 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3444 AlignmentI ds, Vector dseqs)
3446 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3448 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3449 .get(vamsasSeq.getId());
3450 jalview.datamodel.SequenceI dsq = null;
3451 if (sq != null && sq.getDatasetSequence() != null)
3453 dsq = (jalview.datamodel.SequenceI) sq.getDatasetSequence();
3456 String sqid = vamsasSeq.getDsseqid();
3459 // need to create or add a new dataset sequence reference to this sequence
3462 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3467 // make a new dataset sequence
3468 dsq = sq.createDatasetSequence();
3471 // make up a new dataset reference for this sequence
3472 sqid = seqHash(dsq);
3474 dsq.setVamsasId(uniqueSetSuffix + sqid);
3475 seqRefIds.put(sqid, dsq);
3480 dseqs.addElement(dsq);
3485 ds.addSequence(dsq);
3491 { // make this dataset sequence sq's dataset sequence
3492 sq.setDatasetSequence(dsq);
3496 // TODO: refactor this as a merge dataset sequence function
3497 // now check that sq (the dataset sequence) sequence really is the union of
3498 // all references to it
3499 // boolean pre = sq.getStart() < dsq.getStart();
3500 // boolean post = sq.getEnd() > dsq.getEnd();
3504 StringBuffer sb = new StringBuffer();
3505 String newres = jalview.analysis.AlignSeq.extractGaps(
3506 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3507 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3508 && newres.length() > dsq.getLength())
3510 // Update with the longer sequence.
3514 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3515 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3516 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3517 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3519 dsq.setSequence(sb.toString());
3521 // TODO: merges will never happen if we 'know' we have the real dataset
3522 // sequence - this should be detected when id==dssid
3523 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3524 // + (pre ? "prepended" : "") + " "
3525 // + (post ? "appended" : ""));
3530 java.util.Hashtable datasetIds = null;
3532 java.util.IdentityHashMap dataset2Ids = null;
3534 private Alignment getDatasetFor(String datasetId)
3536 if (datasetIds == null)
3538 datasetIds = new Hashtable();
3541 if (datasetIds.containsKey(datasetId))
3543 return (Alignment) datasetIds.get(datasetId);
3548 private void addDatasetRef(String datasetId, Alignment dataset)
3550 if (datasetIds == null)
3552 datasetIds = new Hashtable();
3554 datasetIds.put(datasetId, dataset);
3558 * make a new dataset ID for this jalview dataset alignment
3563 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3565 if (dataset.getDataset() != null)
3567 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3569 String datasetId = makeHashCode(dataset, null);
3570 if (datasetId == null)
3572 // make a new datasetId and record it
3573 if (dataset2Ids == null)
3575 dataset2Ids = new IdentityHashMap();
3579 datasetId = (String) dataset2Ids.get(dataset);
3581 if (datasetId == null)
3583 datasetId = "ds" + dataset2Ids.size() + 1;
3584 dataset2Ids.put(dataset, datasetId);
3590 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3592 for (int d = 0; d < sequence.getDBRefCount(); d++)
3594 DBRef dr = sequence.getDBRef(d);
3595 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3596 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3597 .getVersion(), sequence.getDBRef(d).getAccessionId());
3598 if (dr.getMapping() != null)
3600 entry.setMap(addMapping(dr.getMapping()));
3602 datasetSequence.addDBRef(entry);
3606 private jalview.datamodel.Mapping addMapping(Mapping m)
3608 SequenceI dsto = null;
3609 // Mapping m = dr.getMapping();
3610 int fr[] = new int[m.getMapListFromCount() * 2];
3611 Enumeration f = m.enumerateMapListFrom();
3612 for (int _i = 0; f.hasMoreElements(); _i += 2)
3614 MapListFrom mf = (MapListFrom) f.nextElement();
3615 fr[_i] = mf.getStart();
3616 fr[_i + 1] = mf.getEnd();
3618 int fto[] = new int[m.getMapListToCount() * 2];
3619 f = m.enumerateMapListTo();
3620 for (int _i = 0; f.hasMoreElements(); _i += 2)
3622 MapListTo mf = (MapListTo) f.nextElement();
3623 fto[_i] = mf.getStart();
3624 fto[_i + 1] = mf.getEnd();
3626 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3627 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3628 if (m.getMappingChoice() != null)
3630 MappingChoice mc = m.getMappingChoice();
3631 if (mc.getDseqFor() != null)
3633 String dsfor = "" + mc.getDseqFor();
3634 if (seqRefIds.containsKey(dsfor))
3639 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3643 frefedSequence.add(new Object[]
3650 * local sequence definition
3652 Sequence ms = mc.getSequence();
3653 jalview.datamodel.Sequence djs = null;
3654 String sqid = ms.getDsseqid();
3655 if (sqid != null && sqid.length() > 0)
3658 * recover dataset sequence
3660 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3665 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3666 sqid = ((Object) ms).toString(); // make up a new hascode for
3667 // undefined dataset sequence hash
3668 // (unlikely to happen)
3674 * make a new dataset sequence and add it to refIds hash
3676 djs = new jalview.datamodel.Sequence(ms.getName(),
3678 djs.setStart(jmap.getMap().getToLowest());
3679 djs.setEnd(jmap.getMap().getToHighest());
3680 djs.setVamsasId(uniqueSetSuffix + sqid);
3682 seqRefIds.put(sqid, djs);
3685 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3694 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3695 boolean keepSeqRefs)
3698 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3704 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3708 uniqueSetSuffix = "";
3709 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3714 if (this.frefedSequence == null)
3716 frefedSequence = new Vector();
3719 viewportsAdded = new Hashtable();
3721 AlignFrame af = LoadFromObject(jm, null, false, null);
3722 af.alignPanels.clear();
3723 af.closeMenuItem_actionPerformed(true);
3726 * if(ap.av.alignment.getAlignmentAnnotation()!=null) { for(int i=0;
3727 * i<ap.av.alignment.getAlignmentAnnotation().length; i++) {
3728 * if(!ap.av.alignment.getAlignmentAnnotation()[i].autoCalculated) {
3729 * af.alignPanel.av.alignment.getAlignmentAnnotation()[i] =
3730 * ap.av.alignment.getAlignmentAnnotation()[i]; } } }
3733 return af.alignPanel;
3737 * flag indicating if hashtables should be cleared on finalization TODO this
3738 * flag may not be necessary
3740 private boolean _cleartables = true;
3742 private Hashtable jvids2vobj;
3747 * @see java.lang.Object#finalize()
3749 protected void finalize() throws Throwable
3751 // really make sure we have no buried refs left.
3756 this.seqRefIds = null;
3757 this.seqsToIds = null;
3761 private void warn(String msg)
3766 private void warn(String msg, Exception e)
3768 if (Cache.log != null)
3772 Cache.log.warn(msg, e);
3776 Cache.log.warn(msg);
3781 System.err.println("Warning: " + msg);
3784 e.printStackTrace();
3789 private void debug(String string)
3791 debug(string, null);
3794 private void debug(String msg, Exception e)
3796 if (Cache.log != null)
3800 Cache.log.debug(msg, e);
3804 Cache.log.debug(msg);
3809 System.err.println("Warning: " + msg);
3812 e.printStackTrace();
3818 * set the object to ID mapping tables used to write/recover objects and XML
3819 * ID strings for the jalview project. If external tables are provided then
3820 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3821 * object goes out of scope. - also populates the datasetIds hashtable with
3822 * alignment objects containing dataset sequences
3825 * Map from ID strings to jalview datamodel
3827 * Map from jalview datamodel to ID strings
3831 public void setObjectMappingTables(Hashtable vobj2jv,
3832 IdentityHashMap jv2vobj)
3834 this.jv2vobj = jv2vobj;
3835 this.vobj2jv = vobj2jv;
3836 Iterator ds = jv2vobj.keySet().iterator();
3838 while (ds.hasNext())
3840 Object jvobj = ds.next();
3841 id = jv2vobj.get(jvobj).toString();
3842 if (jvobj instanceof jalview.datamodel.Alignment)
3844 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
3846 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
3849 else if (jvobj instanceof jalview.datamodel.Sequence)
3851 // register sequence object so the XML parser can recover it.
3852 if (seqRefIds == null)
3854 seqRefIds = new Hashtable();
3856 if (seqsToIds == null)
3858 seqsToIds = new IdentityHashMap();
3860 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
3861 seqsToIds.put(jvobj, id);
3863 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
3865 if (annotationIds == null)
3867 annotationIds = new Hashtable();
3870 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
3871 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
3872 if (jvann.annotationId == null)
3874 jvann.annotationId = anid;
3876 if (!jvann.annotationId.equals(anid))
3878 // TODO verify that this is the correct behaviour
3879 this.warn("Overriding Annotation ID for " + anid
3880 + " from different id : " + jvann.annotationId);
3881 jvann.annotationId = anid;
3884 else if (jvobj instanceof String)
3886 if (jvids2vobj == null)
3888 jvids2vobj = new Hashtable();
3889 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
3893 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
3898 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
3899 * objects created from the project archive. If string is null (default for
3900 * construction) then suffix will be set automatically.
3904 public void setUniqueSetSuffix(String string)
3906 uniqueSetSuffix = string;
3911 * uses skipList2 as the skipList for skipping views on sequence sets
3912 * associated with keys in the skipList
3916 public void setSkipList(Hashtable skipList2)
3918 skipList = skipList2;