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 uk.ac.vamsas.objects.utils.MapList;
33 import jalview.bin.Cache;
34 import jalview.datamodel.Alignment;
35 import jalview.datamodel.AlignmentAnnotation;
36 import jalview.datamodel.AlignmentI;
37 import jalview.datamodel.SequenceI;
38 import jalview.schemabinding.version2.*;
39 import jalview.schemes.*;
40 import jalview.structure.StructureSelectionManager;
41 import jalview.util.Platform;
42 import jalview.util.jarInputStreamProvider;
45 * Write out the current jalview desktop state as a Jalview XML stream.
47 * Note: the vamsas objects referred to here are primitive versions of the
48 * VAMSAS project schema elements - they are not the same and most likely never
52 * @version $Revision: 1.134 $
54 public class Jalview2XML
57 * create/return unique hash string for sq
60 * @return new or existing unique string for sq
62 String seqHash(SequenceI sq)
64 if (seqsToIds == null)
68 if (seqsToIds.containsKey(sq))
70 return (String) seqsToIds.get(sq);
74 // create sequential key
75 String key = "sq" + (seqsToIds.size() + 1);
76 key = makeHashCode(sq, key); // check we don't have an external reference
78 seqsToIds.put(sq, key);
87 if (seqRefIds != null)
91 if (seqsToIds != null)
101 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
102 // seqRefIds = new Hashtable();
103 // seqsToIds = new IdentityHashMap();
109 if (seqsToIds == null)
111 seqsToIds = new IdentityHashMap();
113 if (seqRefIds == null)
115 seqRefIds = new Hashtable();
120 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
121 * of sequence objects are created.
123 java.util.IdentityHashMap seqsToIds = null;
126 * jalview XML Sequence ID to jalview sequence object reference (both dataset
127 * and alignment sequences. Populated as XML reps of sequence objects are
130 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
132 Vector frefedSequence = null;
134 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
140 public Jalview2XML(boolean raiseGUI)
142 this.raiseGUI = raiseGUI;
145 public void resolveFrefedSequences()
147 if (frefedSequence.size() > 0)
149 int r = 0, rSize = frefedSequence.size();
152 Object[] ref = (Object[]) frefedSequence.elementAt(r);
155 String sref = (String) ref[0];
156 if (seqRefIds.containsKey(sref))
158 if (ref[1] instanceof jalview.datamodel.Mapping)
160 SequenceI seq = (SequenceI) seqRefIds.get(sref);
161 while (seq.getDatasetSequence() != null)
163 seq = seq.getDatasetSequence();
165 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
169 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
171 SequenceI seq = (SequenceI) seqRefIds.get(sref);
172 while (seq.getDatasetSequence() != null)
174 seq = seq.getDatasetSequence();
177 && ref[2] instanceof jalview.datamodel.Mapping)
179 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
180 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
181 seq, mp.getTo(), mp.getMap());
186 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
187 + ref[2].getClass() + " type objects.");
193 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
194 + ref[1].getClass() + " type objects.");
197 frefedSequence.remove(r);
203 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
205 + " with objecttype "
206 + ref[1].getClass());
213 frefedSequence.remove(r);
221 * This maintains a list of viewports, the key being the seqSetId. Important
222 * to set historyItem and redoList for multiple views
224 Hashtable viewportsAdded;
226 Hashtable annotationIds = new Hashtable();
228 String uniqueSetSuffix = "";
231 * List of pdbfiles added to Jar
233 Vector pdbfiles = null;
235 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
236 public void SaveState(File statefile)
240 FileOutputStream fos = new FileOutputStream(statefile);
241 JarOutputStream jout = new JarOutputStream(fos);
244 } catch (Exception e)
246 // TODO: inform user of the problem - they need to know if their data was
248 if (errorMessage == null)
250 errorMessage = "Couldn't write Jalview Archive to output file '"
251 + statefile + "' - See console error log for details";
255 errorMessage += "(output file was '" + statefile + "')";
263 * Writes a jalview project archive to the given Jar output stream.
267 public void SaveState(JarOutputStream jout)
269 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
279 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
280 // //////////////////////////////////////////////////
281 // NOTE ALSO new PrintWriter must be used for each new JarEntry
282 PrintWriter out = null;
284 Vector shortNames = new Vector();
287 for (int i = frames.length - 1; i > -1; i--)
289 if (frames[i] instanceof AlignFrame)
291 AlignFrame af = (AlignFrame) frames[i];
294 && skipList.containsKey(af.getViewport()
295 .getSequenceSetId()))
300 String shortName = af.getTitle();
302 if (shortName.indexOf(File.separatorChar) > -1)
304 shortName = shortName.substring(shortName
305 .lastIndexOf(File.separatorChar) + 1);
310 while (shortNames.contains(shortName))
312 if (shortName.endsWith("_" + (count - 1)))
314 shortName = shortName
315 .substring(0, shortName.lastIndexOf("_"));
318 shortName = shortName.concat("_" + count);
322 shortNames.addElement(shortName);
324 if (!shortName.endsWith(".xml"))
326 shortName = shortName + ".xml";
329 int ap, apSize = af.alignPanels.size();
330 for (ap = 0; ap < apSize; ap++)
332 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
334 String fileName = apSize == 1 ? shortName : ap + shortName;
335 if (!fileName.endsWith(".xml"))
337 fileName = fileName + ".xml";
340 SaveState(apanel, fileName, jout);
347 } catch (Exception foo)
352 } catch (Exception ex)
354 // TODO: inform user of the problem - they need to know if their data was
356 if (errorMessage == null)
358 errorMessage = "Couldn't write Jalview Archive - see error output for details";
360 ex.printStackTrace();
364 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
365 public boolean SaveAlignment(AlignFrame af, String jarFile,
370 int ap, apSize = af.alignPanels.size();
371 FileOutputStream fos = new FileOutputStream(jarFile);
372 JarOutputStream jout = new JarOutputStream(fos);
373 for (ap = 0; ap < apSize; ap++)
375 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
377 String jfileName = apSize == 1 ? fileName : fileName + ap;
378 if (!jfileName.endsWith(".xml"))
380 jfileName = jfileName + ".xml";
382 SaveState(apanel, jfileName, jout);
388 } catch (Exception foo)
394 } catch (Exception ex)
396 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
397 ex.printStackTrace();
403 * create a JalviewModel from an algnment view and marshall it to a
407 * panel to create jalview model for
409 * name of alignment panel written to output stream
415 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
416 JarOutputStream jout)
419 Vector jmolViewIds = new Vector(); //
420 Vector userColours = new Vector();
422 AlignViewport av = ap.av;
424 JalviewModel object = new JalviewModel();
425 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
427 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
428 object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
430 jalview.datamodel.AlignmentI jal = av.getAlignment();
432 if (av.hasHiddenRows())
434 jal = jal.getHiddenSequences().getFullAlignment();
437 SequenceSet vamsasSet = new SequenceSet();
439 JalviewModelSequence jms = new JalviewModelSequence();
441 vamsasSet.setGapChar(jal.getGapCharacter() + "");
443 if (jal.getDataset() != null)
445 // dataset id is the dataset's hashcode
446 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
448 if (jal.getProperties() != null)
450 Enumeration en = jal.getProperties().keys();
451 while (en.hasMoreElements())
453 String key = en.nextElement().toString();
454 SequenceSetProperties ssp = new SequenceSetProperties();
456 ssp.setValue(jal.getProperties().get(key).toString());
457 vamsasSet.addSequenceSetProperties(ssp);
465 jalview.datamodel.SequenceI jds;
466 for (int i = 0; i < jal.getHeight(); i++)
468 jds = jal.getSequenceAt(i);
471 if (seqRefIds.get(id) != null)
473 // This happens for two reasons: 1. multiple views are being serialised.
474 // 2. the hashCode has collided with another sequence's code. This DOES
475 // HAPPEN! (PF00072.15.stk does this)
476 // JBPNote: Uncomment to debug writing out of files that do not read
477 // back in due to ArrayOutOfBoundExceptions.
478 // System.err.println("vamsasSeq backref: "+id+"");
479 // System.err.println(jds.getName()+"
480 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
481 // System.err.println("Hashcode: "+seqHash(jds));
482 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
483 // System.err.println(rsq.getName()+"
484 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
485 // System.err.println("Hashcode: "+seqHash(rsq));
489 vamsasSeq = createVamsasSequence(id, jds);
490 vamsasSet.addSequence(vamsasSeq);
491 seqRefIds.put(id, jds);
495 jseq.setStart(jds.getStart());
496 jseq.setEnd(jds.getEnd());
497 jseq.setColour(av.getSequenceColour(jds).getRGB());
499 jseq.setId(id); // jseq id should be a string not a number
501 if (av.hasHiddenRows())
503 jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds));
505 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
507 jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(jal.getSequenceAt(i)).getSequencesInOrder(jal);
509 for (int h = 0; h < reps.length; h++)
511 if (reps[h] != jal.getSequenceAt(i))
513 jseq.addHiddenSequences(jal.findIndex(reps[h]));
519 if (jds.getDatasetSequence().getSequenceFeatures() != null)
521 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
522 .getSequenceFeatures();
524 while (index < sf.length)
526 Features features = new Features();
528 features.setBegin(sf[index].getBegin());
529 features.setEnd(sf[index].getEnd());
530 features.setDescription(sf[index].getDescription());
531 features.setType(sf[index].getType());
532 features.setFeatureGroup(sf[index].getFeatureGroup());
533 features.setScore(sf[index].getScore());
534 if (sf[index].links != null)
536 for (int l = 0; l < sf[index].links.size(); l++)
538 OtherData keyValue = new OtherData();
539 keyValue.setKey("LINK_" + l);
540 keyValue.setValue(sf[index].links.elementAt(l).toString());
541 features.addOtherData(keyValue);
544 if (sf[index].otherDetails != null)
547 Enumeration keys = sf[index].otherDetails.keys();
548 while (keys.hasMoreElements())
550 key = keys.nextElement().toString();
551 OtherData keyValue = new OtherData();
552 keyValue.setKey(key);
553 keyValue.setValue(sf[index].otherDetails.get(key).toString());
554 features.addOtherData(keyValue);
558 jseq.addFeatures(features);
563 if (jds.getDatasetSequence().getPDBId() != null)
565 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
566 while (en.hasMoreElements())
568 Pdbids pdb = new Pdbids();
569 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
572 pdb.setId(entry.getId());
573 pdb.setType(entry.getType());
576 // This must have been loaded, is it still visible?
577 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
578 String matchedFile = null;
579 for (int f = frames.length - 1; f > -1; f--)
581 if (frames[f] instanceof AppJmol)
583 jmol = (AppJmol) frames[f];
584 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
586 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
587 && !(entry.getId().length() > 4 && entry
591 jmol.jmb.pdbentry[peid].getId()
594 if (matchedFile == null)
596 matchedFile = jmol.jmb.pdbentry[peid].getFile();
598 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
602 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
603 + jmol.jmb.pdbentry[peid].getFile());
607 // can get at it if the ID
608 // match is ambiguous (e.g.
610 String statestring = jmol.jmb.viewer.getStateInfo();
612 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
614 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
615 if (jds==jmol.jmb.sequence[peid][smap])
617 StructureState state = new StructureState();
618 state.setVisible(true);
619 state.setXpos(jmol.getX());
620 state.setYpos(jmol.getY());
621 state.setWidth(jmol.getWidth());
622 state.setHeight(jmol.getHeight());
623 state.setViewId(jmol.getViewId());
624 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
625 state.setColourwithAlignPanel(jmol
626 .isUsedforcolourby(ap));
627 state.setColourByJmol(jmol.isColouredByJmol());
628 if (!jmolViewIds.contains(state.getViewId()))
630 // Make sure we only store a Jmol state once in each XML
632 jmolViewIds.addElement(state.getViewId());
633 state.setContent(statestring.replaceAll("\n", ""));
637 state.setContent("# duplicate state");
639 pdb.addStructureState(state);
646 if (matchedFile != null || entry.getFile() != null)
648 if (entry.getFile() != null)
651 matchedFile = entry.getFile();
653 pdb.setFile(matchedFile); // entry.getFile());
654 if (pdbfiles == null)
656 pdbfiles = new Vector();
659 if (!pdbfiles.contains(entry.getId()))
661 pdbfiles.addElement(entry.getId());
664 File file = new File(matchedFile);
665 if (file.exists() && jout != null)
667 byte[] data = new byte[(int) file.length()];
668 jout.putNextEntry(new JarEntry(entry.getId()));
669 DataInputStream dis = new DataInputStream(
670 new FileInputStream(file));
673 DataOutputStream dout = new DataOutputStream(jout);
674 dout.write(data, 0, data.length);
678 } catch (Exception ex)
680 ex.printStackTrace();
686 if (entry.getProperty() != null)
688 PdbentryItem item = new PdbentryItem();
689 Hashtable properties = entry.getProperty();
690 Enumeration en2 = properties.keys();
691 while (en2.hasMoreElements())
693 Property prop = new Property();
694 String key = en2.nextElement().toString();
696 prop.setValue(properties.get(key).toString());
697 item.addProperty(prop);
699 pdb.addPdbentryItem(item);
709 if (av.hasHiddenRows())
711 jal = av.getAlignment();
714 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
716 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
717 for (int i = 0; i < jac.length; i++)
719 AlcodonFrame alc = new AlcodonFrame();
720 vamsasSet.addAlcodonFrame(alc);
721 for (int p = 0; p < jac[i].aaWidth; p++)
723 Alcodon cmap = new Alcodon();
724 if (jac[i].codons[p] != null)
726 // Null codons indicate a gapped column in the translated peptide
728 cmap.setPos1(jac[i].codons[p][0]);
729 cmap.setPos2(jac[i].codons[p][1]);
730 cmap.setPos3(jac[i].codons[p][2]);
732 alc.addAlcodon(cmap);
734 if (jac[i].getProtMappings() != null
735 && jac[i].getProtMappings().length > 0)
737 SequenceI[] dnas = jac[i].getdnaSeqs();
738 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
739 for (int m = 0; m < pmaps.length; m++)
741 AlcodMap alcmap = new AlcodMap();
742 alcmap.setDnasq(seqHash(dnas[m]));
743 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
745 alc.addAlcodMap(alcmap);
752 // /////////////////////////////////
753 if (av.currentTree != null)
755 // FIND ANY ASSOCIATED TREES
756 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
757 if (Desktop.desktop != null)
759 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
761 for (int t = 0; t < frames.length; t++)
763 if (frames[t] instanceof TreePanel)
765 TreePanel tp = (TreePanel) frames[t];
767 if (tp.treeCanvas.av.getAlignment() == jal)
769 Tree tree = new Tree();
770 tree.setTitle(tp.getTitle());
771 tree.setCurrentTree((av.currentTree == tp.getTree()));
772 tree.setNewick(tp.getTree().toString());
773 tree.setThreshold(tp.treeCanvas.threshold);
775 tree.setFitToWindow(tp.fitToWindow.getState());
776 tree.setFontName(tp.getTreeFont().getName());
777 tree.setFontSize(tp.getTreeFont().getSize());
778 tree.setFontStyle(tp.getTreeFont().getStyle());
779 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
781 tree.setShowBootstrap(tp.bootstrapMenu.getState());
782 tree.setShowDistances(tp.distanceMenu.getState());
784 tree.setHeight(tp.getHeight());
785 tree.setWidth(tp.getWidth());
786 tree.setXpos(tp.getX());
787 tree.setYpos(tp.getY());
788 tree.setId(makeHashCode(tp, null));
798 * store forward refs from an annotationRow to any groups
800 IdentityHashMap groupRefs = new IdentityHashMap();
801 if (jal.getAlignmentAnnotation() != null)
803 jalview.datamodel.AlignmentAnnotation[] aa = jal
804 .getAlignmentAnnotation();
806 for (int i = 0; i < aa.length; i++)
808 Annotation an = new Annotation();
810 if (aa[i].annotationId != null)
812 annotationIds.put(aa[i].annotationId, aa[i]);
815 an.setId(aa[i].annotationId);
817 an.setVisible(aa[i].visible);
819 an.setDescription(aa[i].description);
821 if (aa[i].sequenceRef != null)
823 // TODO later annotation sequenceRef should be the XML ID of the
824 // sequence rather than its display name
825 an.setSequenceRef(aa[i].sequenceRef.getName());
827 if (aa[i].groupRef != null)
829 Object groupIdr = groupRefs.get(aa[i].groupRef);
830 if (groupIdr == null)
832 // make a locally unique String
833 groupRefs.put(aa[i].groupRef,
834 groupIdr = ("" + System.currentTimeMillis()
835 + aa[i].groupRef.getName() + groupRefs.size()));
837 an.setGroupRef(groupIdr.toString());
840 // store all visualization attributes for annotation
841 an.setGraphHeight(aa[i].graphHeight);
842 an.setCentreColLabels(aa[i].centreColLabels);
843 an.setScaleColLabels(aa[i].scaleColLabel);
844 an.setShowAllColLabels(aa[i].showAllColLabels);
849 an.setGraphType(aa[i].graph);
850 an.setGraphGroup(aa[i].graphGroup);
851 if (aa[i].getThreshold() != null)
853 ThresholdLine line = new ThresholdLine();
854 line.setLabel(aa[i].getThreshold().label);
855 line.setValue(aa[i].getThreshold().value);
856 line.setColour(aa[i].getThreshold().colour.getRGB());
857 an.setThresholdLine(line);
865 an.setLabel(aa[i].label);
867 if (aa[i] == av.getAlignmentQualityAnnot() || aa[i] == av.getAlignmentConservationAnnotation()
868 || aa[i] == av.getAlignmentConsensusAnnotation() || aa[i].autoCalculated)
870 // new way of indicating autocalculated annotation -
871 an.setAutoCalculated(aa[i].autoCalculated);
873 if (aa[i].hasScore())
875 an.setScore(aa[i].getScore());
877 AnnotationElement ae;
878 if (aa[i].annotations != null)
880 an.setScoreOnly(false);
881 for (int a = 0; a < aa[i].annotations.length; a++)
883 if ((aa[i] == null) || (aa[i].annotations[a] == null))
888 ae = new AnnotationElement();
889 if (aa[i].annotations[a].description != null)
890 ae.setDescription(aa[i].annotations[a].description);
891 if (aa[i].annotations[a].displayCharacter != null)
892 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
894 if (!Float.isNaN(aa[i].annotations[a].value))
895 ae.setValue(aa[i].annotations[a].value);
898 if (aa[i].annotations[a].secondaryStructure != ' '
899 && aa[i].annotations[a].secondaryStructure != '\0')
900 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
903 if (aa[i].annotations[a].colour != null
904 && aa[i].annotations[a].colour != java.awt.Color.black)
906 ae.setColour(aa[i].annotations[a].colour.getRGB());
909 an.addAnnotationElement(ae);
910 if (aa[i].autoCalculated)
912 // only write one non-null entry into the annotation row -
913 // sufficient to get the visualization attributes necessary to
921 an.setScoreOnly(true);
923 vamsasSet.addAnnotation(an);
927 if (jal.getGroups() != null)
929 JGroup[] groups = new JGroup[jal.getGroups().size()];
931 for (jalview.datamodel.SequenceGroup sg:jal.getGroups())
933 groups[++i] = new JGroup();
935 groups[i].setStart(sg.getStartRes());
936 groups[i].setEnd(sg.getEndRes());
937 groups[i].setName(sg.getName());
938 if (groupRefs.containsKey(sg))
940 // group has references so set it's ID field
941 groups[i].setId(groupRefs.get(sg).toString());
945 if (sg.cs.conservationApplied())
947 groups[i].setConsThreshold(sg.cs.getConservationInc());
949 if (sg.cs instanceof jalview.schemes.UserColourScheme)
951 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
957 .setColour(ColourSchemeProperty.getColourName(sg.cs));
960 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
963 .setColour(ColourSchemeProperty
964 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
967 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
970 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
974 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
977 groups[i].setPidThreshold(sg.cs.getThreshold());
980 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
981 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
982 groups[i].setDisplayText(sg.getDisplayText());
983 groups[i].setColourText(sg.getColourText());
984 groups[i].setTextCol1(sg.textColour.getRGB());
985 groups[i].setTextCol2(sg.textColour2.getRGB());
986 groups[i].setTextColThreshold(sg.thresholdTextColour);
987 groups[i].setShowUnconserved(sg.getShowNonconserved());
988 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
989 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
990 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
991 for (int s = 0; s < sg.getSize(); s++)
993 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
995 groups[i].addSeq(seqHash(seq));
999 jms.setJGroup(groups);
1002 // /////////SAVE VIEWPORT
1003 Viewport view = new Viewport();
1004 view.setTitle(ap.alignFrame.getTitle());
1005 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1006 av.getSequenceSetId()));
1007 view.setId(av.getViewId());
1008 view.setViewName(av.viewName);
1009 view.setGatheredViews(av.gatherViewsHere);
1011 if (ap.av.explodedPosition != null)
1013 view.setXpos(av.explodedPosition.x);
1014 view.setYpos(av.explodedPosition.y);
1015 view.setWidth(av.explodedPosition.width);
1016 view.setHeight(av.explodedPosition.height);
1020 view.setXpos(ap.alignFrame.getBounds().x);
1021 view.setYpos(ap.alignFrame.getBounds().y);
1022 view.setWidth(ap.alignFrame.getBounds().width);
1023 view.setHeight(ap.alignFrame.getBounds().height);
1026 view.setStartRes(av.startRes);
1027 view.setStartSeq(av.startSeq);
1029 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1031 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1034 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1036 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1037 .getGlobalColourScheme();
1039 AnnotationColours ac = new AnnotationColours();
1040 ac.setAboveThreshold(acg.getAboveThreshold());
1041 ac.setThreshold(acg.getAnnotationThreshold());
1042 ac.setAnnotation(acg.getAnnotation());
1043 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1045 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1050 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1054 ac.setMaxColour(acg.getMaxColour().getRGB());
1055 ac.setMinColour(acg.getMinColour().getRGB());
1056 view.setAnnotationColours(ac);
1057 view.setBgColour("AnnotationColourGradient");
1061 view.setBgColour(ColourSchemeProperty.getColourName(av
1062 .getGlobalColourScheme()));
1065 ColourSchemeI cs = av.getGlobalColourScheme();
1069 if (cs.conservationApplied())
1071 view.setConsThreshold(cs.getConservationInc());
1072 if (cs instanceof jalview.schemes.UserColourScheme)
1074 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1078 if (cs instanceof ResidueColourScheme)
1080 view.setPidThreshold(cs.getThreshold());
1084 view.setConservationSelected(av.getConservationSelected());
1085 view.setPidSelected(av.getAbovePIDThreshold());
1086 view.setFontName(av.font.getName());
1087 view.setFontSize(av.font.getSize());
1088 view.setFontStyle(av.font.getStyle());
1089 view.setRenderGaps(av.renderGaps);
1090 view.setShowAnnotation(av.getShowAnnotation());
1091 view.setShowBoxes(av.getShowBoxes());
1092 view.setShowColourText(av.getColourText());
1093 view.setShowFullId(av.getShowJVSuffix());
1094 view.setRightAlignIds(av.rightAlignIds);
1095 view.setShowSequenceFeatures(av.showSequenceFeatures);
1096 view.setShowText(av.getShowText());
1097 view.setShowUnconserved(av.getShowUnconserved());
1098 view.setWrapAlignment(av.getWrapAlignment());
1099 view.setTextCol1(av.textColour.getRGB());
1100 view.setTextCol2(av.textColour2.getRGB());
1101 view.setTextColThreshold(av.thresholdTextColour);
1102 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1103 view.setShowSequenceLogo(av.isShowSequenceLogo());
1104 view.setShowGroupConsensus(av.isShowGroupConsensus());
1105 view.setShowGroupConservation(av.isShowGroupConservation());
1106 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1107 view.setShowDbRefTooltip(av.isShowDbRefs());
1108 view.setFollowHighlight(av.followHighlight);
1109 view.setFollowSelection(av.followSelection);
1110 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1111 if (av.featuresDisplayed != null)
1113 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1115 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1117 Vector settingsAdded = new Vector();
1118 Object gstyle = null;
1119 GraduatedColor gcol = null;
1120 if (renderOrder != null)
1122 for (int ro = 0; ro < renderOrder.length; ro++)
1124 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1125 .getFeatureStyle(renderOrder[ro]);
1126 Setting setting = new Setting();
1127 setting.setType(renderOrder[ro]);
1128 if (gstyle instanceof GraduatedColor)
1130 gcol = (GraduatedColor) gstyle;
1131 setting.setColour(gcol.getMaxColor().getRGB());
1132 setting.setMincolour(gcol.getMinColor().getRGB());
1133 setting.setMin(gcol.getMin());
1134 setting.setMax(gcol.getMax());
1135 setting.setColourByLabel(gcol.isColourByLabel());
1136 setting.setAutoScale(gcol.isAutoScale());
1137 setting.setThreshold(gcol.getThresh());
1138 setting.setThreshstate(gcol.getThreshType());
1142 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1143 .getColour(renderOrder[ro]).getRGB());
1146 setting.setDisplay(av.featuresDisplayed
1147 .containsKey(renderOrder[ro]));
1148 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1149 .getOrder(renderOrder[ro]);
1152 setting.setOrder(rorder);
1154 fs.addSetting(setting);
1155 settingsAdded.addElement(renderOrder[ro]);
1159 // Make sure we save none displayed feature settings
1160 Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1162 while (en.hasMoreElements())
1164 String key = en.nextElement().toString();
1165 if (settingsAdded.contains(key))
1170 Setting setting = new Setting();
1171 setting.setType(key);
1172 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1173 .getColour(key).getRGB());
1175 setting.setDisplay(false);
1176 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1180 setting.setOrder(rorder);
1182 fs.addSetting(setting);
1183 settingsAdded.addElement(key);
1185 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys();
1186 Vector groupsAdded = new Vector();
1187 while (en.hasMoreElements())
1189 String grp = en.nextElement().toString();
1190 if (groupsAdded.contains(grp))
1194 Group g = new Group();
1196 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1197 .get(grp)).booleanValue());
1199 groupsAdded.addElement(grp);
1201 jms.setFeatureSettings(fs);
1205 if (av.hasHiddenColumns())
1207 if (av.getColumnSelection() == null
1208 || av.getColumnSelection().getHiddenColumns() == null)
1210 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1214 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1217 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1219 HiddenColumns hc = new HiddenColumns();
1220 hc.setStart(region[0]);
1221 hc.setEnd(region[1]);
1222 view.addHiddenColumns(hc);
1227 jms.addViewport(view);
1229 object.setJalviewModelSequence(jms);
1230 object.getVamsasModel().addSequenceSet(vamsasSet);
1232 if (jout != null && fileName != null)
1234 // We may not want to write the object to disk,
1235 // eg we can copy the alignViewport to a new view object
1236 // using save and then load
1239 JarEntry entry = new JarEntry(fileName);
1240 jout.putNextEntry(entry);
1241 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1243 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1245 marshaller.marshal(object);
1248 } catch (Exception ex)
1250 // TODO: raise error in GUI if marshalling failed.
1251 ex.printStackTrace();
1258 * External mapping between jalview objects and objects yielding a valid and
1259 * unique object ID string. This is null for normal Jalview project IO, but
1260 * non-null when a jalview project is being read or written as part of a
1263 IdentityHashMap jv2vobj = null;
1266 * Construct a unique ID for jvobj using either existing bindings or if none
1267 * exist, the result of the hashcode call for the object.
1270 * jalview data object
1271 * @return unique ID for referring to jvobj
1273 private String makeHashCode(Object jvobj, String altCode)
1275 if (jv2vobj != null)
1277 Object id = jv2vobj.get(jvobj);
1280 return id.toString();
1282 // check string ID mappings
1283 if (jvids2vobj != null && jvobj instanceof String)
1285 id = jvids2vobj.get(jvobj);
1289 return id.toString();
1291 // give up and warn that something has gone wrong
1292 warn("Cannot find ID for object in external mapping : " + jvobj);
1298 * return local jalview object mapped to ID, if it exists
1302 * @return null or object bound to idcode
1304 private Object retrieveExistingObj(String idcode)
1306 if (idcode != null && vobj2jv != null)
1308 return vobj2jv.get(idcode);
1314 * binding from ID strings from external mapping table to jalview data model
1317 private Hashtable vobj2jv;
1319 private Sequence createVamsasSequence(String id, SequenceI jds)
1321 return createVamsasSequence(true, id, jds, null);
1324 private Sequence createVamsasSequence(boolean recurse, String id,
1325 SequenceI jds, SequenceI parentseq)
1327 Sequence vamsasSeq = new Sequence();
1328 vamsasSeq.setId(id);
1329 vamsasSeq.setName(jds.getName());
1330 vamsasSeq.setSequence(jds.getSequenceAsString());
1331 vamsasSeq.setDescription(jds.getDescription());
1332 jalview.datamodel.DBRefEntry[] dbrefs = null;
1333 if (jds.getDatasetSequence() != null)
1335 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1336 if (jds.getDatasetSequence().getDBRef() != null)
1338 dbrefs = jds.getDatasetSequence().getDBRef();
1343 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1344 // dataset sequences only
1345 dbrefs = jds.getDBRef();
1349 for (int d = 0; d < dbrefs.length; d++)
1351 DBRef dbref = new DBRef();
1352 dbref.setSource(dbrefs[d].getSource());
1353 dbref.setVersion(dbrefs[d].getVersion());
1354 dbref.setAccessionId(dbrefs[d].getAccessionId());
1355 if (dbrefs[d].hasMap())
1357 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1359 dbref.setMapping(mp);
1361 vamsasSeq.addDBRef(dbref);
1367 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1368 SequenceI parentseq, SequenceI jds, boolean recurse)
1371 if (jmp.getMap() != null)
1375 jalview.util.MapList mlst = jmp.getMap();
1376 int r[] = mlst.getFromRanges();
1377 for (int s = 0; s < r.length; s += 2)
1379 MapListFrom mfrom = new MapListFrom();
1380 mfrom.setStart(r[s]);
1381 mfrom.setEnd(r[s + 1]);
1382 mp.addMapListFrom(mfrom);
1384 r = mlst.getToRanges();
1385 for (int s = 0; s < r.length; s += 2)
1387 MapListTo mto = new MapListTo();
1389 mto.setEnd(r[s + 1]);
1390 mp.addMapListTo(mto);
1392 mp.setMapFromUnit(mlst.getFromRatio());
1393 mp.setMapToUnit(mlst.getToRatio());
1394 if (jmp.getTo() != null)
1396 MappingChoice mpc = new MappingChoice();
1398 && (parentseq != jmp.getTo() || parentseq
1399 .getDatasetSequence() != jmp.getTo()))
1401 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1407 SequenceI ps = null;
1408 if (parentseq != jmp.getTo()
1409 && parentseq.getDatasetSequence() != jmp.getTo())
1411 // chaining dbref rather than a handshaking one
1412 jmpid = seqHash(ps = jmp.getTo());
1416 jmpid = seqHash(ps = parentseq);
1418 mpc.setDseqFor(jmpid);
1419 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1421 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1422 seqRefIds.put(mpc.getDseqFor(), ps);
1426 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1429 mp.setMappingChoice(mpc);
1435 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1436 Vector userColours, JalviewModelSequence jms)
1439 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1440 boolean newucs = false;
1441 if (!userColours.contains(ucs))
1443 userColours.add(ucs);
1446 id = "ucs" + userColours.indexOf(ucs);
1449 // actually create the scheme's entry in the XML model
1450 java.awt.Color[] colours = ucs.getColours();
1451 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1452 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1454 for (int i = 0; i < colours.length; i++)
1456 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1457 col.setName(ResidueProperties.aa[i]);
1458 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1459 jbucs.addColour(col);
1461 if (ucs.getLowerCaseColours() != null)
1463 colours = ucs.getLowerCaseColours();
1464 for (int i = 0; i < colours.length; i++)
1466 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1467 col.setName(ResidueProperties.aa[i].toLowerCase());
1468 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1469 jbucs.addColour(col);
1474 uc.setUserColourScheme(jbucs);
1475 jms.addUserColours(uc);
1481 jalview.schemes.UserColourScheme GetUserColourScheme(
1482 JalviewModelSequence jms, String id)
1484 UserColours[] uc = jms.getUserColours();
1485 UserColours colours = null;
1487 for (int i = 0; i < uc.length; i++)
1489 if (uc[i].getId().equals(id))
1497 java.awt.Color[] newColours = new java.awt.Color[24];
1499 for (int i = 0; i < 24; i++)
1501 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1502 .getUserColourScheme().getColour(i).getRGB(), 16));
1505 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1508 if (colours.getUserColourScheme().getColourCount() > 24)
1510 newColours = new java.awt.Color[23];
1511 for (int i = 0; i < 23; i++)
1513 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1514 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1516 ucs.setLowerCaseColours(newColours);
1523 * contains last error message (if any) encountered by XML loader.
1525 String errorMessage = null;
1528 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1529 * exceptions are raised during project XML parsing
1531 public boolean attemptversion1parse = true;
1534 * Load a jalview project archive from a jar file
1537 * - HTTP URL or filename
1539 public AlignFrame LoadJalviewAlign(final String file)
1542 jalview.gui.AlignFrame af = null;
1546 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1547 // Workaround is to make sure caller implements the JarInputStreamProvider
1549 // so we can re-open the jar input stream for each entry.
1551 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1552 af = LoadJalviewAlign(jprovider);
1553 } catch (MalformedURLException e)
1555 errorMessage = "Invalid URL format for '" + file + "'";
1561 private jarInputStreamProvider createjarInputStreamProvider(
1562 final String file) throws MalformedURLException
1565 errorMessage = null;
1566 uniqueSetSuffix = null;
1568 viewportsAdded = null;
1569 frefedSequence = null;
1571 if (file.startsWith("http://"))
1573 url = new URL(file);
1575 final URL _url = url;
1576 return new jarInputStreamProvider()
1579 public JarInputStream getJarInputStream() throws IOException
1583 return new JarInputStream(_url.openStream());
1587 return new JarInputStream(new FileInputStream(file));
1591 public String getFilename()
1599 * Recover jalview session from a jalview project archive. Caller may
1600 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1601 * themselves. Any null fields will be initialised with default values,
1602 * non-null fields are left alone.
1607 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1609 errorMessage = null;
1610 if (uniqueSetSuffix == null)
1612 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1614 if (seqRefIds == null)
1616 seqRefIds = new Hashtable();
1618 if (viewportsAdded == null)
1620 viewportsAdded = new Hashtable();
1622 if (frefedSequence == null)
1624 frefedSequence = new Vector();
1627 jalview.gui.AlignFrame af = null;
1628 Hashtable gatherToThisFrame = new Hashtable();
1629 final String file = jprovider.getFilename();
1632 JarInputStream jin = null;
1633 JarEntry jarentry = null;
1638 jin = jprovider.getJarInputStream();
1639 for (int i = 0; i < entryCount; i++)
1641 jarentry = jin.getNextJarEntry();
1644 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1646 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1647 JalviewModel object = new JalviewModel();
1649 Unmarshaller unmar = new Unmarshaller(object);
1650 unmar.setValidation(false);
1651 object = (JalviewModel) unmar.unmarshal(in);
1652 if (true) // !skipViewport(object))
1654 af = LoadFromObject(object, file, true, jprovider);
1655 if (af.viewport.gatherViewsHere)
1657 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1662 else if (jarentry != null)
1664 // Some other file here.
1667 } while (jarentry != null);
1668 resolveFrefedSequences();
1669 } catch (java.io.FileNotFoundException ex)
1671 ex.printStackTrace();
1672 errorMessage = "Couldn't locate Jalview XML file : " + file;
1673 System.err.println("Exception whilst loading jalview XML file : "
1675 } catch (java.net.UnknownHostException ex)
1677 ex.printStackTrace();
1678 errorMessage = "Couldn't locate Jalview XML file : " + file;
1679 System.err.println("Exception whilst loading jalview XML file : "
1681 } catch (Exception ex)
1683 System.err.println("Parsing as Jalview Version 2 file failed.");
1684 ex.printStackTrace(System.err);
1685 if (attemptversion1parse)
1687 // Is Version 1 Jar file?
1690 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1691 } catch (Exception ex2)
1693 System.err.println("Exception whilst loading as jalviewXMLV1:");
1694 ex2.printStackTrace();
1698 if (Desktop.instance != null)
1700 Desktop.instance.stopLoading();
1704 System.out.println("Successfully loaded archive file");
1707 ex.printStackTrace();
1709 System.err.println("Exception whilst loading jalview XML file : "
1711 } catch (OutOfMemoryError e)
1713 // Don't use the OOM Window here
1714 errorMessage = "Out of memory loading jalview XML file";
1715 System.err.println("Out of memory whilst loading jalview XML file");
1716 e.printStackTrace();
1719 if (Desktop.instance != null)
1721 Desktop.instance.stopLoading();
1724 Enumeration en = gatherToThisFrame.elements();
1725 while (en.hasMoreElements())
1727 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1729 if (errorMessage != null)
1737 * check errorMessage for a valid error message and raise an error box in the
1738 * GUI or write the current errorMessage to stderr and then clear the error
1741 protected void reportErrors()
1743 reportErrors(false);
1746 protected void reportErrors(final boolean saving)
1748 if (errorMessage != null)
1750 final String finalErrorMessage = errorMessage;
1753 javax.swing.SwingUtilities.invokeLater(new Runnable()
1757 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1758 finalErrorMessage, "Error "
1759 + (saving ? "saving" : "loading")
1760 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1766 System.err.println("Problem loading Jalview file: " + errorMessage);
1769 errorMessage = null;
1772 Hashtable alreadyLoadedPDB;
1775 * when set, local views will be updated from view stored in JalviewXML
1776 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1777 * sync if this is set to true.
1779 private boolean updateLocalViews = false;
1781 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1783 if (alreadyLoadedPDB == null)
1784 alreadyLoadedPDB = new Hashtable();
1786 if (alreadyLoadedPDB.containsKey(pdbId))
1787 return alreadyLoadedPDB.get(pdbId).toString();
1791 JarInputStream jin = jprovider.getJarInputStream();
1793 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1794 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1795 * FileInputStream(jprovider)); }
1798 JarEntry entry = null;
1801 entry = jin.getNextJarEntry();
1802 } while (entry != null && !entry.getName().equals(pdbId));
1805 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1806 File outFile = File.createTempFile("jalview_pdb", ".txt");
1807 outFile.deleteOnExit();
1808 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1811 while ((data = in.readLine()) != null)
1818 } catch (Exception foo)
1823 String t=outFile.getAbsolutePath();
1824 alreadyLoadedPDB.put(pdbId, t);
1829 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1831 } catch (Exception ex)
1833 ex.printStackTrace();
1839 private class JvAnnotRow
1841 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1848 * persisted version of annotation row from which to take vis properties
1850 public jalview.datamodel.AlignmentAnnotation template;
1853 * original position of the annotation row in the alignment
1859 * Load alignment frame from jalview XML DOM object
1864 * filename source string
1865 * @param loadTreesAndStructures
1866 * when false only create Viewport
1868 * data source provider
1869 * @return alignment frame created from view stored in DOM
1871 AlignFrame LoadFromObject(JalviewModel object, String file,
1872 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
1874 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1875 Sequence[] vamsasSeq = vamsasSet.getSequence();
1877 JalviewModelSequence jms = object.getJalviewModelSequence();
1879 Viewport view = jms.getViewport(0);
1880 // ////////////////////////////////
1883 Vector hiddenSeqs = null;
1884 jalview.datamodel.Sequence jseq;
1886 ArrayList tmpseqs = new ArrayList();
1888 boolean multipleView = false;
1890 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1891 int vi = 0; // counter in vamsasSeq array
1892 for (int i = 0; i < JSEQ.length; i++)
1894 String seqId = JSEQ[i].getId();
1896 if (seqRefIds.get(seqId) != null)
1898 tmpseqs.add((jalview.datamodel.Sequence) seqRefIds.get(seqId));
1899 multipleView = true;
1903 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
1904 vamsasSeq[vi].getSequence());
1905 jseq.setDescription(vamsasSeq[vi].getDescription());
1906 jseq.setStart(JSEQ[i].getStart());
1907 jseq.setEnd(JSEQ[i].getEnd());
1908 jseq.setVamsasId(uniqueSetSuffix + seqId);
1909 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
1914 if (JSEQ[i].getHidden())
1916 if (hiddenSeqs == null)
1918 hiddenSeqs = new Vector();
1921 hiddenSeqs.addElement((jalview.datamodel.Sequence) seqRefIds
1928 // Create the alignment object from the sequence set
1929 // ///////////////////////////////
1930 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
1933 tmpseqs.toArray(orderedSeqs);
1935 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
1938 // / Add the alignment properties
1939 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
1941 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
1942 al.setProperty(ssp.getKey(), ssp.getValue());
1946 // SequenceFeatures are added to the DatasetSequence,
1947 // so we must create or recover the dataset before loading features
1948 // ///////////////////////////////
1949 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
1951 // older jalview projects do not have a dataset id.
1952 al.setDataset(null);
1956 recoverDatasetFor(vamsasSet, al);
1958 // ///////////////////////////////
1960 Hashtable pdbloaded = new Hashtable();
1963 // load sequence features, database references and any associated PDB
1964 // structures for the alignment
1965 for (int i = 0; i < vamsasSeq.length; i++)
1967 if (JSEQ[i].getFeaturesCount() > 0)
1969 Features[] features = JSEQ[i].getFeatures();
1970 for (int f = 0; f < features.length; f++)
1972 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
1973 features[f].getType(), features[f].getDescription(),
1974 features[f].getStatus(), features[f].getBegin(),
1975 features[f].getEnd(), features[f].getFeatureGroup());
1977 sf.setScore(features[f].getScore());
1978 for (int od = 0; od < features[f].getOtherDataCount(); od++)
1980 OtherData keyValue = features[f].getOtherData(od);
1981 if (keyValue.getKey().startsWith("LINK"))
1983 sf.addLink(keyValue.getValue());
1987 sf.setValue(keyValue.getKey(), keyValue.getValue());
1992 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
1995 if (vamsasSeq[i].getDBRefCount() > 0)
1997 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
1999 if (JSEQ[i].getPdbidsCount() > 0)
2001 Pdbids[] ids = JSEQ[i].getPdbids();
2002 for (int p = 0; p < ids.length; p++)
2004 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2005 entry.setId(ids[p].getId());
2006 entry.setType(ids[p].getType());
2007 if (ids[p].getFile() != null)
2009 if (!pdbloaded.containsKey(ids[p].getFile()))
2011 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2015 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2019 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2023 } // end !multipleview
2025 // ///////////////////////////////
2026 // LOAD SEQUENCE MAPPINGS
2028 if (vamsasSet.getAlcodonFrameCount() > 0)
2030 // TODO Potentially this should only be done once for all views of an
2032 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2033 for (int i = 0; i < alc.length; i++)
2035 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2036 alc[i].getAlcodonCount());
2037 if (alc[i].getAlcodonCount() > 0)
2039 Alcodon[] alcods = alc[i].getAlcodon();
2040 for (int p = 0; p < cf.codons.length; p++)
2042 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2043 && alcods[p].hasPos3())
2045 // translated codons require three valid positions
2046 cf.codons[p] = new int[3];
2047 cf.codons[p][0] = (int) alcods[p].getPos1();
2048 cf.codons[p][1] = (int) alcods[p].getPos2();
2049 cf.codons[p][2] = (int) alcods[p].getPos3();
2053 cf.codons[p] = null;
2057 if (alc[i].getAlcodMapCount() > 0)
2059 AlcodMap[] maps = alc[i].getAlcodMap();
2060 for (int m = 0; m < maps.length; m++)
2062 SequenceI dnaseq = (SequenceI) seqRefIds
2063 .get(maps[m].getDnasq());
2065 jalview.datamodel.Mapping mapping = null;
2066 // attach to dna sequence reference.
2067 if (maps[m].getMapping() != null)
2069 mapping = addMapping(maps[m].getMapping());
2073 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2078 frefedSequence.add(new Object[]
2079 { maps[m].getDnasq(), cf, mapping });
2083 al.addCodonFrame(cf);
2088 // ////////////////////////////////
2090 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2092 * store any annotations which forward reference a group's ID
2094 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2096 if (vamsasSet.getAnnotationCount() > 0)
2098 Annotation[] an = vamsasSet.getAnnotation();
2100 for (int i = 0; i < an.length; i++)
2103 * test if annotation is automatically calculated for this view only
2105 boolean autoForView = false;
2106 if (an[i].getLabel().equals("Quality")
2107 || an[i].getLabel().equals("Conservation")
2108 || an[i].getLabel().equals("Consensus"))
2110 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2112 if (!an[i].hasAutoCalculated())
2114 an[i].setAutoCalculated(true);
2118 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2120 // remove ID - we don't recover annotation from other views for
2121 // view-specific annotation
2125 // set visiblity for other annotation in this view
2126 if (an[i].getId() != null
2127 && annotationIds.containsKey(an[i].getId()))
2129 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2130 .get(an[i].getId());
2131 // in principle Visible should always be true for annotation displayed
2132 // in multiple views
2133 if (an[i].hasVisible())
2134 jda.visible = an[i].getVisible();
2136 al.addAnnotation(jda);
2140 // Construct new annotation from model.
2141 AnnotationElement[] ae = an[i].getAnnotationElement();
2142 jalview.datamodel.Annotation[] anot = null;
2144 if (!an[i].getScoreOnly())
2146 anot = new jalview.datamodel.Annotation[al.getWidth()];
2147 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2149 if (ae[aa].getPosition() >= anot.length)
2152 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2154 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2155 (ae[aa].getSecondaryStructure() == null || ae[aa]
2156 .getSecondaryStructure().length() == 0) ? ' '
2157 : ae[aa].getSecondaryStructure().charAt(0),
2161 // JBPNote: Consider verifying dataflow for IO of secondary
2162 // structure annotation read from Stockholm files
2163 // this was added to try to ensure that
2164 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2166 // anot[ae[aa].getPosition()].displayCharacter = "";
2168 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2169 ae[aa].getColour());
2172 jalview.datamodel.AlignmentAnnotation jaa = null;
2174 if (an[i].getGraph())
2176 float llim = 0, hlim = 0;
2177 // if (autoForView || an[i].isAutoCalculated()) {
2180 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2181 an[i].getDescription(), anot, llim, hlim,
2182 an[i].getGraphType());
2184 jaa.graphGroup = an[i].getGraphGroup();
2186 if (an[i].getThresholdLine() != null)
2188 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2189 .getThresholdLine().getValue(), an[i]
2190 .getThresholdLine().getLabel(), new java.awt.Color(
2191 an[i].getThresholdLine().getColour())));
2194 if (autoForView || an[i].isAutoCalculated())
2196 // Hardwire the symbol display line to ensure that labels for
2197 // histograms are displayed
2203 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2204 an[i].getDescription(), anot);
2208 // register new annotation
2209 if (an[i].getId() != null)
2211 annotationIds.put(an[i].getId(), jaa);
2212 jaa.annotationId = an[i].getId();
2214 // recover sequence association
2215 if (an[i].getSequenceRef() != null)
2217 if (al.findName(an[i].getSequenceRef()) != null)
2219 jaa.createSequenceMapping(
2220 al.findName(an[i].getSequenceRef()), 1, true);
2221 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
2226 // and make a note of any group association
2227 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2229 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2230 .get(an[i].getGroupRef());
2233 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2234 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2239 if (an[i].hasScore())
2241 jaa.setScore(an[i].getScore());
2243 if (an[i].hasVisible())
2244 jaa.visible = an[i].getVisible();
2246 if (an[i].hasCentreColLabels())
2247 jaa.centreColLabels = an[i].getCentreColLabels();
2249 if (an[i].hasScaleColLabels())
2251 jaa.scaleColLabel = an[i].getScaleColLabels();
2253 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2255 // newer files have an 'autoCalculated' flag and store calculation
2256 // state in viewport properties
2257 jaa.autoCalculated = true; // means annotation will be marked for
2258 // update at end of load.
2260 if (an[i].hasGraphHeight())
2262 jaa.graphHeight = an[i].getGraphHeight();
2264 if (jaa.autoCalculated)
2266 autoAlan.add(new JvAnnotRow(i, jaa));
2269 // if (!autoForView)
2271 // add autocalculated group annotation and any user created annotation
2273 al.addAnnotation(jaa);
2278 // ///////////////////////
2280 // Create alignment markup and styles for this view
2281 if (jms.getJGroupCount() > 0)
2283 JGroup[] groups = jms.getJGroup();
2285 for (int i = 0; i < groups.length; i++)
2287 ColourSchemeI cs = null;
2289 if (groups[i].getColour() != null)
2291 if (groups[i].getColour().startsWith("ucs"))
2293 cs = GetUserColourScheme(jms, groups[i].getColour());
2297 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2302 cs.setThreshold(groups[i].getPidThreshold(), true);
2306 Vector seqs = new Vector();
2308 for (int s = 0; s < groups[i].getSeqCount(); s++)
2310 String seqId = groups[i].getSeq(s) + "";
2311 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2316 seqs.addElement(ts);
2320 if (seqs.size() < 1)
2325 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2326 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2327 groups[i].getDisplayText(), groups[i].getColourText(),
2328 groups[i].getStart(), groups[i].getEnd());
2330 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2332 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2333 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2334 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2335 .isShowUnconserved() : false);
2336 sg.thresholdTextColour = groups[i].getTextColThreshold();
2337 if (groups[i].hasShowConsensusHistogram())
2339 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2342 if (groups[i].hasShowSequenceLogo())
2344 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2346 if (groups[i].hasIgnoreGapsinConsensus())
2348 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2350 if (groups[i].getConsThreshold() != 0)
2352 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2353 "All", ResidueProperties.propHash, 3,
2354 sg.getSequences(null), 0, sg.getWidth() - 1);
2356 c.verdict(false, 25);
2357 sg.cs.setConservation(c);
2360 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2362 // re-instate unique group/annotation row reference
2363 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2364 .get(groups[i].getId());
2367 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2370 if (jaa.autoCalculated)
2372 // match up and try to set group autocalc alignment row for this
2374 if (jaa.label.startsWith("Consensus for "))
2376 sg.setConsensus(jaa);
2378 // match up and try to set group autocalc alignment row for this
2380 if (jaa.label.startsWith("Conservation for "))
2382 sg.setConservationRow(jaa);
2393 // ///////////////////////////////
2396 // If we just load in the same jar file again, the sequenceSetId
2397 // will be the same, and we end up with multiple references
2398 // to the same sequenceSet. We must modify this id on load
2399 // so that each load of the file gives a unique id
2400 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2401 String viewId = (view.getId() == null ? null : view.getId()
2403 AlignFrame af = null;
2404 AlignViewport av = null;
2405 // now check to see if we really need to create a new viewport.
2406 if (multipleView && viewportsAdded.size() == 0)
2408 // We recovered an alignment for which a viewport already exists.
2409 // TODO: fix up any settings necessary for overlaying stored state onto
2410 // state recovered from another document. (may not be necessary).
2411 // we may need a binding from a viewport in memory to one recovered from
2413 // and then recover its containing af to allow the settings to be applied.
2414 // TODO: fix for vamsas demo
2416 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2418 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2419 if (seqsetobj != null)
2421 if (seqsetobj instanceof String)
2423 uniqueSeqSetId = (String) seqsetobj;
2425 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2431 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2436 AlignmentPanel ap = null;
2437 boolean isnewview = true;
2440 // Check to see if this alignment already has a view id == viewId
2441 jalview.gui.AlignmentPanel views[] = Desktop
2442 .getAlignmentPanels(uniqueSeqSetId);
2443 if (views != null && views.length > 0)
2445 for (int v = 0; v < views.length; v++)
2447 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2449 // recover the existing alignpanel, alignframe, viewport
2450 af = views[v].alignFrame;
2453 // TODO: could even skip resetting view settings if we don't want to
2454 // change the local settings from other jalview processes
2463 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2464 uniqueSeqSetId, viewId, autoAlan);
2469 // /////////////////////////////////////
2470 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2474 for (int t = 0; t < jms.getTreeCount(); t++)
2477 Tree tree = jms.getTree(t);
2479 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2482 tp = af.ShowNewickTree(
2483 new jalview.io.NewickFile(tree.getNewick()),
2484 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2485 tree.getXpos(), tree.getYpos());
2486 if (tree.getId() != null)
2488 // perhaps bind the tree id to something ?
2493 // update local tree attributes ?
2494 // TODO: should check if tp has been manipulated by user - if so its
2495 // settings shouldn't be modified
2496 tp.setTitle(tree.getTitle());
2497 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2498 .getWidth(), tree.getHeight()));
2499 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2502 tp.treeCanvas.av = av; // af.viewport;
2503 tp.treeCanvas.ap = ap; // af.alignPanel;
2508 warn("There was a problem recovering stored Newick tree: \n"
2509 + tree.getNewick());
2513 tp.fitToWindow.setState(tree.getFitToWindow());
2514 tp.fitToWindow_actionPerformed(null);
2516 if (tree.getFontName() != null)
2518 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2519 .getFontStyle(), tree.getFontSize()));
2523 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2524 .getFontStyle(), tree.getFontSize()));
2527 tp.showPlaceholders(tree.getMarkUnlinked());
2528 tp.showBootstrap(tree.getShowBootstrap());
2529 tp.showDistances(tree.getShowDistances());
2531 tp.treeCanvas.threshold = tree.getThreshold();
2533 if (tree.getCurrentTree())
2535 af.viewport.setCurrentTree(tp.getTree());
2539 } catch (Exception ex)
2541 ex.printStackTrace();
2545 // //LOAD STRUCTURES
2546 if (loadTreesAndStructures)
2548 // run through all PDB ids on the alignment, and collect mappings between
2549 // jmol view ids and all sequences referring to it
2550 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2552 for (int i = 0; i < JSEQ.length; i++)
2554 if (JSEQ[i].getPdbidsCount() > 0)
2556 Pdbids[] ids = JSEQ[i].getPdbids();
2557 for (int p = 0; p < ids.length; p++)
2559 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2561 // check to see if we haven't already created this structure view
2562 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2563 : ids[p].getStructureState(s).getViewId()
2565 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2566 // Originally : ids[p].getFile()
2567 // : TODO: verify external PDB file recovery still works in normal
2568 // jalview project load
2569 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2570 jpdb.setId(ids[p].getId());
2572 int x = ids[p].getStructureState(s).getXpos();
2573 int y = ids[p].getStructureState(s).getYpos();
2574 int width = ids[p].getStructureState(s).getWidth();
2575 int height = ids[p].getStructureState(s).getHeight();
2577 // Probably don't need to do this anymore...
2578 // Desktop.desktop.getComponentAt(x, y);
2579 // TODO: NOW: check that this recovers the PDB file correctly.
2580 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2581 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2582 .get(JSEQ[i].getId() + "");
2583 if (sviewid == null)
2585 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2588 if (!jmolViewIds.containsKey(sviewid))
2590 jmolViewIds.put(sviewid, new Object[]
2592 { x, y, width, height }, "",
2593 new Hashtable<String, Object[]>(), new boolean[]
2594 { false, false, true } });
2595 // Legacy pre-2.7 conversion JAL-823 :
2596 // do not assume any view has to be linked for colour by
2600 // assemble String[] { pdb files }, String[] { id for each
2601 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2602 // seqs_file 2}, boolean[] {
2603 // linkAlignPanel,superposeWithAlignpanel}} from hash
2604 Object[] jmoldat = (Object[]) jmolViewIds.get(sviewid);
2605 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2606 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2607 s).getAlignwithAlignPanel() : false;
2608 // never colour by linked panel if not specified
2609 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2610 .hasColourwithAlignPanel() ? ids[p]
2611 .getStructureState(s).getColourwithAlignPanel()
2613 // default for pre-2.7 projects is that Jmol colouring is enabled
2614 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2615 .hasColourByJmol() ? ids[p].getStructureState(s)
2616 .getColourByJmol() : true;
2618 if (((String) jmoldat[1]).length() < ids[p]
2619 .getStructureState(s).getContent().length())
2622 jmoldat[1] = ids[p].getStructureState(s).getContent();
2625 if (ids[p].getFile() != null)
2627 File mapkey=new File(ids[p].getFile());
2628 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2630 if (seqstrmaps == null)
2632 ((Hashtable) jmoldat[2]).put(
2634 seqstrmaps = new Object[]
2635 { pdbFile, ids[p].getId(), new Vector(),
2638 if (!((Vector) seqstrmaps[2]).contains(seq))
2640 ((Vector) seqstrmaps[2]).addElement(seq);
2641 // ((Vector)seqstrmaps[3]).addElement(n) :
2642 // in principle, chains
2643 // should be stored here : do we need to
2644 // TODO: store and recover seq/pdb_id :
2650 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");
2659 // Instantiate the associated Jmol views
2660 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2662 String sviewid = entry.getKey();
2663 Object[] svattrib = entry.getValue();
2664 int[] geom = (int[]) svattrib[0];
2665 String state = (String) svattrib[1];
2666 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2667 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2668 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2669 // collate the pdbfile -> sequence mappings from this view
2670 Vector<String> pdbfilenames = new Vector<String>();
2671 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2672 Vector<String> pdbids = new Vector<String>();
2674 // Search to see if we've already created this Jmol view
2675 AppJmol comp = null;
2676 JInternalFrame[] frames = null;
2681 frames = Desktop.desktop.getAllFrames();
2682 } catch (ArrayIndexOutOfBoundsException e)
2684 // occasional No such child exceptions are thrown here...
2689 } catch (Exception f)
2694 } while (frames == null);
2695 // search for any Jmol windows already open from other
2696 // alignment views that exactly match the stored structure state
2697 for (int f = 0; comp == null && f < frames.length; f++)
2699 if (frames[f] instanceof AppJmol)
2702 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2704 // post jalview 2.4 schema includes structure view id
2705 comp = (AppJmol) frames[f];
2707 else if (frames[f].getX() == x && frames[f].getY() == y
2708 && frames[f].getHeight() == height
2709 && frames[f].getWidth() == width)
2711 comp = (AppJmol) frames[f];
2718 // create a new Jmol window.
2719 // First parse the Jmol state to translate filenames loaded into the
2720 // view, and record the order in which files are shown in the Jmol
2721 // view, so we can add the sequence mappings in same order.
2722 StringBuffer newFileLoc = null;
2723 int cp = 0, ncp, ecp;
2724 while ((ncp = state.indexOf("load ", cp)) > -1)
2726 if (newFileLoc == null)
2728 newFileLoc = new StringBuffer();
2731 // look for next filename in load statement
2732 newFileLoc.append(state.substring(cp,
2733 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2734 String oldfilenam = state.substring(ncp,
2735 ecp = state.indexOf("\"", ncp));
2736 // recover the new mapping data for this old filename
2737 // have to normalize filename - since Jmol and jalview do filename
2738 // translation differently.
2739 Object[] filedat = oldFiles.get(new File(oldfilenam));
2740 newFileLoc.append(Platform.escapeString((String) filedat[0]));
2741 pdbfilenames.addElement((String) filedat[0]);
2742 pdbids.addElement((String) filedat[1]);
2743 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2744 .toArray(new SequenceI[0]));
2745 newFileLoc.append("\"");
2746 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2747 // look for next file statement.
2748 } while ((ncp=state.indexOf("/*file*/",cp))>-1);
2752 // just append rest of state
2753 newFileLoc.append(state.substring(cp));
2758 .print("Ignoring incomplete Jmol state for PDB ids: ");
2759 newFileLoc = new StringBuffer(state);
2760 newFileLoc.append("; load append ");
2761 for (File id : oldFiles.keySet())
2763 // add this and any other pdb files that should be present in
2765 Object[] filedat = oldFiles.get(id);
2767 newFileLoc.append(((String) filedat[0]));
2768 pdbfilenames.addElement((String) filedat[0]);
2769 pdbids.addElement((String) filedat[1]);
2770 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2771 .toArray(new SequenceI[0]));
2772 newFileLoc.append(" \"");
2773 newFileLoc.append((String) filedat[0]);
2774 newFileLoc.append("\"");
2777 newFileLoc.append(";");
2780 if (newFileLoc != null)
2782 int histbug = newFileLoc.indexOf("history = ");
2784 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2786 String val = (diff == -1) ? null : newFileLoc.substring(
2788 if (val != null && val.length() >= 4)
2790 if (val.contains("e"))
2792 if (val.trim().equals("true"))
2800 newFileLoc.replace(histbug, diff, val);
2803 // TODO: assemble String[] { pdb files }, String[] { id for each
2804 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2805 // seqs_file 2}} from hash
2806 final String[] pdbf = (String[]) pdbfilenames
2807 .toArray(new String[pdbfilenames.size()]), id = (String[]) pdbids
2808 .toArray(new String[pdbids.size()]);
2809 final SequenceI[][] sq = (SequenceI[][]) seqmaps
2810 .toArray(new SequenceI[seqmaps.size()][]);
2811 final String fileloc = newFileLoc.toString(), vid = sviewid;
2812 final AlignFrame alf = af;
2813 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2817 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2821 AppJmol sview = null;
2824 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2825 useinJmolsuperpos, usetoColourbyseq,
2826 jmolColouring, fileloc, rect, vid);
2827 } catch (OutOfMemoryError ex)
2829 new OOMWarning("restoring structure view for PDB id "
2830 + id, (OutOfMemoryError) ex.getCause());
2831 if (sview != null && sview.isVisible())
2833 sview.closeViewer();
2834 sview.setVisible(false);
2840 } catch (InvocationTargetException ex)
2842 warn("Unexpected error when opening Jmol view.", ex);
2844 } catch (InterruptedException e)
2846 // e.printStackTrace();
2852 // if (comp != null)
2854 // NOTE: if the jalview project is part of a shared session then
2855 // view synchronization should/could be done here.
2857 // add mapping for sequences in this view to an already open Jmol
2859 for (File id : oldFiles.keySet())
2861 // add this and any other pdb files that should be present in the
2863 Object[] filedat = oldFiles.get(id);
2864 String pdbFile = (String) filedat[0];
2865 SequenceI[] seq = (SequenceI[]) ((Vector<SequenceI>) filedat[2])
2866 .toArray(new SequenceI[0]);
2867 ((AppJmol) comp).jmb.ssm.setMapping(seq, null, pdbFile,
2868 jalview.io.AppletFormatAdapter.FILE);
2869 ((AppJmol) comp).jmb.addSequenceForStructFile(pdbFile, seq);
2871 // and add the AlignmentPanel's reference to the Jmol view
2872 ((AppJmol) comp).addAlignmentPanel(ap);
2873 if (useinJmolsuperpos)
2875 ((AppJmol) comp).useAlignmentPanelForSuperposition(ap);
2879 ((AppJmol) comp).excludeAlignmentPanelForSuperposition(ap);
2881 if (usetoColourbyseq)
2883 ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap,
2888 ((AppJmol) comp).excludeAlignmentPanelForColourbyseq(ap);
2894 // and finally return.
2898 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
2899 Alignment al, JalviewModelSequence jms, Viewport view,
2900 String uniqueSeqSetId, String viewId,
2901 ArrayList<JvAnnotRow> autoAlan)
2903 AlignFrame af = null;
2904 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
2905 uniqueSeqSetId, viewId);
2907 af.setFileName(file, "Jalview");
2909 for (int i = 0; i < JSEQ.length; i++)
2911 af.viewport.setSequenceColour(af.viewport.getAlignment().getSequenceAt(i),
2912 new java.awt.Color(JSEQ[i].getColour()));
2915 af.viewport.gatherViewsHere = view.getGatheredViews();
2917 if (view.getSequenceSetId() != null)
2919 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
2920 .get(uniqueSeqSetId);
2922 af.viewport.setSequenceSetId(uniqueSeqSetId);
2925 // propagate shared settings to this new view
2926 af.viewport.historyList = av.historyList;
2927 af.viewport.redoList = av.redoList;
2931 viewportsAdded.put(uniqueSeqSetId, af.viewport);
2933 // TODO: check if this method can be called repeatedly without
2934 // side-effects if alignpanel already registered.
2935 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
2937 // apply Hidden regions to view.
2938 if (hiddenSeqs != null)
2940 for (int s = 0; s < JSEQ.length; s++)
2942 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
2944 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
2947 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
2949 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
2952 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
2955 for (int s = 0; s < hiddenSeqs.size(); s++)
2957 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
2960 af.viewport.hideSequence(hseqs);
2963 // recover view properties and display parameters
2964 if (view.getViewName() != null)
2966 af.viewport.viewName = view.getViewName();
2967 af.setInitialTabVisible();
2969 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
2972 af.viewport.setShowAnnotation(view.getShowAnnotation());
2973 af.viewport.setAbovePIDThreshold(view.getPidSelected());
2975 af.viewport.setColourText(view.getShowColourText());
2977 af.viewport.setConservationSelected(view.getConservationSelected());
2978 af.viewport.setShowJVSuffix(view.getShowFullId());
2979 af.viewport.rightAlignIds = view.getRightAlignIds();
2980 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
2981 .getFontStyle(), view.getFontSize()));
2982 af.alignPanel.fontChanged();
2983 af.viewport.setRenderGaps(view.getRenderGaps());
2984 af.viewport.setWrapAlignment(view.getWrapAlignment());
2985 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
2986 af.viewport.setShowAnnotation(view.getShowAnnotation());
2987 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
2989 af.viewport.setShowBoxes(view.getShowBoxes());
2991 af.viewport.setShowText(view.getShowText());
2993 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
2994 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
2995 af.viewport.thresholdTextColour = view.getTextColThreshold();
2996 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
2997 .isShowUnconserved() : false);
2998 af.viewport.setStartRes(view.getStartRes());
2999 af.viewport.setStartSeq(view.getStartSeq());
3001 ColourSchemeI cs = null;
3002 // apply colourschemes
3003 if (view.getBgColour() != null)
3005 if (view.getBgColour().startsWith("ucs"))
3007 cs = GetUserColourScheme(jms, view.getBgColour());
3009 else if (view.getBgColour().startsWith("Annotation"))
3011 // int find annotation
3012 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3014 for (int i = 0; i < af.viewport.getAlignment()
3015 .getAlignmentAnnotation().length; i++)
3017 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3018 .equals(view.getAnnotationColours().getAnnotation()))
3020 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3021 .getThreshold() == null)
3023 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3024 .setThreshold(new jalview.datamodel.GraphLine(view
3025 .getAnnotationColours().getThreshold(),
3026 "Threshold", java.awt.Color.black)
3031 if (view.getAnnotationColours().getColourScheme()
3034 cs = new AnnotationColourGradient(
3035 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3036 new java.awt.Color(view.getAnnotationColours()
3037 .getMinColour()), new java.awt.Color(view
3038 .getAnnotationColours().getMaxColour()),
3039 view.getAnnotationColours().getAboveThreshold());
3041 else if (view.getAnnotationColours().getColourScheme()
3044 cs = new AnnotationColourGradient(
3045 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3046 GetUserColourScheme(jms, view
3047 .getAnnotationColours().getColourScheme()),
3048 view.getAnnotationColours().getAboveThreshold());
3052 cs = new AnnotationColourGradient(
3053 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3054 ColourSchemeProperty.getColour(al, view
3055 .getAnnotationColours().getColourScheme()),
3056 view.getAnnotationColours().getAboveThreshold());
3059 // Also use these settings for all the groups
3060 if (al.getGroups() != null)
3062 for (int g = 0; g < al.getGroups().size(); g++)
3064 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
3065 .getGroups().elementAt(g);
3074 * (view.getAnnotationColours().getColourScheme().equals("None"
3075 * )) { sg.cs = new AnnotationColourGradient(
3076 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3077 * java.awt.Color(view.getAnnotationColours().
3078 * getMinColour()), new
3079 * java.awt.Color(view.getAnnotationColours().
3081 * view.getAnnotationColours().getAboveThreshold()); } else
3084 sg.cs = new AnnotationColourGradient(
3085 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3086 sg.cs, view.getAnnotationColours()
3087 .getAboveThreshold());
3101 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3106 cs.setThreshold(view.getPidThreshold(), true);
3107 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3111 af.viewport.setGlobalColourScheme(cs);
3112 af.viewport.setColourAppliesToAllGroups(false);
3114 if (view.getConservationSelected() && cs != null)
3116 cs.setConservationInc(view.getConsThreshold());
3119 af.changeColour(cs);
3121 af.viewport.setColourAppliesToAllGroups(true);
3123 if (view.getShowSequenceFeatures())
3125 af.viewport.showSequenceFeatures = true;
3127 if (view.hasCentreColumnLabels())
3129 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3131 if (view.hasIgnoreGapsinConsensus())
3133 af.viewport.setIgnoreGapsConsensus(view
3134 .getIgnoreGapsinConsensus(), null);
3136 if (view.hasFollowHighlight())
3138 af.viewport.followHighlight = view.getFollowHighlight();
3140 if (view.hasFollowSelection())
3142 af.viewport.followSelection = view.getFollowSelection();
3144 if (view.hasShowConsensusHistogram())
3146 af.viewport.setShowConsensusHistogram(view
3147 .getShowConsensusHistogram());
3151 af.viewport.setShowConsensusHistogram(true);
3153 if (view.hasShowSequenceLogo())
3155 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3159 af.viewport.setShowSequenceLogo(false);
3161 if (view.hasShowDbRefTooltip())
3163 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3165 if (view.hasShowNPfeatureTooltip())
3167 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3169 if (view.hasShowGroupConsensus())
3171 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3175 af.viewport.setShowGroupConsensus(false);
3177 if (view.hasShowGroupConservation())
3179 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3183 af.viewport.setShowGroupConservation(false);
3186 // recover featre settings
3187 if (jms.getFeatureSettings() != null)
3189 af.viewport.featuresDisplayed = new Hashtable();
3190 String[] renderOrder = new String[jms.getFeatureSettings()
3191 .getSettingCount()];
3192 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3194 Setting setting = jms.getFeatureSettings().getSetting(fs);
3195 if (setting.hasMincolour())
3197 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3198 new java.awt.Color(setting.getMincolour()),
3199 new java.awt.Color(setting.getColour()),
3200 setting.getMin(), setting.getMax()) : new GraduatedColor(
3201 new java.awt.Color(setting.getMincolour()),
3202 new java.awt.Color(setting.getColour()), 0, 1);
3203 if (setting.hasThreshold())
3205 gc.setThresh(setting.getThreshold());
3206 gc.setThreshType(setting.getThreshstate());
3208 gc.setAutoScaled(true); // default
3209 if (setting.hasAutoScale())
3211 gc.setAutoScaled(setting.getAutoScale());
3213 if (setting.hasColourByLabel())
3215 gc.setColourByLabel(setting.getColourByLabel());
3217 // and put in the feature colour table.
3218 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3219 setting.getType(), gc);
3223 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3225 new java.awt.Color(setting.getColour()));
3227 renderOrder[fs] = setting.getType();
3228 if (setting.hasOrder())
3229 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3230 setting.getType(), setting.getOrder());
3232 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3234 fs / jms.getFeatureSettings().getSettingCount());
3235 if (setting.getDisplay())
3237 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3238 setting.getColour()));
3241 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3243 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3244 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3246 Group grp = jms.getFeatureSettings().getGroup(gs);
3247 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3251 if (view.getHiddenColumnsCount() > 0)
3253 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3255 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3256 .getHiddenColumns(c).getEnd() // +1
3261 af.setMenusFromViewport(af.viewport);
3262 // TODO: we don't need to do this if the viewport is aready visible.
3263 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3265 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3266 reorderAutoannotation(af, al, autoAlan);
3270 private void reorderAutoannotation(AlignFrame af, Alignment al,
3271 ArrayList<JvAnnotRow> autoAlan)
3273 // copy over visualization settings for autocalculated annotation in the
3275 if (al.getAlignmentAnnotation() != null)
3278 * Kludge for magic autoannotation names (see JAL-811)
3280 String[] magicNames = new String[]
3281 { "Consensus", "Quality", "Conservation" };
3282 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3283 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3284 for (String nm : magicNames)
3286 visan.put(nm, nullAnnot);
3288 for (JvAnnotRow auan : autoAlan)
3290 visan.put(auan.template.label, auan);
3292 int hSize = al.getAlignmentAnnotation().length;
3293 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3294 for (int h = 0; h < hSize; h++)
3296 jalview.datamodel.AlignmentAnnotation jalan = al
3297 .getAlignmentAnnotation()[h];
3298 if (jalan.autoCalculated)
3300 JvAnnotRow valan = visan.get(jalan.label);
3303 // delete the auto calculated row from the alignment
3304 al.deleteAnnotation(al.getAlignmentAnnotation()[h], false);
3307 if (valan != nullAnnot)
3309 if (jalan != valan.template)
3311 // newly created autoannotation row instance
3312 // so keep a reference to the visible annotation row
3313 // and copy over all relevant attributes
3314 if (valan.template.graphHeight >= 0)
3317 jalan.graphHeight = valan.template.graphHeight;
3319 jalan.visible = valan.template.visible;
3321 reorder.add(new JvAnnotRow(valan.order, jalan));
3326 int s = 0, srt[] = new int[reorder.size()];
3327 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3328 for (JvAnnotRow jvar : reorder)
3331 srt[s++] = jvar.order;
3334 jalview.util.QuickSort.sort(srt, rws);
3335 // and re-insert the annotation at its correct position
3336 for (JvAnnotRow jvar : rws)
3338 al.addAnnotation(jvar.template, jvar.order);
3340 af.alignPanel.adjustAnnotationHeight();
3344 Hashtable skipList = null;
3347 * TODO remove this method
3350 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3351 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3352 * throw new Error("Implementation Error. No skipList defined for this
3353 * Jalview2XML instance."); } return (AlignFrame)
3354 * skipList.get(view.getSequenceSetId()); }
3358 * Check if the Jalview view contained in object should be skipped or not.
3361 * @return true if view's sequenceSetId is a key in skipList
3363 private boolean skipViewport(JalviewModel object)
3365 if (skipList == null)
3370 if (skipList.containsKey(id = object.getJalviewModelSequence()
3371 .getViewport()[0].getSequenceSetId()))
3373 if (Cache.log != null && Cache.log.isDebugEnabled())
3375 Cache.log.debug("Skipping seuqence set id " + id);
3382 public void AddToSkipList(AlignFrame af)
3384 if (skipList == null)
3386 skipList = new Hashtable();
3388 skipList.put(af.getViewport().getSequenceSetId(), af);
3391 public void clearSkipList()
3393 if (skipList != null)
3400 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3402 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3403 Vector dseqs = null;
3406 // create a list of new dataset sequences
3407 dseqs = new Vector();
3409 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3411 Sequence vamsasSeq = vamsasSet.getSequence(i);
3412 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3414 // create a new dataset
3417 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3418 dseqs.copyInto(dsseqs);
3419 ds = new jalview.datamodel.Alignment(dsseqs);
3420 debug("Created new dataset " + vamsasSet.getDatasetId()
3421 + " for alignment " + System.identityHashCode(al));
3422 addDatasetRef(vamsasSet.getDatasetId(), ds);
3424 // set the dataset for the newly imported alignment.
3425 if (al.getDataset() == null)
3434 * sequence definition to create/merge dataset sequence for
3438 * vector to add new dataset sequence to
3440 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3441 AlignmentI ds, Vector dseqs)
3443 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3445 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3446 .get(vamsasSeq.getId());
3447 jalview.datamodel.SequenceI dsq = null;
3448 if (sq != null && sq.getDatasetSequence() != null)
3450 dsq = (jalview.datamodel.SequenceI) sq.getDatasetSequence();
3453 String sqid = vamsasSeq.getDsseqid();
3456 // need to create or add a new dataset sequence reference to this sequence
3459 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3464 // make a new dataset sequence
3465 dsq = sq.createDatasetSequence();
3468 // make up a new dataset reference for this sequence
3469 sqid = seqHash(dsq);
3471 dsq.setVamsasId(uniqueSetSuffix + sqid);
3472 seqRefIds.put(sqid, dsq);
3477 dseqs.addElement(dsq);
3482 ds.addSequence(dsq);
3488 { // make this dataset sequence sq's dataset sequence
3489 sq.setDatasetSequence(dsq);
3493 // TODO: refactor this as a merge dataset sequence function
3494 // now check that sq (the dataset sequence) sequence really is the union of
3495 // all references to it
3496 // boolean pre = sq.getStart() < dsq.getStart();
3497 // boolean post = sq.getEnd() > dsq.getEnd();
3501 StringBuffer sb = new StringBuffer();
3502 String newres = jalview.analysis.AlignSeq.extractGaps(
3503 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3504 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3505 && newres.length() > dsq.getLength())
3507 // Update with the longer sequence.
3511 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3512 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3513 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3514 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3516 dsq.setSequence(sb.toString());
3518 // TODO: merges will never happen if we 'know' we have the real dataset
3519 // sequence - this should be detected when id==dssid
3520 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3521 // + (pre ? "prepended" : "") + " "
3522 // + (post ? "appended" : ""));
3527 java.util.Hashtable datasetIds = null;
3529 java.util.IdentityHashMap dataset2Ids = null;
3531 private Alignment getDatasetFor(String datasetId)
3533 if (datasetIds == null)
3535 datasetIds = new Hashtable();
3538 if (datasetIds.containsKey(datasetId))
3540 return (Alignment) datasetIds.get(datasetId);
3545 private void addDatasetRef(String datasetId, Alignment dataset)
3547 if (datasetIds == null)
3549 datasetIds = new Hashtable();
3551 datasetIds.put(datasetId, dataset);
3555 * make a new dataset ID for this jalview dataset alignment
3560 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3562 if (dataset.getDataset() != null)
3564 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3566 String datasetId = makeHashCode(dataset, null);
3567 if (datasetId == null)
3569 // make a new datasetId and record it
3570 if (dataset2Ids == null)
3572 dataset2Ids = new IdentityHashMap();
3576 datasetId = (String) dataset2Ids.get(dataset);
3578 if (datasetId == null)
3580 datasetId = "ds" + dataset2Ids.size() + 1;
3581 dataset2Ids.put(dataset, datasetId);
3587 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3589 for (int d = 0; d < sequence.getDBRefCount(); d++)
3591 DBRef dr = sequence.getDBRef(d);
3592 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3593 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3594 .getVersion(), sequence.getDBRef(d).getAccessionId());
3595 if (dr.getMapping() != null)
3597 entry.setMap(addMapping(dr.getMapping()));
3599 datasetSequence.addDBRef(entry);
3603 private jalview.datamodel.Mapping addMapping(Mapping m)
3605 SequenceI dsto = null;
3606 // Mapping m = dr.getMapping();
3607 int fr[] = new int[m.getMapListFromCount() * 2];
3608 Enumeration f = m.enumerateMapListFrom();
3609 for (int _i = 0; f.hasMoreElements(); _i += 2)
3611 MapListFrom mf = (MapListFrom) f.nextElement();
3612 fr[_i] = mf.getStart();
3613 fr[_i + 1] = mf.getEnd();
3615 int fto[] = new int[m.getMapListToCount() * 2];
3616 f = m.enumerateMapListTo();
3617 for (int _i = 0; f.hasMoreElements(); _i += 2)
3619 MapListTo mf = (MapListTo) f.nextElement();
3620 fto[_i] = mf.getStart();
3621 fto[_i + 1] = mf.getEnd();
3623 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3624 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3625 if (m.getMappingChoice() != null)
3627 MappingChoice mc = m.getMappingChoice();
3628 if (mc.getDseqFor() != null)
3630 String dsfor = "" + mc.getDseqFor();
3631 if (seqRefIds.containsKey(dsfor))
3636 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3640 frefedSequence.add(new Object[]
3647 * local sequence definition
3649 Sequence ms = mc.getSequence();
3650 jalview.datamodel.Sequence djs = null;
3651 String sqid = ms.getDsseqid();
3652 if (sqid != null && sqid.length() > 0)
3655 * recover dataset sequence
3657 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3662 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3663 sqid = ((Object) ms).toString(); // make up a new hascode for
3664 // undefined dataset sequence hash
3665 // (unlikely to happen)
3671 * make a new dataset sequence and add it to refIds hash
3673 djs = new jalview.datamodel.Sequence(ms.getName(),
3675 djs.setStart(jmap.getMap().getToLowest());
3676 djs.setEnd(jmap.getMap().getToHighest());
3677 djs.setVamsasId(uniqueSetSuffix + sqid);
3679 seqRefIds.put(sqid, djs);
3682 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3691 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3692 boolean keepSeqRefs)
3695 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3701 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3705 uniqueSetSuffix = "";
3706 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3711 if (this.frefedSequence == null)
3713 frefedSequence = new Vector();
3716 viewportsAdded = new Hashtable();
3718 AlignFrame af = LoadFromObject(jm, null, false, null);
3719 af.alignPanels.clear();
3720 af.closeMenuItem_actionPerformed(true);
3723 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3724 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3725 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3726 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3727 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3730 return af.alignPanel;
3734 * flag indicating if hashtables should be cleared on finalization TODO this
3735 * flag may not be necessary
3737 private boolean _cleartables = true;
3739 private Hashtable jvids2vobj;
3744 * @see java.lang.Object#finalize()
3746 protected void finalize() throws Throwable
3748 // really make sure we have no buried refs left.
3753 this.seqRefIds = null;
3754 this.seqsToIds = null;
3758 private void warn(String msg)
3763 private void warn(String msg, Exception e)
3765 if (Cache.log != null)
3769 Cache.log.warn(msg, e);
3773 Cache.log.warn(msg);
3778 System.err.println("Warning: " + msg);
3781 e.printStackTrace();
3786 private void debug(String string)
3788 debug(string, null);
3791 private void debug(String msg, Exception e)
3793 if (Cache.log != null)
3797 Cache.log.debug(msg, e);
3801 Cache.log.debug(msg);
3806 System.err.println("Warning: " + msg);
3809 e.printStackTrace();
3815 * set the object to ID mapping tables used to write/recover objects and XML
3816 * ID strings for the jalview project. If external tables are provided then
3817 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3818 * object goes out of scope. - also populates the datasetIds hashtable with
3819 * alignment objects containing dataset sequences
3822 * Map from ID strings to jalview datamodel
3824 * Map from jalview datamodel to ID strings
3828 public void setObjectMappingTables(Hashtable vobj2jv,
3829 IdentityHashMap jv2vobj)
3831 this.jv2vobj = jv2vobj;
3832 this.vobj2jv = vobj2jv;
3833 Iterator ds = jv2vobj.keySet().iterator();
3835 while (ds.hasNext())
3837 Object jvobj = ds.next();
3838 id = jv2vobj.get(jvobj).toString();
3839 if (jvobj instanceof jalview.datamodel.Alignment)
3841 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
3843 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
3846 else if (jvobj instanceof jalview.datamodel.Sequence)
3848 // register sequence object so the XML parser can recover it.
3849 if (seqRefIds == null)
3851 seqRefIds = new Hashtable();
3853 if (seqsToIds == null)
3855 seqsToIds = new IdentityHashMap();
3857 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
3858 seqsToIds.put(jvobj, id);
3860 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
3862 if (annotationIds == null)
3864 annotationIds = new Hashtable();
3867 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
3868 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
3869 if (jvann.annotationId == null)
3871 jvann.annotationId = anid;
3873 if (!jvann.annotationId.equals(anid))
3875 // TODO verify that this is the correct behaviour
3876 this.warn("Overriding Annotation ID for " + anid
3877 + " from different id : " + jvann.annotationId);
3878 jvann.annotationId = anid;
3881 else if (jvobj instanceof String)
3883 if (jvids2vobj == null)
3885 jvids2vobj = new Hashtable();
3886 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
3890 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
3895 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
3896 * objects created from the project archive. If string is null (default for
3897 * construction) then suffix will be set automatically.
3901 public void setUniqueSetSuffix(String string)
3903 uniqueSetSuffix = string;
3908 * uses skipList2 as the skipList for skipping views on sequence sets
3909 * associated with keys in the skipList
3913 public void setSkipList(Hashtable skipList2)
3915 skipList = skipList2;