2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, 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 jalview.bin.Cache;
33 import jalview.datamodel.Alignment;
34 import jalview.datamodel.AlignmentAnnotation;
35 import jalview.datamodel.AlignmentI;
36 import jalview.datamodel.SequenceI;
37 import jalview.schemabinding.version2.*;
38 import jalview.schemes.*;
39 import jalview.util.Platform;
40 import jalview.util.jarInputStreamProvider;
43 * Write out the current jalview desktop state as a Jalview XML stream.
45 * Note: the vamsas objects referred to here are primitive versions of the
46 * VAMSAS project schema elements - they are not the same and most likely never
50 * @version $Revision: 1.134 $
52 public class Jalview2XML
55 * create/return unique hash string for sq
58 * @return new or existing unique string for sq
60 String seqHash(SequenceI sq)
62 if (seqsToIds == null)
66 if (seqsToIds.containsKey(sq))
68 return (String) seqsToIds.get(sq);
72 // create sequential key
73 String key = "sq" + (seqsToIds.size() + 1);
74 key = makeHashCode(sq, key); // check we don't have an external reference
76 seqsToIds.put(sq, key);
85 if (seqRefIds != null)
89 if (seqsToIds != null)
99 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
100 // seqRefIds = new Hashtable();
101 // seqsToIds = new IdentityHashMap();
107 if (seqsToIds == null)
109 seqsToIds = new IdentityHashMap();
111 if (seqRefIds == null)
113 seqRefIds = new Hashtable();
118 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
119 * of sequence objects are created.
121 java.util.IdentityHashMap seqsToIds = null;
124 * jalview XML Sequence ID to jalview sequence object reference (both dataset
125 * and alignment sequences. Populated as XML reps of sequence objects are
128 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
130 Vector frefedSequence = null;
132 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
138 public Jalview2XML(boolean raiseGUI)
140 this.raiseGUI = raiseGUI;
143 public void resolveFrefedSequences()
145 if (frefedSequence.size() > 0)
147 int r = 0, rSize = frefedSequence.size();
150 Object[] ref = (Object[]) frefedSequence.elementAt(r);
153 String sref = (String) ref[0];
154 if (seqRefIds.containsKey(sref))
156 if (ref[1] instanceof jalview.datamodel.Mapping)
158 SequenceI seq = (SequenceI) seqRefIds.get(sref);
159 while (seq.getDatasetSequence() != null)
161 seq = seq.getDatasetSequence();
163 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
167 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
169 SequenceI seq = (SequenceI) seqRefIds.get(sref);
170 while (seq.getDatasetSequence() != null)
172 seq = seq.getDatasetSequence();
175 && ref[2] instanceof jalview.datamodel.Mapping)
177 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
178 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
179 seq, mp.getTo(), mp.getMap());
184 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
185 + ref[2].getClass() + " type objects.");
191 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
192 + ref[1].getClass() + " type objects.");
195 frefedSequence.remove(r);
201 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
203 + " with objecttype "
204 + ref[1].getClass());
211 frefedSequence.remove(r);
219 * This maintains a list of viewports, the key being the seqSetId. Important
220 * to set historyItem and redoList for multiple views
222 Hashtable viewportsAdded;
224 Hashtable annotationIds = new Hashtable();
226 String uniqueSetSuffix = "";
229 * List of pdbfiles added to Jar
231 Vector pdbfiles = null;
233 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
234 public void SaveState(File statefile)
238 FileOutputStream fos = new FileOutputStream(statefile);
239 JarOutputStream jout = new JarOutputStream(fos);
242 } catch (Exception e)
244 // TODO: inform user of the problem - they need to know if their data was
246 if (errorMessage == null)
248 errorMessage = "Couldn't write Jalview Archive to output file '"
249 + statefile + "' - See console error log for details";
253 errorMessage += "(output file was '" + statefile + "')";
261 * Writes a jalview project archive to the given Jar output stream.
265 public void SaveState(JarOutputStream jout)
267 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
277 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
278 // //////////////////////////////////////////////////
279 // NOTE ALSO new PrintWriter must be used for each new JarEntry
280 PrintWriter out = null;
282 Vector shortNames = new Vector();
285 for (int i = frames.length - 1; i > -1; i--)
287 if (frames[i] instanceof AlignFrame)
289 AlignFrame af = (AlignFrame) frames[i];
292 && skipList.containsKey(af.getViewport()
293 .getSequenceSetId()))
298 String shortName = af.getTitle();
300 if (shortName.indexOf(File.separatorChar) > -1)
302 shortName = shortName.substring(shortName
303 .lastIndexOf(File.separatorChar) + 1);
308 while (shortNames.contains(shortName))
310 if (shortName.endsWith("_" + (count - 1)))
312 shortName = shortName
313 .substring(0, shortName.lastIndexOf("_"));
316 shortName = shortName.concat("_" + count);
320 shortNames.addElement(shortName);
322 if (!shortName.endsWith(".xml"))
324 shortName = shortName + ".xml";
327 int ap, apSize = af.alignPanels.size();
328 for (ap = 0; ap < apSize; ap++)
330 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
332 String fileName = apSize == 1 ? shortName : ap + shortName;
333 if (!fileName.endsWith(".xml"))
335 fileName = fileName + ".xml";
338 SaveState(apanel, fileName, jout);
345 } catch (Exception foo)
350 } catch (Exception ex)
352 // TODO: inform user of the problem - they need to know if their data was
354 if (errorMessage == null)
356 errorMessage = "Couldn't write Jalview Archive - see error output for details";
358 ex.printStackTrace();
362 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
363 public boolean SaveAlignment(AlignFrame af, String jarFile,
368 int ap, apSize = af.alignPanels.size();
369 FileOutputStream fos = new FileOutputStream(jarFile);
370 JarOutputStream jout = new JarOutputStream(fos);
371 for (ap = 0; ap < apSize; ap++)
373 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
375 String jfileName = apSize == 1 ? fileName : fileName + ap;
376 if (!jfileName.endsWith(".xml"))
378 jfileName = jfileName + ".xml";
380 SaveState(apanel, jfileName, jout);
386 } catch (Exception foo)
392 } catch (Exception ex)
394 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
395 ex.printStackTrace();
401 * create a JalviewModel from an algnment view and marshall it to a
405 * panel to create jalview model for
407 * name of alignment panel written to output stream
413 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
414 JarOutputStream jout)
417 Vector jmolViewIds = new Vector(); //
418 Vector userColours = new Vector();
420 AlignViewport av = ap.av;
422 JalviewModel object = new JalviewModel();
423 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
425 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
426 object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
428 jalview.datamodel.AlignmentI jal = av.getAlignment();
430 if (av.hasHiddenRows())
432 jal = jal.getHiddenSequences().getFullAlignment();
435 SequenceSet vamsasSet = new SequenceSet();
437 JalviewModelSequence jms = new JalviewModelSequence();
439 vamsasSet.setGapChar(jal.getGapCharacter() + "");
441 if (jal.getDataset() != null)
443 // dataset id is the dataset's hashcode
444 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
446 if (jal.getProperties() != null)
448 Enumeration en = jal.getProperties().keys();
449 while (en.hasMoreElements())
451 String key = en.nextElement().toString();
452 SequenceSetProperties ssp = new SequenceSetProperties();
454 ssp.setValue(jal.getProperties().get(key).toString());
455 vamsasSet.addSequenceSetProperties(ssp);
463 jalview.datamodel.SequenceI jds;
464 for (int i = 0; i < jal.getHeight(); i++)
466 jds = jal.getSequenceAt(i);
469 if (seqRefIds.get(id) != null)
471 // This happens for two reasons: 1. multiple views are being serialised.
472 // 2. the hashCode has collided with another sequence's code. This DOES
473 // HAPPEN! (PF00072.15.stk does this)
474 // JBPNote: Uncomment to debug writing out of files that do not read
475 // back in due to ArrayOutOfBoundExceptions.
476 // System.err.println("vamsasSeq backref: "+id+"");
477 // System.err.println(jds.getName()+"
478 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
479 // System.err.println("Hashcode: "+seqHash(jds));
480 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
481 // System.err.println(rsq.getName()+"
482 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
483 // System.err.println("Hashcode: "+seqHash(rsq));
487 vamsasSeq = createVamsasSequence(id, jds);
488 vamsasSet.addSequence(vamsasSeq);
489 seqRefIds.put(id, jds);
493 jseq.setStart(jds.getStart());
494 jseq.setEnd(jds.getEnd());
495 jseq.setColour(av.getSequenceColour(jds).getRGB());
497 jseq.setId(id); // jseq id should be a string not a number
499 if (av.hasHiddenRows())
501 jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds));
503 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
505 jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(jal.getSequenceAt(i)).getSequencesInOrder(jal);
507 for (int h = 0; h < reps.length; h++)
509 if (reps[h] != jal.getSequenceAt(i))
511 jseq.addHiddenSequences(jal.findIndex(reps[h]));
517 if (jds.getDatasetSequence().getSequenceFeatures() != null)
519 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
520 .getSequenceFeatures();
522 while (index < sf.length)
524 Features features = new Features();
526 features.setBegin(sf[index].getBegin());
527 features.setEnd(sf[index].getEnd());
528 features.setDescription(sf[index].getDescription());
529 features.setType(sf[index].getType());
530 features.setFeatureGroup(sf[index].getFeatureGroup());
531 features.setScore(sf[index].getScore());
532 if (sf[index].links != null)
534 for (int l = 0; l < sf[index].links.size(); l++)
536 OtherData keyValue = new OtherData();
537 keyValue.setKey("LINK_" + l);
538 keyValue.setValue(sf[index].links.elementAt(l).toString());
539 features.addOtherData(keyValue);
542 if (sf[index].otherDetails != null)
545 Enumeration keys = sf[index].otherDetails.keys();
546 while (keys.hasMoreElements())
548 key = keys.nextElement().toString();
549 OtherData keyValue = new OtherData();
550 keyValue.setKey(key);
551 keyValue.setValue(sf[index].otherDetails.get(key).toString());
552 features.addOtherData(keyValue);
556 jseq.addFeatures(features);
561 if (jds.getDatasetSequence().getPDBId() != null)
563 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
564 while (en.hasMoreElements())
566 Pdbids pdb = new Pdbids();
567 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
570 pdb.setId(entry.getId());
571 pdb.setType(entry.getType());
574 // This must have been loaded, is it still visible?
575 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
576 String matchedFile = null;
577 for (int f = frames.length - 1; f > -1; f--)
579 if (frames[f] instanceof AppJmol)
581 jmol = (AppJmol) frames[f];
582 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
584 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
585 && !(entry.getId().length() > 4 && entry
589 jmol.jmb.pdbentry[peid].getId()
592 if (matchedFile == null)
594 matchedFile = jmol.jmb.pdbentry[peid].getFile();
596 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
600 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
601 + jmol.jmb.pdbentry[peid].getFile());
605 // can get at it if the ID
606 // match is ambiguous (e.g.
608 String statestring = jmol.jmb.viewer.getStateInfo();
610 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
612 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
613 if (jds==jmol.jmb.sequence[peid][smap])
615 StructureState state = new StructureState();
616 state.setVisible(true);
617 state.setXpos(jmol.getX());
618 state.setYpos(jmol.getY());
619 state.setWidth(jmol.getWidth());
620 state.setHeight(jmol.getHeight());
621 state.setViewId(jmol.getViewId());
622 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
623 state.setColourwithAlignPanel(jmol
624 .isUsedforcolourby(ap));
625 state.setColourByJmol(jmol.isColouredByJmol());
626 if (!jmolViewIds.contains(state.getViewId()))
628 // Make sure we only store a Jmol state once in each XML
630 jmolViewIds.addElement(state.getViewId());
631 state.setContent(statestring.replaceAll("\n", ""));
635 state.setContent("# duplicate state");
637 pdb.addStructureState(state);
644 if (matchedFile != null || entry.getFile() != null)
646 if (entry.getFile() != null)
649 matchedFile = entry.getFile();
651 pdb.setFile(matchedFile); // entry.getFile());
652 if (pdbfiles == null)
654 pdbfiles = new Vector();
657 if (!pdbfiles.contains(entry.getId()))
659 pdbfiles.addElement(entry.getId());
662 File file = new File(matchedFile);
663 if (file.exists() && jout != null)
665 byte[] data = new byte[(int) file.length()];
666 jout.putNextEntry(new JarEntry(entry.getId()));
667 DataInputStream dis = new DataInputStream(
668 new FileInputStream(file));
671 DataOutputStream dout = new DataOutputStream(jout);
672 dout.write(data, 0, data.length);
676 } catch (Exception ex)
678 ex.printStackTrace();
684 if (entry.getProperty() != null)
686 PdbentryItem item = new PdbentryItem();
687 Hashtable properties = entry.getProperty();
688 Enumeration en2 = properties.keys();
689 while (en2.hasMoreElements())
691 Property prop = new Property();
692 String key = en2.nextElement().toString();
694 prop.setValue(properties.get(key).toString());
695 item.addProperty(prop);
697 pdb.addPdbentryItem(item);
707 if (av.hasHiddenRows())
709 jal = av.getAlignment();
712 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
714 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
715 for (int i = 0; i < jac.length; i++)
717 AlcodonFrame alc = new AlcodonFrame();
718 vamsasSet.addAlcodonFrame(alc);
719 for (int p = 0; p < jac[i].aaWidth; p++)
721 Alcodon cmap = new Alcodon();
722 if (jac[i].codons[p] != null)
724 // Null codons indicate a gapped column in the translated peptide
726 cmap.setPos1(jac[i].codons[p][0]);
727 cmap.setPos2(jac[i].codons[p][1]);
728 cmap.setPos3(jac[i].codons[p][2]);
730 alc.addAlcodon(cmap);
732 if (jac[i].getProtMappings() != null
733 && jac[i].getProtMappings().length > 0)
735 SequenceI[] dnas = jac[i].getdnaSeqs();
736 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
737 for (int m = 0; m < pmaps.length; m++)
739 AlcodMap alcmap = new AlcodMap();
740 alcmap.setDnasq(seqHash(dnas[m]));
741 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
743 alc.addAlcodMap(alcmap);
750 // /////////////////////////////////
751 if (av.currentTree != null)
753 // FIND ANY ASSOCIATED TREES
754 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
755 if (Desktop.desktop != null)
757 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
759 for (int t = 0; t < frames.length; t++)
761 if (frames[t] instanceof TreePanel)
763 TreePanel tp = (TreePanel) frames[t];
765 if (tp.treeCanvas.av.getAlignment() == jal)
767 Tree tree = new Tree();
768 tree.setTitle(tp.getTitle());
769 tree.setCurrentTree((av.currentTree == tp.getTree()));
770 tree.setNewick(tp.getTree().toString());
771 tree.setThreshold(tp.treeCanvas.threshold);
773 tree.setFitToWindow(tp.fitToWindow.getState());
774 tree.setFontName(tp.getTreeFont().getName());
775 tree.setFontSize(tp.getTreeFont().getSize());
776 tree.setFontStyle(tp.getTreeFont().getStyle());
777 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
779 tree.setShowBootstrap(tp.bootstrapMenu.getState());
780 tree.setShowDistances(tp.distanceMenu.getState());
782 tree.setHeight(tp.getHeight());
783 tree.setWidth(tp.getWidth());
784 tree.setXpos(tp.getX());
785 tree.setYpos(tp.getY());
786 tree.setId(makeHashCode(tp, null));
796 * store forward refs from an annotationRow to any groups
798 IdentityHashMap groupRefs = new IdentityHashMap();
799 if (jal.getAlignmentAnnotation() != null)
801 jalview.datamodel.AlignmentAnnotation[] aa = jal
802 .getAlignmentAnnotation();
804 for (int i = 0; i < aa.length; i++)
806 Annotation an = new Annotation();
808 if (aa[i].annotationId != null)
810 annotationIds.put(aa[i].annotationId, aa[i]);
813 an.setId(aa[i].annotationId);
815 an.setVisible(aa[i].visible);
817 an.setDescription(aa[i].description);
819 if (aa[i].sequenceRef != null)
821 // TODO later annotation sequenceRef should be the XML ID of the
822 // sequence rather than its display name
823 an.setSequenceRef(aa[i].sequenceRef.getName());
825 if (aa[i].groupRef != null)
827 Object groupIdr = groupRefs.get(aa[i].groupRef);
828 if (groupIdr == null)
830 // make a locally unique String
831 groupRefs.put(aa[i].groupRef,
832 groupIdr = ("" + System.currentTimeMillis()
833 + aa[i].groupRef.getName() + groupRefs.size()));
835 an.setGroupRef(groupIdr.toString());
838 // store all visualization attributes for annotation
839 an.setGraphHeight(aa[i].graphHeight);
840 an.setCentreColLabels(aa[i].centreColLabels);
841 an.setScaleColLabels(aa[i].scaleColLabel);
842 an.setShowAllColLabels(aa[i].showAllColLabels);
843 an.setBelowAlignment(aa[i].belowAlignment);
848 an.setGraphType(aa[i].graph);
849 an.setGraphGroup(aa[i].graphGroup);
850 if (aa[i].getThreshold() != null)
852 ThresholdLine line = new ThresholdLine();
853 line.setLabel(aa[i].getThreshold().label);
854 line.setValue(aa[i].getThreshold().value);
855 line.setColour(aa[i].getThreshold().colour.getRGB());
856 an.setThresholdLine(line);
864 an.setLabel(aa[i].label);
866 if (aa[i] == av.getAlignmentQualityAnnot() || aa[i] == av.getAlignmentConservationAnnotation()
867 || aa[i] == av.getAlignmentConsensusAnnotation() || aa[i].autoCalculated)
869 // new way of indicating autocalculated annotation -
870 an.setAutoCalculated(aa[i].autoCalculated);
872 if (aa[i].hasScore())
874 an.setScore(aa[i].getScore());
877 if (aa[i].getCalcId()!=null)
879 an.setCalcId(aa[i].getCalcId());
882 AnnotationElement ae;
883 if (aa[i].annotations != null)
885 an.setScoreOnly(false);
886 for (int a = 0; a < aa[i].annotations.length; a++)
888 if ((aa[i] == null) || (aa[i].annotations[a] == null))
893 ae = new AnnotationElement();
894 if (aa[i].annotations[a].description != null)
895 ae.setDescription(aa[i].annotations[a].description);
896 if (aa[i].annotations[a].displayCharacter != null)
897 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
899 if (!Float.isNaN(aa[i].annotations[a].value))
900 ae.setValue(aa[i].annotations[a].value);
903 if (aa[i].annotations[a].secondaryStructure != ' '
904 && aa[i].annotations[a].secondaryStructure != '\0')
905 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
908 if (aa[i].annotations[a].colour != null
909 && aa[i].annotations[a].colour != java.awt.Color.black)
911 ae.setColour(aa[i].annotations[a].colour.getRGB());
914 an.addAnnotationElement(ae);
915 if (aa[i].autoCalculated)
917 // only write one non-null entry into the annotation row -
918 // sufficient to get the visualization attributes necessary to
926 an.setScoreOnly(true);
928 vamsasSet.addAnnotation(an);
932 if (jal.getGroups() != null)
934 JGroup[] groups = new JGroup[jal.getGroups().size()];
936 for (jalview.datamodel.SequenceGroup sg:jal.getGroups())
938 groups[++i] = new JGroup();
940 groups[i].setStart(sg.getStartRes());
941 groups[i].setEnd(sg.getEndRes());
942 groups[i].setName(sg.getName());
943 if (groupRefs.containsKey(sg))
945 // group has references so set it's ID field
946 groups[i].setId(groupRefs.get(sg).toString());
950 if (sg.cs.conservationApplied())
952 groups[i].setConsThreshold(sg.cs.getConservationInc());
954 if (sg.cs instanceof jalview.schemes.UserColourScheme)
956 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
962 .setColour(ColourSchemeProperty.getColourName(sg.cs));
965 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
968 .setColour(ColourSchemeProperty
969 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
972 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
975 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
979 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
982 groups[i].setPidThreshold(sg.cs.getThreshold());
985 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
986 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
987 groups[i].setDisplayText(sg.getDisplayText());
988 groups[i].setColourText(sg.getColourText());
989 groups[i].setTextCol1(sg.textColour.getRGB());
990 groups[i].setTextCol2(sg.textColour2.getRGB());
991 groups[i].setTextColThreshold(sg.thresholdTextColour);
992 groups[i].setShowUnconserved(sg.getShowNonconserved());
993 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
994 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
995 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
996 for (int s = 0; s < sg.getSize(); s++)
998 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1000 groups[i].addSeq(seqHash(seq));
1004 jms.setJGroup(groups);
1007 // /////////SAVE VIEWPORT
1008 Viewport view = new Viewport();
1009 view.setTitle(ap.alignFrame.getTitle());
1010 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1011 av.getSequenceSetId()));
1012 view.setId(av.getViewId());
1013 view.setViewName(av.viewName);
1014 view.setGatheredViews(av.gatherViewsHere);
1016 if (ap.av.explodedPosition != null)
1018 view.setXpos(av.explodedPosition.x);
1019 view.setYpos(av.explodedPosition.y);
1020 view.setWidth(av.explodedPosition.width);
1021 view.setHeight(av.explodedPosition.height);
1025 view.setXpos(ap.alignFrame.getBounds().x);
1026 view.setYpos(ap.alignFrame.getBounds().y);
1027 view.setWidth(ap.alignFrame.getBounds().width);
1028 view.setHeight(ap.alignFrame.getBounds().height);
1031 view.setStartRes(av.startRes);
1032 view.setStartSeq(av.startSeq);
1034 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1036 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1039 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1041 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1042 .getGlobalColourScheme();
1044 AnnotationColours ac = new AnnotationColours();
1045 ac.setAboveThreshold(acg.getAboveThreshold());
1046 ac.setThreshold(acg.getAnnotationThreshold());
1047 ac.setAnnotation(acg.getAnnotation());
1048 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1050 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1055 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1059 ac.setMaxColour(acg.getMaxColour().getRGB());
1060 ac.setMinColour(acg.getMinColour().getRGB());
1061 view.setAnnotationColours(ac);
1062 view.setBgColour("AnnotationColourGradient");
1066 view.setBgColour(ColourSchemeProperty.getColourName(av
1067 .getGlobalColourScheme()));
1070 ColourSchemeI cs = av.getGlobalColourScheme();
1074 if (cs.conservationApplied())
1076 view.setConsThreshold(cs.getConservationInc());
1077 if (cs instanceof jalview.schemes.UserColourScheme)
1079 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1083 if (cs instanceof ResidueColourScheme)
1085 view.setPidThreshold(cs.getThreshold());
1089 view.setConservationSelected(av.getConservationSelected());
1090 view.setPidSelected(av.getAbovePIDThreshold());
1091 view.setFontName(av.font.getName());
1092 view.setFontSize(av.font.getSize());
1093 view.setFontStyle(av.font.getStyle());
1094 view.setRenderGaps(av.renderGaps);
1095 view.setShowAnnotation(av.getShowAnnotation());
1096 view.setShowBoxes(av.getShowBoxes());
1097 view.setShowColourText(av.getColourText());
1098 view.setShowFullId(av.getShowJVSuffix());
1099 view.setRightAlignIds(av.rightAlignIds);
1100 view.setShowSequenceFeatures(av.showSequenceFeatures);
1101 view.setShowText(av.getShowText());
1102 view.setShowUnconserved(av.getShowUnconserved());
1103 view.setWrapAlignment(av.getWrapAlignment());
1104 view.setTextCol1(av.textColour.getRGB());
1105 view.setTextCol2(av.textColour2.getRGB());
1106 view.setTextColThreshold(av.thresholdTextColour);
1107 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1108 view.setShowSequenceLogo(av.isShowSequenceLogo());
1109 view.setShowGroupConsensus(av.isShowGroupConsensus());
1110 view.setShowGroupConservation(av.isShowGroupConservation());
1111 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1112 view.setShowDbRefTooltip(av.isShowDbRefs());
1113 view.setFollowHighlight(av.followHighlight);
1114 view.setFollowSelection(av.followSelection);
1115 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1116 if (av.featuresDisplayed != null)
1118 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1120 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1122 Vector settingsAdded = new Vector();
1123 Object gstyle = null;
1124 GraduatedColor gcol = null;
1125 if (renderOrder != null)
1127 for (int ro = 0; ro < renderOrder.length; ro++)
1129 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1130 .getFeatureStyle(renderOrder[ro]);
1131 Setting setting = new Setting();
1132 setting.setType(renderOrder[ro]);
1133 if (gstyle instanceof GraduatedColor)
1135 gcol = (GraduatedColor) gstyle;
1136 setting.setColour(gcol.getMaxColor().getRGB());
1137 setting.setMincolour(gcol.getMinColor().getRGB());
1138 setting.setMin(gcol.getMin());
1139 setting.setMax(gcol.getMax());
1140 setting.setColourByLabel(gcol.isColourByLabel());
1141 setting.setAutoScale(gcol.isAutoScale());
1142 setting.setThreshold(gcol.getThresh());
1143 setting.setThreshstate(gcol.getThreshType());
1147 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1148 .getColour(renderOrder[ro]).getRGB());
1151 setting.setDisplay(av.featuresDisplayed
1152 .containsKey(renderOrder[ro]));
1153 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1154 .getOrder(renderOrder[ro]);
1157 setting.setOrder(rorder);
1159 fs.addSetting(setting);
1160 settingsAdded.addElement(renderOrder[ro]);
1164 // Make sure we save none displayed feature settings
1165 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1166 .keySet().iterator();
1167 while (en.hasNext())
1169 String key = en.next().toString();
1170 if (settingsAdded.contains(key))
1175 Setting setting = new Setting();
1176 setting.setType(key);
1177 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1178 .getColour(key).getRGB());
1180 setting.setDisplay(false);
1181 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1185 setting.setOrder(rorder);
1187 fs.addSetting(setting);
1188 settingsAdded.addElement(key);
1190 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keySet().iterator();
1191 Vector groupsAdded = new Vector();
1192 while (en.hasNext())
1194 String grp = en.next().toString();
1195 if (groupsAdded.contains(grp))
1199 Group g = new Group();
1201 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1202 .get(grp)).booleanValue());
1204 groupsAdded.addElement(grp);
1206 jms.setFeatureSettings(fs);
1210 if (av.hasHiddenColumns())
1212 if (av.getColumnSelection() == null
1213 || av.getColumnSelection().getHiddenColumns() == null)
1215 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1219 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1222 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1224 HiddenColumns hc = new HiddenColumns();
1225 hc.setStart(region[0]);
1226 hc.setEnd(region[1]);
1227 view.addHiddenColumns(hc);
1232 jms.addViewport(view);
1234 object.setJalviewModelSequence(jms);
1235 object.getVamsasModel().addSequenceSet(vamsasSet);
1237 if (jout != null && fileName != null)
1239 // We may not want to write the object to disk,
1240 // eg we can copy the alignViewport to a new view object
1241 // using save and then load
1244 JarEntry entry = new JarEntry(fileName);
1245 jout.putNextEntry(entry);
1246 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1248 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1250 marshaller.marshal(object);
1253 } catch (Exception ex)
1255 // TODO: raise error in GUI if marshalling failed.
1256 ex.printStackTrace();
1263 * External mapping between jalview objects and objects yielding a valid and
1264 * unique object ID string. This is null for normal Jalview project IO, but
1265 * non-null when a jalview project is being read or written as part of a
1268 IdentityHashMap jv2vobj = null;
1271 * Construct a unique ID for jvobj using either existing bindings or if none
1272 * exist, the result of the hashcode call for the object.
1275 * jalview data object
1276 * @return unique ID for referring to jvobj
1278 private String makeHashCode(Object jvobj, String altCode)
1280 if (jv2vobj != null)
1282 Object id = jv2vobj.get(jvobj);
1285 return id.toString();
1287 // check string ID mappings
1288 if (jvids2vobj != null && jvobj instanceof String)
1290 id = jvids2vobj.get(jvobj);
1294 return id.toString();
1296 // give up and warn that something has gone wrong
1297 warn("Cannot find ID for object in external mapping : " + jvobj);
1303 * return local jalview object mapped to ID, if it exists
1307 * @return null or object bound to idcode
1309 private Object retrieveExistingObj(String idcode)
1311 if (idcode != null && vobj2jv != null)
1313 return vobj2jv.get(idcode);
1319 * binding from ID strings from external mapping table to jalview data model
1322 private Hashtable vobj2jv;
1324 private Sequence createVamsasSequence(String id, SequenceI jds)
1326 return createVamsasSequence(true, id, jds, null);
1329 private Sequence createVamsasSequence(boolean recurse, String id,
1330 SequenceI jds, SequenceI parentseq)
1332 Sequence vamsasSeq = new Sequence();
1333 vamsasSeq.setId(id);
1334 vamsasSeq.setName(jds.getName());
1335 vamsasSeq.setSequence(jds.getSequenceAsString());
1336 vamsasSeq.setDescription(jds.getDescription());
1337 jalview.datamodel.DBRefEntry[] dbrefs = null;
1338 if (jds.getDatasetSequence() != null)
1340 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1341 if (jds.getDatasetSequence().getDBRef() != null)
1343 dbrefs = jds.getDatasetSequence().getDBRef();
1348 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1349 // dataset sequences only
1350 dbrefs = jds.getDBRef();
1354 for (int d = 0; d < dbrefs.length; d++)
1356 DBRef dbref = new DBRef();
1357 dbref.setSource(dbrefs[d].getSource());
1358 dbref.setVersion(dbrefs[d].getVersion());
1359 dbref.setAccessionId(dbrefs[d].getAccessionId());
1360 if (dbrefs[d].hasMap())
1362 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1364 dbref.setMapping(mp);
1366 vamsasSeq.addDBRef(dbref);
1372 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1373 SequenceI parentseq, SequenceI jds, boolean recurse)
1376 if (jmp.getMap() != null)
1380 jalview.util.MapList mlst = jmp.getMap();
1381 int r[] = mlst.getFromRanges();
1382 for (int s = 0; s < r.length; s += 2)
1384 MapListFrom mfrom = new MapListFrom();
1385 mfrom.setStart(r[s]);
1386 mfrom.setEnd(r[s + 1]);
1387 mp.addMapListFrom(mfrom);
1389 r = mlst.getToRanges();
1390 for (int s = 0; s < r.length; s += 2)
1392 MapListTo mto = new MapListTo();
1394 mto.setEnd(r[s + 1]);
1395 mp.addMapListTo(mto);
1397 mp.setMapFromUnit(mlst.getFromRatio());
1398 mp.setMapToUnit(mlst.getToRatio());
1399 if (jmp.getTo() != null)
1401 MappingChoice mpc = new MappingChoice();
1403 && (parentseq != jmp.getTo() || parentseq
1404 .getDatasetSequence() != jmp.getTo()))
1406 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1412 SequenceI ps = null;
1413 if (parentseq != jmp.getTo()
1414 && parentseq.getDatasetSequence() != jmp.getTo())
1416 // chaining dbref rather than a handshaking one
1417 jmpid = seqHash(ps = jmp.getTo());
1421 jmpid = seqHash(ps = parentseq);
1423 mpc.setDseqFor(jmpid);
1424 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1426 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1427 seqRefIds.put(mpc.getDseqFor(), ps);
1431 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1434 mp.setMappingChoice(mpc);
1440 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1441 Vector userColours, JalviewModelSequence jms)
1444 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1445 boolean newucs = false;
1446 if (!userColours.contains(ucs))
1448 userColours.add(ucs);
1451 id = "ucs" + userColours.indexOf(ucs);
1454 // actually create the scheme's entry in the XML model
1455 java.awt.Color[] colours = ucs.getColours();
1456 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1457 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1459 for (int i = 0; i < colours.length; i++)
1461 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1462 col.setName(ResidueProperties.aa[i]);
1463 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1464 jbucs.addColour(col);
1466 if (ucs.getLowerCaseColours() != null)
1468 colours = ucs.getLowerCaseColours();
1469 for (int i = 0; i < colours.length; i++)
1471 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1472 col.setName(ResidueProperties.aa[i].toLowerCase());
1473 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1474 jbucs.addColour(col);
1479 uc.setUserColourScheme(jbucs);
1480 jms.addUserColours(uc);
1486 jalview.schemes.UserColourScheme GetUserColourScheme(
1487 JalviewModelSequence jms, String id)
1489 UserColours[] uc = jms.getUserColours();
1490 UserColours colours = null;
1492 for (int i = 0; i < uc.length; i++)
1494 if (uc[i].getId().equals(id))
1502 java.awt.Color[] newColours = new java.awt.Color[24];
1504 for (int i = 0; i < 24; i++)
1506 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1507 .getUserColourScheme().getColour(i).getRGB(), 16));
1510 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1513 if (colours.getUserColourScheme().getColourCount() > 24)
1515 newColours = new java.awt.Color[23];
1516 for (int i = 0; i < 23; i++)
1518 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1519 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1521 ucs.setLowerCaseColours(newColours);
1528 * contains last error message (if any) encountered by XML loader.
1530 String errorMessage = null;
1533 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1534 * exceptions are raised during project XML parsing
1536 public boolean attemptversion1parse = true;
1539 * Load a jalview project archive from a jar file
1542 * - HTTP URL or filename
1544 public AlignFrame LoadJalviewAlign(final String file)
1547 jalview.gui.AlignFrame af = null;
1551 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1552 // Workaround is to make sure caller implements the JarInputStreamProvider
1554 // so we can re-open the jar input stream for each entry.
1556 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1557 af = LoadJalviewAlign(jprovider);
1558 } catch (MalformedURLException e)
1560 errorMessage = "Invalid URL format for '" + file + "'";
1566 private jarInputStreamProvider createjarInputStreamProvider(
1567 final String file) throws MalformedURLException
1570 errorMessage = null;
1571 uniqueSetSuffix = null;
1573 viewportsAdded = null;
1574 frefedSequence = null;
1576 if (file.startsWith("http://"))
1578 url = new URL(file);
1580 final URL _url = url;
1581 return new jarInputStreamProvider()
1585 public JarInputStream getJarInputStream() throws IOException
1589 return new JarInputStream(_url.openStream());
1593 return new JarInputStream(new FileInputStream(file));
1598 public String getFilename()
1606 * Recover jalview session from a jalview project archive. Caller may
1607 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1608 * themselves. Any null fields will be initialised with default values,
1609 * non-null fields are left alone.
1614 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1616 errorMessage = null;
1617 if (uniqueSetSuffix == null)
1619 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1621 if (seqRefIds == null)
1623 seqRefIds = new Hashtable();
1625 if (viewportsAdded == null)
1627 viewportsAdded = new Hashtable();
1629 if (frefedSequence == null)
1631 frefedSequence = new Vector();
1634 jalview.gui.AlignFrame af = null;
1635 Hashtable gatherToThisFrame = new Hashtable();
1636 final String file = jprovider.getFilename();
1639 JarInputStream jin = null;
1640 JarEntry jarentry = null;
1645 jin = jprovider.getJarInputStream();
1646 for (int i = 0; i < entryCount; i++)
1648 jarentry = jin.getNextJarEntry();
1651 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1653 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1654 JalviewModel object = new JalviewModel();
1656 Unmarshaller unmar = new Unmarshaller(object);
1657 unmar.setValidation(false);
1658 object = (JalviewModel) unmar.unmarshal(in);
1659 if (true) // !skipViewport(object))
1661 af = LoadFromObject(object, file, true, jprovider);
1662 if (af.viewport.gatherViewsHere)
1664 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1669 else if (jarentry != null)
1671 // Some other file here.
1674 } while (jarentry != null);
1675 resolveFrefedSequences();
1676 } catch (java.io.FileNotFoundException ex)
1678 ex.printStackTrace();
1679 errorMessage = "Couldn't locate Jalview XML file : " + file;
1680 System.err.println("Exception whilst loading jalview XML file : "
1682 } catch (java.net.UnknownHostException ex)
1684 ex.printStackTrace();
1685 errorMessage = "Couldn't locate Jalview XML file : " + file;
1686 System.err.println("Exception whilst loading jalview XML file : "
1688 } catch (Exception ex)
1690 System.err.println("Parsing as Jalview Version 2 file failed.");
1691 ex.printStackTrace(System.err);
1692 if (attemptversion1parse)
1694 // Is Version 1 Jar file?
1697 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1698 } catch (Exception ex2)
1700 System.err.println("Exception whilst loading as jalviewXMLV1:");
1701 ex2.printStackTrace();
1705 if (Desktop.instance != null)
1707 Desktop.instance.stopLoading();
1711 System.out.println("Successfully loaded archive file");
1714 ex.printStackTrace();
1716 System.err.println("Exception whilst loading jalview XML file : "
1718 } catch (OutOfMemoryError e)
1720 // Don't use the OOM Window here
1721 errorMessage = "Out of memory loading jalview XML file";
1722 System.err.println("Out of memory whilst loading jalview XML file");
1723 e.printStackTrace();
1726 if (Desktop.instance != null)
1728 Desktop.instance.stopLoading();
1731 Enumeration en = gatherToThisFrame.elements();
1732 while (en.hasMoreElements())
1734 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1736 if (errorMessage != null)
1744 * check errorMessage for a valid error message and raise an error box in the
1745 * GUI or write the current errorMessage to stderr and then clear the error
1748 protected void reportErrors()
1750 reportErrors(false);
1753 protected void reportErrors(final boolean saving)
1755 if (errorMessage != null)
1757 final String finalErrorMessage = errorMessage;
1760 javax.swing.SwingUtilities.invokeLater(new Runnable()
1765 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1766 finalErrorMessage, "Error "
1767 + (saving ? "saving" : "loading")
1768 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1774 System.err.println("Problem loading Jalview file: " + errorMessage);
1777 errorMessage = null;
1780 Hashtable alreadyLoadedPDB;
1783 * when set, local views will be updated from view stored in JalviewXML
1784 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1785 * sync if this is set to true.
1787 private final boolean updateLocalViews = false;
1789 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1791 if (alreadyLoadedPDB == null)
1792 alreadyLoadedPDB = new Hashtable();
1794 if (alreadyLoadedPDB.containsKey(pdbId))
1795 return alreadyLoadedPDB.get(pdbId).toString();
1799 JarInputStream jin = jprovider.getJarInputStream();
1801 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1802 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1803 * FileInputStream(jprovider)); }
1806 JarEntry entry = null;
1809 entry = jin.getNextJarEntry();
1810 } while (entry != null && !entry.getName().equals(pdbId));
1813 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1814 File outFile = File.createTempFile("jalview_pdb", ".txt");
1815 outFile.deleteOnExit();
1816 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1819 while ((data = in.readLine()) != null)
1826 } catch (Exception foo)
1831 String t=outFile.getAbsolutePath();
1832 alreadyLoadedPDB.put(pdbId, t);
1837 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1839 } catch (Exception ex)
1841 ex.printStackTrace();
1847 private class JvAnnotRow
1849 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1856 * persisted version of annotation row from which to take vis properties
1858 public jalview.datamodel.AlignmentAnnotation template;
1861 * original position of the annotation row in the alignment
1867 * Load alignment frame from jalview XML DOM object
1872 * filename source string
1873 * @param loadTreesAndStructures
1874 * when false only create Viewport
1876 * data source provider
1877 * @return alignment frame created from view stored in DOM
1879 AlignFrame LoadFromObject(JalviewModel object, String file,
1880 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
1882 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1883 Sequence[] vamsasSeq = vamsasSet.getSequence();
1885 JalviewModelSequence jms = object.getJalviewModelSequence();
1887 Viewport view = jms.getViewport(0);
1888 // ////////////////////////////////
1891 Vector hiddenSeqs = null;
1892 jalview.datamodel.Sequence jseq;
1894 ArrayList tmpseqs = new ArrayList();
1896 boolean multipleView = false;
1898 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1899 int vi = 0; // counter in vamsasSeq array
1900 for (int i = 0; i < JSEQ.length; i++)
1902 String seqId = JSEQ[i].getId();
1904 if (seqRefIds.get(seqId) != null)
1906 tmpseqs.add(seqRefIds.get(seqId));
1907 multipleView = true;
1911 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
1912 vamsasSeq[vi].getSequence());
1913 jseq.setDescription(vamsasSeq[vi].getDescription());
1914 jseq.setStart(JSEQ[i].getStart());
1915 jseq.setEnd(JSEQ[i].getEnd());
1916 jseq.setVamsasId(uniqueSetSuffix + seqId);
1917 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
1922 if (JSEQ[i].getHidden())
1924 if (hiddenSeqs == null)
1926 hiddenSeqs = new Vector();
1929 hiddenSeqs.addElement(seqRefIds
1936 // Create the alignment object from the sequence set
1937 // ///////////////////////////////
1938 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
1941 tmpseqs.toArray(orderedSeqs);
1943 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
1946 // / Add the alignment properties
1947 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
1949 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
1950 al.setProperty(ssp.getKey(), ssp.getValue());
1954 // SequenceFeatures are added to the DatasetSequence,
1955 // so we must create or recover the dataset before loading features
1956 // ///////////////////////////////
1957 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
1959 // older jalview projects do not have a dataset id.
1960 al.setDataset(null);
1964 recoverDatasetFor(vamsasSet, al);
1966 // ///////////////////////////////
1968 Hashtable pdbloaded = new Hashtable();
1971 // load sequence features, database references and any associated PDB
1972 // structures for the alignment
1973 for (int i = 0; i < vamsasSeq.length; i++)
1975 if (JSEQ[i].getFeaturesCount() > 0)
1977 Features[] features = JSEQ[i].getFeatures();
1978 for (int f = 0; f < features.length; f++)
1980 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
1981 features[f].getType(), features[f].getDescription(),
1982 features[f].getStatus(), features[f].getBegin(),
1983 features[f].getEnd(), features[f].getFeatureGroup());
1985 sf.setScore(features[f].getScore());
1986 for (int od = 0; od < features[f].getOtherDataCount(); od++)
1988 OtherData keyValue = features[f].getOtherData(od);
1989 if (keyValue.getKey().startsWith("LINK"))
1991 sf.addLink(keyValue.getValue());
1995 sf.setValue(keyValue.getKey(), keyValue.getValue());
2000 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2003 if (vamsasSeq[i].getDBRefCount() > 0)
2005 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2007 if (JSEQ[i].getPdbidsCount() > 0)
2009 Pdbids[] ids = JSEQ[i].getPdbids();
2010 for (int p = 0; p < ids.length; p++)
2012 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2013 entry.setId(ids[p].getId());
2014 entry.setType(ids[p].getType());
2015 if (ids[p].getFile() != null)
2017 if (!pdbloaded.containsKey(ids[p].getFile()))
2019 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2023 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2027 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2031 } // end !multipleview
2033 // ///////////////////////////////
2034 // LOAD SEQUENCE MAPPINGS
2036 if (vamsasSet.getAlcodonFrameCount() > 0)
2038 // TODO Potentially this should only be done once for all views of an
2040 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2041 for (int i = 0; i < alc.length; i++)
2043 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2044 alc[i].getAlcodonCount());
2045 if (alc[i].getAlcodonCount() > 0)
2047 Alcodon[] alcods = alc[i].getAlcodon();
2048 for (int p = 0; p < cf.codons.length; p++)
2050 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2051 && alcods[p].hasPos3())
2053 // translated codons require three valid positions
2054 cf.codons[p] = new int[3];
2055 cf.codons[p][0] = (int) alcods[p].getPos1();
2056 cf.codons[p][1] = (int) alcods[p].getPos2();
2057 cf.codons[p][2] = (int) alcods[p].getPos3();
2061 cf.codons[p] = null;
2065 if (alc[i].getAlcodMapCount() > 0)
2067 AlcodMap[] maps = alc[i].getAlcodMap();
2068 for (int m = 0; m < maps.length; m++)
2070 SequenceI dnaseq = (SequenceI) seqRefIds
2071 .get(maps[m].getDnasq());
2073 jalview.datamodel.Mapping mapping = null;
2074 // attach to dna sequence reference.
2075 if (maps[m].getMapping() != null)
2077 mapping = addMapping(maps[m].getMapping());
2081 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2086 frefedSequence.add(new Object[]
2087 { maps[m].getDnasq(), cf, mapping });
2091 al.addCodonFrame(cf);
2096 // ////////////////////////////////
2098 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2100 * store any annotations which forward reference a group's ID
2102 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2104 if (vamsasSet.getAnnotationCount() > 0)
2106 Annotation[] an = vamsasSet.getAnnotation();
2108 for (int i = 0; i < an.length; i++)
2111 * test if annotation is automatically calculated for this view only
2113 boolean autoForView = false;
2114 if (an[i].getLabel().equals("Quality")
2115 || an[i].getLabel().equals("Conservation")
2116 || an[i].getLabel().equals("Consensus"))
2118 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2120 if (!an[i].hasAutoCalculated())
2122 an[i].setAutoCalculated(true);
2126 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2128 // remove ID - we don't recover annotation from other views for
2129 // view-specific annotation
2133 // set visiblity for other annotation in this view
2134 if (an[i].getId() != null
2135 && annotationIds.containsKey(an[i].getId()))
2137 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2138 .get(an[i].getId());
2139 // in principle Visible should always be true for annotation displayed
2140 // in multiple views
2141 if (an[i].hasVisible())
2142 jda.visible = an[i].getVisible();
2144 al.addAnnotation(jda);
2148 // Construct new annotation from model.
2149 AnnotationElement[] ae = an[i].getAnnotationElement();
2150 jalview.datamodel.Annotation[] anot = null;
2152 if (!an[i].getScoreOnly())
2154 anot = new jalview.datamodel.Annotation[al.getWidth()];
2155 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2157 if (ae[aa].getPosition() >= anot.length)
2160 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2162 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2163 (ae[aa].getSecondaryStructure() == null || ae[aa]
2164 .getSecondaryStructure().length() == 0) ? ' '
2165 : ae[aa].getSecondaryStructure().charAt(0),
2169 // JBPNote: Consider verifying dataflow for IO of secondary
2170 // structure annotation read from Stockholm files
2171 // this was added to try to ensure that
2172 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2174 // anot[ae[aa].getPosition()].displayCharacter = "";
2176 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2177 ae[aa].getColour());
2180 jalview.datamodel.AlignmentAnnotation jaa = null;
2182 if (an[i].getGraph())
2184 float llim = 0, hlim = 0;
2185 // if (autoForView || an[i].isAutoCalculated()) {
2188 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2189 an[i].getDescription(), anot, llim, hlim,
2190 an[i].getGraphType());
2192 jaa.graphGroup = an[i].getGraphGroup();
2194 if (an[i].getThresholdLine() != null)
2196 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2197 .getThresholdLine().getValue(), an[i]
2198 .getThresholdLine().getLabel(), new java.awt.Color(
2199 an[i].getThresholdLine().getColour())));
2202 if (autoForView || an[i].isAutoCalculated())
2204 // Hardwire the symbol display line to ensure that labels for
2205 // histograms are displayed
2211 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2212 an[i].getDescription(), anot);
2216 // register new annotation
2217 if (an[i].getId() != null)
2219 annotationIds.put(an[i].getId(), jaa);
2220 jaa.annotationId = an[i].getId();
2222 // recover sequence association
2223 if (an[i].getSequenceRef() != null)
2225 if (al.findName(an[i].getSequenceRef()) != null)
2227 jaa.createSequenceMapping(
2228 al.findName(an[i].getSequenceRef()), 1, true);
2229 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
2234 // and make a note of any group association
2235 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2237 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2238 .get(an[i].getGroupRef());
2241 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2242 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2247 if (an[i].hasScore())
2249 jaa.setScore(an[i].getScore());
2251 if (an[i].hasVisible())
2252 jaa.visible = an[i].getVisible();
2254 if (an[i].hasCentreColLabels())
2255 jaa.centreColLabels = an[i].getCentreColLabels();
2257 if (an[i].hasScaleColLabels())
2259 jaa.scaleColLabel = an[i].getScaleColLabels();
2261 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2263 // newer files have an 'autoCalculated' flag and store calculation
2264 // state in viewport properties
2265 jaa.autoCalculated = true; // means annotation will be marked for
2266 // update at end of load.
2268 if (an[i].hasGraphHeight())
2270 jaa.graphHeight = an[i].getGraphHeight();
2272 if (an[i].hasBelowAlignment())
2274 jaa.belowAlignment=an[i].isBelowAlignment();
2276 jaa.setCalcId(an[i].getCalcId());
2278 if (jaa.autoCalculated)
2280 autoAlan.add(new JvAnnotRow(i, jaa));
2283 // if (!autoForView)
2285 // add autocalculated group annotation and any user created annotation
2287 al.addAnnotation(jaa);
2292 // ///////////////////////
2294 // Create alignment markup and styles for this view
2295 if (jms.getJGroupCount() > 0)
2297 JGroup[] groups = jms.getJGroup();
2299 for (int i = 0; i < groups.length; i++)
2301 ColourSchemeI cs = null;
2303 if (groups[i].getColour() != null)
2305 if (groups[i].getColour().startsWith("ucs"))
2307 cs = GetUserColourScheme(jms, groups[i].getColour());
2311 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2316 cs.setThreshold(groups[i].getPidThreshold(), true);
2320 Vector seqs = new Vector();
2322 for (int s = 0; s < groups[i].getSeqCount(); s++)
2324 String seqId = groups[i].getSeq(s) + "";
2325 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2330 seqs.addElement(ts);
2334 if (seqs.size() < 1)
2339 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2340 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2341 groups[i].getDisplayText(), groups[i].getColourText(),
2342 groups[i].getStart(), groups[i].getEnd());
2344 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2346 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2347 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2348 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2349 .isShowUnconserved() : false);
2350 sg.thresholdTextColour = groups[i].getTextColThreshold();
2351 if (groups[i].hasShowConsensusHistogram())
2353 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2356 if (groups[i].hasShowSequenceLogo())
2358 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2360 if (groups[i].hasIgnoreGapsinConsensus())
2362 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2364 if (groups[i].getConsThreshold() != 0)
2366 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2367 "All", ResidueProperties.propHash, 3,
2368 sg.getSequences(null), 0, sg.getWidth() - 1);
2370 c.verdict(false, 25);
2371 sg.cs.setConservation(c);
2374 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2376 // re-instate unique group/annotation row reference
2377 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2378 .get(groups[i].getId());
2381 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2384 if (jaa.autoCalculated)
2386 // match up and try to set group autocalc alignment row for this
2388 if (jaa.label.startsWith("Consensus for "))
2390 sg.setConsensus(jaa);
2392 // match up and try to set group autocalc alignment row for this
2394 if (jaa.label.startsWith("Conservation for "))
2396 sg.setConservationRow(jaa);
2407 // ///////////////////////////////
2410 // If we just load in the same jar file again, the sequenceSetId
2411 // will be the same, and we end up with multiple references
2412 // to the same sequenceSet. We must modify this id on load
2413 // so that each load of the file gives a unique id
2414 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2415 String viewId = (view.getId() == null ? null : view.getId()
2417 AlignFrame af = null;
2418 AlignViewport av = null;
2419 // now check to see if we really need to create a new viewport.
2420 if (multipleView && viewportsAdded.size() == 0)
2422 // We recovered an alignment for which a viewport already exists.
2423 // TODO: fix up any settings necessary for overlaying stored state onto
2424 // state recovered from another document. (may not be necessary).
2425 // we may need a binding from a viewport in memory to one recovered from
2427 // and then recover its containing af to allow the settings to be applied.
2428 // TODO: fix for vamsas demo
2430 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2432 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2433 if (seqsetobj != null)
2435 if (seqsetobj instanceof String)
2437 uniqueSeqSetId = (String) seqsetobj;
2439 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2445 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2450 AlignmentPanel ap = null;
2451 boolean isnewview = true;
2454 // Check to see if this alignment already has a view id == viewId
2455 jalview.gui.AlignmentPanel views[] = Desktop
2456 .getAlignmentPanels(uniqueSeqSetId);
2457 if (views != null && views.length > 0)
2459 for (int v = 0; v < views.length; v++)
2461 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2463 // recover the existing alignpanel, alignframe, viewport
2464 af = views[v].alignFrame;
2467 // TODO: could even skip resetting view settings if we don't want to
2468 // change the local settings from other jalview processes
2477 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2478 uniqueSeqSetId, viewId, autoAlan);
2483 // /////////////////////////////////////
2484 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2488 for (int t = 0; t < jms.getTreeCount(); t++)
2491 Tree tree = jms.getTree(t);
2493 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2496 tp = af.ShowNewickTree(
2497 new jalview.io.NewickFile(tree.getNewick()),
2498 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2499 tree.getXpos(), tree.getYpos());
2500 if (tree.getId() != null)
2502 // perhaps bind the tree id to something ?
2507 // update local tree attributes ?
2508 // TODO: should check if tp has been manipulated by user - if so its
2509 // settings shouldn't be modified
2510 tp.setTitle(tree.getTitle());
2511 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2512 .getWidth(), tree.getHeight()));
2513 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2516 tp.treeCanvas.av = av; // af.viewport;
2517 tp.treeCanvas.ap = ap; // af.alignPanel;
2522 warn("There was a problem recovering stored Newick tree: \n"
2523 + tree.getNewick());
2527 tp.fitToWindow.setState(tree.getFitToWindow());
2528 tp.fitToWindow_actionPerformed(null);
2530 if (tree.getFontName() != null)
2532 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2533 .getFontStyle(), tree.getFontSize()));
2537 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2538 .getFontStyle(), tree.getFontSize()));
2541 tp.showPlaceholders(tree.getMarkUnlinked());
2542 tp.showBootstrap(tree.getShowBootstrap());
2543 tp.showDistances(tree.getShowDistances());
2545 tp.treeCanvas.threshold = tree.getThreshold();
2547 if (tree.getCurrentTree())
2549 af.viewport.setCurrentTree(tp.getTree());
2553 } catch (Exception ex)
2555 ex.printStackTrace();
2559 // //LOAD STRUCTURES
2560 if (loadTreesAndStructures)
2562 // run through all PDB ids on the alignment, and collect mappings between
2563 // jmol view ids and all sequences referring to it
2564 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2566 for (int i = 0; i < JSEQ.length; i++)
2568 if (JSEQ[i].getPdbidsCount() > 0)
2570 Pdbids[] ids = JSEQ[i].getPdbids();
2571 for (int p = 0; p < ids.length; p++)
2573 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2575 // check to see if we haven't already created this structure view
2576 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2577 : ids[p].getStructureState(s).getViewId()
2579 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2580 // Originally : ids[p].getFile()
2581 // : TODO: verify external PDB file recovery still works in normal
2582 // jalview project load
2583 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2584 jpdb.setId(ids[p].getId());
2586 int x = ids[p].getStructureState(s).getXpos();
2587 int y = ids[p].getStructureState(s).getYpos();
2588 int width = ids[p].getStructureState(s).getWidth();
2589 int height = ids[p].getStructureState(s).getHeight();
2591 // Probably don't need to do this anymore...
2592 // Desktop.desktop.getComponentAt(x, y);
2593 // TODO: NOW: check that this recovers the PDB file correctly.
2594 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2595 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2596 .get(JSEQ[i].getId() + "");
2597 if (sviewid == null)
2599 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2602 if (!jmolViewIds.containsKey(sviewid))
2604 jmolViewIds.put(sviewid, new Object[]
2606 { x, y, width, height }, "",
2607 new Hashtable<String, Object[]>(), new boolean[]
2608 { false, false, true } });
2609 // Legacy pre-2.7 conversion JAL-823 :
2610 // do not assume any view has to be linked for colour by
2614 // assemble String[] { pdb files }, String[] { id for each
2615 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2616 // seqs_file 2}, boolean[] {
2617 // linkAlignPanel,superposeWithAlignpanel}} from hash
2618 Object[] jmoldat = jmolViewIds.get(sviewid);
2619 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2620 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2621 s).getAlignwithAlignPanel() : false;
2622 // never colour by linked panel if not specified
2623 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2624 .hasColourwithAlignPanel() ? ids[p]
2625 .getStructureState(s).getColourwithAlignPanel()
2627 // default for pre-2.7 projects is that Jmol colouring is enabled
2628 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2629 .hasColourByJmol() ? ids[p].getStructureState(s)
2630 .getColourByJmol() : true;
2632 if (((String) jmoldat[1]).length() < ids[p]
2633 .getStructureState(s).getContent().length())
2636 jmoldat[1] = ids[p].getStructureState(s).getContent();
2639 if (ids[p].getFile() != null)
2641 File mapkey=new File(ids[p].getFile());
2642 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2644 if (seqstrmaps == null)
2646 ((Hashtable) jmoldat[2]).put(
2648 seqstrmaps = new Object[]
2649 { pdbFile, ids[p].getId(), new Vector(),
2652 if (!((Vector) seqstrmaps[2]).contains(seq))
2654 ((Vector) seqstrmaps[2]).addElement(seq);
2655 // ((Vector)seqstrmaps[3]).addElement(n) :
2656 // in principle, chains
2657 // should be stored here : do we need to
2658 // TODO: store and recover seq/pdb_id :
2664 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");
2673 // Instantiate the associated Jmol views
2674 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2676 String sviewid = entry.getKey();
2677 Object[] svattrib = entry.getValue();
2678 int[] geom = (int[]) svattrib[0];
2679 String state = (String) svattrib[1];
2680 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2681 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2682 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2683 // collate the pdbfile -> sequence mappings from this view
2684 Vector<String> pdbfilenames = new Vector<String>();
2685 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2686 Vector<String> pdbids = new Vector<String>();
2688 // Search to see if we've already created this Jmol view
2689 AppJmol comp = null;
2690 JInternalFrame[] frames = null;
2695 frames = Desktop.desktop.getAllFrames();
2696 } catch (ArrayIndexOutOfBoundsException e)
2698 // occasional No such child exceptions are thrown here...
2703 } catch (Exception f)
2708 } while (frames == null);
2709 // search for any Jmol windows already open from other
2710 // alignment views that exactly match the stored structure state
2711 for (int f = 0; comp == null && f < frames.length; f++)
2713 if (frames[f] instanceof AppJmol)
2716 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2718 // post jalview 2.4 schema includes structure view id
2719 comp = (AppJmol) frames[f];
2721 else if (frames[f].getX() == x && frames[f].getY() == y
2722 && frames[f].getHeight() == height
2723 && frames[f].getWidth() == width)
2725 comp = (AppJmol) frames[f];
2732 // create a new Jmol window.
2733 // First parse the Jmol state to translate filenames loaded into the
2734 // view, and record the order in which files are shown in the Jmol
2735 // view, so we can add the sequence mappings in same order.
2736 StringBuffer newFileLoc = null;
2737 int cp = 0, ncp, ecp;
2738 while ((ncp = state.indexOf("load ", cp)) > -1)
2740 if (newFileLoc == null)
2742 newFileLoc = new StringBuffer();
2745 // look for next filename in load statement
2746 newFileLoc.append(state.substring(cp,
2747 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2748 String oldfilenam = state.substring(ncp,
2749 ecp = state.indexOf("\"", ncp));
2750 // recover the new mapping data for this old filename
2751 // have to normalize filename - since Jmol and jalview do filename
2752 // translation differently.
2753 Object[] filedat = oldFiles.get(new File(oldfilenam));
2754 newFileLoc.append(Platform.escapeString((String) filedat[0]));
2755 pdbfilenames.addElement((String) filedat[0]);
2756 pdbids.addElement((String) filedat[1]);
2757 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2758 .toArray(new SequenceI[0]));
2759 newFileLoc.append("\"");
2760 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2761 // look for next file statement.
2762 } while ((ncp=state.indexOf("/*file*/",cp))>-1);
2766 // just append rest of state
2767 newFileLoc.append(state.substring(cp));
2772 .print("Ignoring incomplete Jmol state for PDB ids: ");
2773 newFileLoc = new StringBuffer(state);
2774 newFileLoc.append("; load append ");
2775 for (File id : oldFiles.keySet())
2777 // add this and any other pdb files that should be present in
2779 Object[] filedat = oldFiles.get(id);
2781 newFileLoc.append(((String) filedat[0]));
2782 pdbfilenames.addElement((String) filedat[0]);
2783 pdbids.addElement((String) filedat[1]);
2784 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2785 .toArray(new SequenceI[0]));
2786 newFileLoc.append(" \"");
2787 newFileLoc.append((String) filedat[0]);
2788 newFileLoc.append("\"");
2791 newFileLoc.append(";");
2794 if (newFileLoc != null)
2796 int histbug = newFileLoc.indexOf("history = ");
2798 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2800 String val = (diff == -1) ? null : newFileLoc.substring(
2802 if (val != null && val.length() >= 4)
2804 if (val.contains("e"))
2806 if (val.trim().equals("true"))
2814 newFileLoc.replace(histbug, diff, val);
2817 // TODO: assemble String[] { pdb files }, String[] { id for each
2818 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2819 // seqs_file 2}} from hash
2820 final String[] pdbf = pdbfilenames
2821 .toArray(new String[pdbfilenames.size()]), id = pdbids
2822 .toArray(new String[pdbids.size()]);
2823 final SequenceI[][] sq = seqmaps
2824 .toArray(new SequenceI[seqmaps.size()][]);
2825 final String fileloc = newFileLoc.toString(), vid = sviewid;
2826 final AlignFrame alf = af;
2827 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2831 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2836 AppJmol sview = null;
2839 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2840 useinJmolsuperpos, usetoColourbyseq,
2841 jmolColouring, fileloc, rect, vid);
2842 } catch (OutOfMemoryError ex)
2844 new OOMWarning("restoring structure view for PDB id "
2845 + id, (OutOfMemoryError) ex.getCause());
2846 if (sview != null && sview.isVisible())
2848 sview.closeViewer();
2849 sview.setVisible(false);
2855 } catch (InvocationTargetException ex)
2857 warn("Unexpected error when opening Jmol view.", ex);
2859 } catch (InterruptedException e)
2861 // e.printStackTrace();
2867 // if (comp != null)
2869 // NOTE: if the jalview project is part of a shared session then
2870 // view synchronization should/could be done here.
2872 // add mapping for sequences in this view to an already open Jmol
2874 for (File id : oldFiles.keySet())
2876 // add this and any other pdb files that should be present in the
2878 Object[] filedat = oldFiles.get(id);
2879 String pdbFile = (String) filedat[0];
2880 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
2881 .toArray(new SequenceI[0]);
2882 comp.jmb.ssm.setMapping(seq, null, pdbFile,
2883 jalview.io.AppletFormatAdapter.FILE);
2884 comp.jmb.addSequenceForStructFile(pdbFile, seq);
2886 // and add the AlignmentPanel's reference to the Jmol view
2887 comp.addAlignmentPanel(ap);
2888 if (useinJmolsuperpos)
2890 comp.useAlignmentPanelForSuperposition(ap);
2894 comp.excludeAlignmentPanelForSuperposition(ap);
2896 if (usetoColourbyseq)
2898 comp.useAlignmentPanelForColourbyseq(ap,
2903 comp.excludeAlignmentPanelForColourbyseq(ap);
2909 // and finally return.
2913 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
2914 Alignment al, JalviewModelSequence jms, Viewport view,
2915 String uniqueSeqSetId, String viewId,
2916 ArrayList<JvAnnotRow> autoAlan)
2918 AlignFrame af = null;
2919 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
2920 uniqueSeqSetId, viewId);
2922 af.setFileName(file, "Jalview");
2924 for (int i = 0; i < JSEQ.length; i++)
2926 af.viewport.setSequenceColour(af.viewport.getAlignment().getSequenceAt(i),
2927 new java.awt.Color(JSEQ[i].getColour()));
2930 af.viewport.gatherViewsHere = view.getGatheredViews();
2932 if (view.getSequenceSetId() != null)
2934 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
2935 .get(uniqueSeqSetId);
2937 af.viewport.setSequenceSetId(uniqueSeqSetId);
2940 // propagate shared settings to this new view
2941 af.viewport.historyList = av.historyList;
2942 af.viewport.redoList = av.redoList;
2946 viewportsAdded.put(uniqueSeqSetId, af.viewport);
2948 // TODO: check if this method can be called repeatedly without
2949 // side-effects if alignpanel already registered.
2950 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
2952 // apply Hidden regions to view.
2953 if (hiddenSeqs != null)
2955 for (int s = 0; s < JSEQ.length; s++)
2957 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
2959 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
2962 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
2964 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
2967 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
2970 for (int s = 0; s < hiddenSeqs.size(); s++)
2972 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
2975 af.viewport.hideSequence(hseqs);
2978 // recover view properties and display parameters
2979 if (view.getViewName() != null)
2981 af.viewport.viewName = view.getViewName();
2982 af.setInitialTabVisible();
2984 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
2987 af.viewport.setShowAnnotation(view.getShowAnnotation());
2988 af.viewport.setAbovePIDThreshold(view.getPidSelected());
2990 af.viewport.setColourText(view.getShowColourText());
2992 af.viewport.setConservationSelected(view.getConservationSelected());
2993 af.viewport.setShowJVSuffix(view.getShowFullId());
2994 af.viewport.rightAlignIds = view.getRightAlignIds();
2995 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
2996 .getFontStyle(), view.getFontSize()));
2997 af.alignPanel.fontChanged();
2998 af.viewport.setRenderGaps(view.getRenderGaps());
2999 af.viewport.setWrapAlignment(view.getWrapAlignment());
3000 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3001 af.viewport.setShowAnnotation(view.getShowAnnotation());
3002 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3004 af.viewport.setShowBoxes(view.getShowBoxes());
3006 af.viewport.setShowText(view.getShowText());
3008 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3009 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3010 af.viewport.thresholdTextColour = view.getTextColThreshold();
3011 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3012 .isShowUnconserved() : false);
3013 af.viewport.setStartRes(view.getStartRes());
3014 af.viewport.setStartSeq(view.getStartSeq());
3016 ColourSchemeI cs = null;
3017 // apply colourschemes
3018 if (view.getBgColour() != null)
3020 if (view.getBgColour().startsWith("ucs"))
3022 cs = GetUserColourScheme(jms, view.getBgColour());
3024 else if (view.getBgColour().startsWith("Annotation"))
3026 // int find annotation
3027 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3029 for (int i = 0; i < af.viewport.getAlignment()
3030 .getAlignmentAnnotation().length; i++)
3032 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3033 .equals(view.getAnnotationColours().getAnnotation()))
3035 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3036 .getThreshold() == null)
3038 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3039 .setThreshold(new jalview.datamodel.GraphLine(view
3040 .getAnnotationColours().getThreshold(),
3041 "Threshold", java.awt.Color.black)
3046 if (view.getAnnotationColours().getColourScheme()
3049 cs = new AnnotationColourGradient(
3050 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3051 new java.awt.Color(view.getAnnotationColours()
3052 .getMinColour()), new java.awt.Color(view
3053 .getAnnotationColours().getMaxColour()),
3054 view.getAnnotationColours().getAboveThreshold());
3056 else if (view.getAnnotationColours().getColourScheme()
3059 cs = new AnnotationColourGradient(
3060 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3061 GetUserColourScheme(jms, view
3062 .getAnnotationColours().getColourScheme()),
3063 view.getAnnotationColours().getAboveThreshold());
3067 cs = new AnnotationColourGradient(
3068 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3069 ColourSchemeProperty.getColour(al, view
3070 .getAnnotationColours().getColourScheme()),
3071 view.getAnnotationColours().getAboveThreshold());
3074 // Also use these settings for all the groups
3075 if (al.getGroups() != null)
3077 for (int g = 0; g < al.getGroups().size(); g++)
3079 jalview.datamodel.SequenceGroup sg = al
3080 .getGroups().get(g);
3089 * (view.getAnnotationColours().getColourScheme().equals("None"
3090 * )) { sg.cs = new AnnotationColourGradient(
3091 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3092 * java.awt.Color(view.getAnnotationColours().
3093 * getMinColour()), new
3094 * java.awt.Color(view.getAnnotationColours().
3096 * view.getAnnotationColours().getAboveThreshold()); } else
3099 sg.cs = new AnnotationColourGradient(
3100 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3101 sg.cs, view.getAnnotationColours()
3102 .getAboveThreshold());
3116 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3121 cs.setThreshold(view.getPidThreshold(), true);
3122 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3126 af.viewport.setGlobalColourScheme(cs);
3127 af.viewport.setColourAppliesToAllGroups(false);
3129 if (view.getConservationSelected() && cs != null)
3131 cs.setConservationInc(view.getConsThreshold());
3134 af.changeColour(cs);
3136 af.viewport.setColourAppliesToAllGroups(true);
3138 if (view.getShowSequenceFeatures())
3140 af.viewport.showSequenceFeatures = true;
3142 if (view.hasCentreColumnLabels())
3144 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3146 if (view.hasIgnoreGapsinConsensus())
3148 af.viewport.setIgnoreGapsConsensus(view
3149 .getIgnoreGapsinConsensus(), null);
3151 if (view.hasFollowHighlight())
3153 af.viewport.followHighlight = view.getFollowHighlight();
3155 if (view.hasFollowSelection())
3157 af.viewport.followSelection = view.getFollowSelection();
3159 if (view.hasShowConsensusHistogram())
3161 af.viewport.setShowConsensusHistogram(view
3162 .getShowConsensusHistogram());
3166 af.viewport.setShowConsensusHistogram(true);
3168 if (view.hasShowSequenceLogo())
3170 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3174 af.viewport.setShowSequenceLogo(false);
3176 if (view.hasShowDbRefTooltip())
3178 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3180 if (view.hasShowNPfeatureTooltip())
3182 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3184 if (view.hasShowGroupConsensus())
3186 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3190 af.viewport.setShowGroupConsensus(false);
3192 if (view.hasShowGroupConservation())
3194 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3198 af.viewport.setShowGroupConservation(false);
3201 // recover featre settings
3202 if (jms.getFeatureSettings() != null)
3204 af.viewport.featuresDisplayed = new Hashtable();
3205 String[] renderOrder = new String[jms.getFeatureSettings()
3206 .getSettingCount()];
3207 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3209 Setting setting = jms.getFeatureSettings().getSetting(fs);
3210 if (setting.hasMincolour())
3212 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3213 new java.awt.Color(setting.getMincolour()),
3214 new java.awt.Color(setting.getColour()),
3215 setting.getMin(), setting.getMax()) : new GraduatedColor(
3216 new java.awt.Color(setting.getMincolour()),
3217 new java.awt.Color(setting.getColour()), 0, 1);
3218 if (setting.hasThreshold())
3220 gc.setThresh(setting.getThreshold());
3221 gc.setThreshType(setting.getThreshstate());
3223 gc.setAutoScaled(true); // default
3224 if (setting.hasAutoScale())
3226 gc.setAutoScaled(setting.getAutoScale());
3228 if (setting.hasColourByLabel())
3230 gc.setColourByLabel(setting.getColourByLabel());
3232 // and put in the feature colour table.
3233 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3234 setting.getType(), gc);
3238 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3240 new java.awt.Color(setting.getColour()));
3242 renderOrder[fs] = setting.getType();
3243 if (setting.hasOrder())
3244 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3245 setting.getType(), setting.getOrder());
3247 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3249 fs / jms.getFeatureSettings().getSettingCount());
3250 if (setting.getDisplay())
3252 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3253 setting.getColour()));
3256 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3258 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3259 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3261 Group grp = jms.getFeatureSettings().getGroup(gs);
3262 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3266 if (view.getHiddenColumnsCount() > 0)
3268 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3270 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3271 .getHiddenColumns(c).getEnd() // +1
3276 af.setMenusFromViewport(af.viewport);
3277 // TODO: we don't need to do this if the viewport is aready visible.
3278 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3280 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3281 reorderAutoannotation(af, al, autoAlan);
3285 private void reorderAutoannotation(AlignFrame af, Alignment al,
3286 ArrayList<JvAnnotRow> autoAlan)
3288 // copy over visualization settings for autocalculated annotation in the
3290 if (al.getAlignmentAnnotation() != null)
3293 * Kludge for magic autoannotation names (see JAL-811)
3295 String[] magicNames = new String[]
3296 { "Consensus", "Quality", "Conservation" };
3297 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3298 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3299 for (String nm : magicNames)
3301 visan.put(nm, nullAnnot);
3303 for (JvAnnotRow auan : autoAlan)
3305 visan.put(auan.template.label, auan);
3307 int hSize = al.getAlignmentAnnotation().length;
3308 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3309 for (int h = 0; h < hSize; h++)
3311 jalview.datamodel.AlignmentAnnotation jalan = al
3312 .getAlignmentAnnotation()[h];
3313 if (jalan.autoCalculated)
3315 JvAnnotRow valan = visan.get(jalan.label);
3318 // delete the auto calculated row from the alignment
3319 al.deleteAnnotation(al.getAlignmentAnnotation()[h], false);
3322 if (valan != nullAnnot)
3324 if (jalan != valan.template)
3326 // newly created autoannotation row instance
3327 // so keep a reference to the visible annotation row
3328 // and copy over all relevant attributes
3329 if (valan.template.graphHeight >= 0)
3332 jalan.graphHeight = valan.template.graphHeight;
3334 jalan.visible = valan.template.visible;
3336 reorder.add(new JvAnnotRow(valan.order, jalan));
3341 int s = 0, srt[] = new int[reorder.size()];
3342 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3343 for (JvAnnotRow jvar : reorder)
3346 srt[s++] = jvar.order;
3349 jalview.util.QuickSort.sort(srt, rws);
3350 // and re-insert the annotation at its correct position
3351 for (JvAnnotRow jvar : rws)
3353 al.addAnnotation(jvar.template, jvar.order);
3355 af.alignPanel.adjustAnnotationHeight();
3359 Hashtable skipList = null;
3362 * TODO remove this method
3365 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3366 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3367 * throw new Error("Implementation Error. No skipList defined for this
3368 * Jalview2XML instance."); } return (AlignFrame)
3369 * skipList.get(view.getSequenceSetId()); }
3373 * Check if the Jalview view contained in object should be skipped or not.
3376 * @return true if view's sequenceSetId is a key in skipList
3378 private boolean skipViewport(JalviewModel object)
3380 if (skipList == null)
3385 if (skipList.containsKey(id = object.getJalviewModelSequence()
3386 .getViewport()[0].getSequenceSetId()))
3388 if (Cache.log != null && Cache.log.isDebugEnabled())
3390 Cache.log.debug("Skipping seuqence set id " + id);
3397 public void AddToSkipList(AlignFrame af)
3399 if (skipList == null)
3401 skipList = new Hashtable();
3403 skipList.put(af.getViewport().getSequenceSetId(), af);
3406 public void clearSkipList()
3408 if (skipList != null)
3415 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3417 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3418 Vector dseqs = null;
3421 // create a list of new dataset sequences
3422 dseqs = new Vector();
3424 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3426 Sequence vamsasSeq = vamsasSet.getSequence(i);
3427 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3429 // create a new dataset
3432 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3433 dseqs.copyInto(dsseqs);
3434 ds = new jalview.datamodel.Alignment(dsseqs);
3435 debug("Created new dataset " + vamsasSet.getDatasetId()
3436 + " for alignment " + System.identityHashCode(al));
3437 addDatasetRef(vamsasSet.getDatasetId(), ds);
3439 // set the dataset for the newly imported alignment.
3440 if (al.getDataset() == null)
3449 * sequence definition to create/merge dataset sequence for
3453 * vector to add new dataset sequence to
3455 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3456 AlignmentI ds, Vector dseqs)
3458 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3460 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3461 .get(vamsasSeq.getId());
3462 jalview.datamodel.SequenceI dsq = null;
3463 if (sq != null && sq.getDatasetSequence() != null)
3465 dsq = sq.getDatasetSequence();
3468 String sqid = vamsasSeq.getDsseqid();
3471 // need to create or add a new dataset sequence reference to this sequence
3474 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3479 // make a new dataset sequence
3480 dsq = sq.createDatasetSequence();
3483 // make up a new dataset reference for this sequence
3484 sqid = seqHash(dsq);
3486 dsq.setVamsasId(uniqueSetSuffix + sqid);
3487 seqRefIds.put(sqid, dsq);
3492 dseqs.addElement(dsq);
3497 ds.addSequence(dsq);
3503 { // make this dataset sequence sq's dataset sequence
3504 sq.setDatasetSequence(dsq);
3508 // TODO: refactor this as a merge dataset sequence function
3509 // now check that sq (the dataset sequence) sequence really is the union of
3510 // all references to it
3511 // boolean pre = sq.getStart() < dsq.getStart();
3512 // boolean post = sq.getEnd() > dsq.getEnd();
3516 StringBuffer sb = new StringBuffer();
3517 String newres = jalview.analysis.AlignSeq.extractGaps(
3518 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3519 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3520 && newres.length() > dsq.getLength())
3522 // Update with the longer sequence.
3526 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3527 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3528 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3529 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3531 dsq.setSequence(sb.toString());
3533 // TODO: merges will never happen if we 'know' we have the real dataset
3534 // sequence - this should be detected when id==dssid
3535 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3536 // + (pre ? "prepended" : "") + " "
3537 // + (post ? "appended" : ""));
3542 java.util.Hashtable datasetIds = null;
3544 java.util.IdentityHashMap dataset2Ids = null;
3546 private Alignment getDatasetFor(String datasetId)
3548 if (datasetIds == null)
3550 datasetIds = new Hashtable();
3553 if (datasetIds.containsKey(datasetId))
3555 return (Alignment) datasetIds.get(datasetId);
3560 private void addDatasetRef(String datasetId, Alignment dataset)
3562 if (datasetIds == null)
3564 datasetIds = new Hashtable();
3566 datasetIds.put(datasetId, dataset);
3570 * make a new dataset ID for this jalview dataset alignment
3575 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3577 if (dataset.getDataset() != null)
3579 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3581 String datasetId = makeHashCode(dataset, null);
3582 if (datasetId == null)
3584 // make a new datasetId and record it
3585 if (dataset2Ids == null)
3587 dataset2Ids = new IdentityHashMap();
3591 datasetId = (String) dataset2Ids.get(dataset);
3593 if (datasetId == null)
3595 datasetId = "ds" + dataset2Ids.size() + 1;
3596 dataset2Ids.put(dataset, datasetId);
3602 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3604 for (int d = 0; d < sequence.getDBRefCount(); d++)
3606 DBRef dr = sequence.getDBRef(d);
3607 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3608 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3609 .getVersion(), sequence.getDBRef(d).getAccessionId());
3610 if (dr.getMapping() != null)
3612 entry.setMap(addMapping(dr.getMapping()));
3614 datasetSequence.addDBRef(entry);
3618 private jalview.datamodel.Mapping addMapping(Mapping m)
3620 SequenceI dsto = null;
3621 // Mapping m = dr.getMapping();
3622 int fr[] = new int[m.getMapListFromCount() * 2];
3623 Enumeration f = m.enumerateMapListFrom();
3624 for (int _i = 0; f.hasMoreElements(); _i += 2)
3626 MapListFrom mf = (MapListFrom) f.nextElement();
3627 fr[_i] = mf.getStart();
3628 fr[_i + 1] = mf.getEnd();
3630 int fto[] = new int[m.getMapListToCount() * 2];
3631 f = m.enumerateMapListTo();
3632 for (int _i = 0; f.hasMoreElements(); _i += 2)
3634 MapListTo mf = (MapListTo) f.nextElement();
3635 fto[_i] = mf.getStart();
3636 fto[_i + 1] = mf.getEnd();
3638 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3639 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3640 if (m.getMappingChoice() != null)
3642 MappingChoice mc = m.getMappingChoice();
3643 if (mc.getDseqFor() != null)
3645 String dsfor = "" + mc.getDseqFor();
3646 if (seqRefIds.containsKey(dsfor))
3651 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3655 frefedSequence.add(new Object[]
3662 * local sequence definition
3664 Sequence ms = mc.getSequence();
3665 jalview.datamodel.Sequence djs = null;
3666 String sqid = ms.getDsseqid();
3667 if (sqid != null && sqid.length() > 0)
3670 * recover dataset sequence
3672 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3677 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3678 sqid = ((Object) ms).toString(); // make up a new hascode for
3679 // undefined dataset sequence hash
3680 // (unlikely to happen)
3686 * make a new dataset sequence and add it to refIds hash
3688 djs = new jalview.datamodel.Sequence(ms.getName(),
3690 djs.setStart(jmap.getMap().getToLowest());
3691 djs.setEnd(jmap.getMap().getToHighest());
3692 djs.setVamsasId(uniqueSetSuffix + sqid);
3694 seqRefIds.put(sqid, djs);
3697 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3706 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3707 boolean keepSeqRefs)
3710 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3716 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3720 uniqueSetSuffix = "";
3721 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3726 if (this.frefedSequence == null)
3728 frefedSequence = new Vector();
3731 viewportsAdded = new Hashtable();
3733 AlignFrame af = LoadFromObject(jm, null, false, null);
3734 af.alignPanels.clear();
3735 af.closeMenuItem_actionPerformed(true);
3738 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3739 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3740 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3741 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3742 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3745 return af.alignPanel;
3749 * flag indicating if hashtables should be cleared on finalization TODO this
3750 * flag may not be necessary
3752 private final boolean _cleartables = true;
3754 private Hashtable jvids2vobj;
3759 * @see java.lang.Object#finalize()
3762 protected void finalize() throws Throwable
3764 // really make sure we have no buried refs left.
3769 this.seqRefIds = null;
3770 this.seqsToIds = null;
3774 private void warn(String msg)
3779 private void warn(String msg, Exception e)
3781 if (Cache.log != null)
3785 Cache.log.warn(msg, e);
3789 Cache.log.warn(msg);
3794 System.err.println("Warning: " + msg);
3797 e.printStackTrace();
3802 private void debug(String string)
3804 debug(string, null);
3807 private void debug(String msg, Exception e)
3809 if (Cache.log != null)
3813 Cache.log.debug(msg, e);
3817 Cache.log.debug(msg);
3822 System.err.println("Warning: " + msg);
3825 e.printStackTrace();
3831 * set the object to ID mapping tables used to write/recover objects and XML
3832 * ID strings for the jalview project. If external tables are provided then
3833 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3834 * object goes out of scope. - also populates the datasetIds hashtable with
3835 * alignment objects containing dataset sequences
3838 * Map from ID strings to jalview datamodel
3840 * Map from jalview datamodel to ID strings
3844 public void setObjectMappingTables(Hashtable vobj2jv,
3845 IdentityHashMap jv2vobj)
3847 this.jv2vobj = jv2vobj;
3848 this.vobj2jv = vobj2jv;
3849 Iterator ds = jv2vobj.keySet().iterator();
3851 while (ds.hasNext())
3853 Object jvobj = ds.next();
3854 id = jv2vobj.get(jvobj).toString();
3855 if (jvobj instanceof jalview.datamodel.Alignment)
3857 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
3859 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
3862 else if (jvobj instanceof jalview.datamodel.Sequence)
3864 // register sequence object so the XML parser can recover it.
3865 if (seqRefIds == null)
3867 seqRefIds = new Hashtable();
3869 if (seqsToIds == null)
3871 seqsToIds = new IdentityHashMap();
3873 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
3874 seqsToIds.put(jvobj, id);
3876 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
3878 if (annotationIds == null)
3880 annotationIds = new Hashtable();
3883 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
3884 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
3885 if (jvann.annotationId == null)
3887 jvann.annotationId = anid;
3889 if (!jvann.annotationId.equals(anid))
3891 // TODO verify that this is the correct behaviour
3892 this.warn("Overriding Annotation ID for " + anid
3893 + " from different id : " + jvann.annotationId);
3894 jvann.annotationId = anid;
3897 else if (jvobj instanceof String)
3899 if (jvids2vobj == null)
3901 jvids2vobj = new Hashtable();
3902 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
3906 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
3911 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
3912 * objects created from the project archive. If string is null (default for
3913 * construction) then suffix will be set automatically.
3917 public void setUniqueSetSuffix(String string)
3919 uniqueSetSuffix = string;
3924 * uses skipList2 as the skipList for skipping views on sequence sets
3925 * associated with keys in the skipList
3929 public void setSkipList(Hashtable skipList2)
3931 skipList = skipList2;