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 (int i = 0; i < groups.length; i++)
933 groups[i] = new JGroup();
935 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) jal
936 .getGroups().elementAt(i);
937 groups[i].setStart(sg.getStartRes());
938 groups[i].setEnd(sg.getEndRes());
939 groups[i].setName(sg.getName());
940 if (groupRefs.containsKey(sg))
942 // group has references so set it's ID field
943 groups[i].setId(groupRefs.get(sg).toString());
947 if (sg.cs.conservationApplied())
949 groups[i].setConsThreshold(sg.cs.getConservationInc());
951 if (sg.cs instanceof jalview.schemes.UserColourScheme)
953 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
959 .setColour(ColourSchemeProperty.getColourName(sg.cs));
962 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
965 .setColour(ColourSchemeProperty
966 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
969 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
972 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
976 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
979 groups[i].setPidThreshold(sg.cs.getThreshold());
982 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
983 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
984 groups[i].setDisplayText(sg.getDisplayText());
985 groups[i].setColourText(sg.getColourText());
986 groups[i].setTextCol1(sg.textColour.getRGB());
987 groups[i].setTextCol2(sg.textColour2.getRGB());
988 groups[i].setTextColThreshold(sg.thresholdTextColour);
989 groups[i].setShowUnconserved(sg.getShowNonconserved());
990 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
991 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
992 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
993 for (int s = 0; s < sg.getSize(); s++)
995 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
997 groups[i].addSeq(seqHash(seq));
1001 jms.setJGroup(groups);
1004 // /////////SAVE VIEWPORT
1005 Viewport view = new Viewport();
1006 view.setTitle(ap.alignFrame.getTitle());
1007 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1008 av.getSequenceSetId()));
1009 view.setId(av.getViewId());
1010 view.setViewName(av.viewName);
1011 view.setGatheredViews(av.gatherViewsHere);
1013 if (ap.av.explodedPosition != null)
1015 view.setXpos(av.explodedPosition.x);
1016 view.setYpos(av.explodedPosition.y);
1017 view.setWidth(av.explodedPosition.width);
1018 view.setHeight(av.explodedPosition.height);
1022 view.setXpos(ap.alignFrame.getBounds().x);
1023 view.setYpos(ap.alignFrame.getBounds().y);
1024 view.setWidth(ap.alignFrame.getBounds().width);
1025 view.setHeight(ap.alignFrame.getBounds().height);
1028 view.setStartRes(av.startRes);
1029 view.setStartSeq(av.startSeq);
1031 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1033 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1036 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1038 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1039 .getGlobalColourScheme();
1041 AnnotationColours ac = new AnnotationColours();
1042 ac.setAboveThreshold(acg.getAboveThreshold());
1043 ac.setThreshold(acg.getAnnotationThreshold());
1044 ac.setAnnotation(acg.getAnnotation());
1045 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1047 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1052 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1056 ac.setMaxColour(acg.getMaxColour().getRGB());
1057 ac.setMinColour(acg.getMinColour().getRGB());
1058 view.setAnnotationColours(ac);
1059 view.setBgColour("AnnotationColourGradient");
1063 view.setBgColour(ColourSchemeProperty.getColourName(av
1064 .getGlobalColourScheme()));
1067 ColourSchemeI cs = av.getGlobalColourScheme();
1071 if (cs.conservationApplied())
1073 view.setConsThreshold(cs.getConservationInc());
1074 if (cs instanceof jalview.schemes.UserColourScheme)
1076 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1080 if (cs instanceof ResidueColourScheme)
1082 view.setPidThreshold(cs.getThreshold());
1086 view.setConservationSelected(av.getConservationSelected());
1087 view.setPidSelected(av.getAbovePIDThreshold());
1088 view.setFontName(av.font.getName());
1089 view.setFontSize(av.font.getSize());
1090 view.setFontStyle(av.font.getStyle());
1091 view.setRenderGaps(av.renderGaps);
1092 view.setShowAnnotation(av.getShowAnnotation());
1093 view.setShowBoxes(av.getShowBoxes());
1094 view.setShowColourText(av.getColourText());
1095 view.setShowFullId(av.getShowJVSuffix());
1096 view.setRightAlignIds(av.rightAlignIds);
1097 view.setShowSequenceFeatures(av.showSequenceFeatures);
1098 view.setShowText(av.getShowText());
1099 view.setShowUnconserved(av.getShowUnconserved());
1100 view.setWrapAlignment(av.getWrapAlignment());
1101 view.setTextCol1(av.textColour.getRGB());
1102 view.setTextCol2(av.textColour2.getRGB());
1103 view.setTextColThreshold(av.thresholdTextColour);
1104 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1105 view.setShowSequenceLogo(av.isShowSequenceLogo());
1106 view.setShowGroupConsensus(av.isShowGroupConsensus());
1107 view.setShowGroupConservation(av.isShowGroupConservation());
1108 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1109 view.setShowDbRefTooltip(av.isShowDbRefs());
1110 view.setFollowHighlight(av.followHighlight);
1111 view.setFollowSelection(av.followSelection);
1112 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1113 if (av.featuresDisplayed != null)
1115 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1117 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1119 Vector settingsAdded = new Vector();
1120 Object gstyle = null;
1121 GraduatedColor gcol = null;
1122 if (renderOrder != null)
1124 for (int ro = 0; ro < renderOrder.length; ro++)
1126 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1127 .getFeatureStyle(renderOrder[ro]);
1128 Setting setting = new Setting();
1129 setting.setType(renderOrder[ro]);
1130 if (gstyle instanceof GraduatedColor)
1132 gcol = (GraduatedColor) gstyle;
1133 setting.setColour(gcol.getMaxColor().getRGB());
1134 setting.setMincolour(gcol.getMinColor().getRGB());
1135 setting.setMin(gcol.getMin());
1136 setting.setMax(gcol.getMax());
1137 setting.setColourByLabel(gcol.isColourByLabel());
1138 setting.setAutoScale(gcol.isAutoScale());
1139 setting.setThreshold(gcol.getThresh());
1140 setting.setThreshstate(gcol.getThreshType());
1144 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1145 .getColour(renderOrder[ro]).getRGB());
1148 setting.setDisplay(av.featuresDisplayed
1149 .containsKey(renderOrder[ro]));
1150 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1151 .getOrder(renderOrder[ro]);
1154 setting.setOrder(rorder);
1156 fs.addSetting(setting);
1157 settingsAdded.addElement(renderOrder[ro]);
1161 // Make sure we save none displayed feature settings
1162 Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1164 while (en.hasMoreElements())
1166 String key = en.nextElement().toString();
1167 if (settingsAdded.contains(key))
1172 Setting setting = new Setting();
1173 setting.setType(key);
1174 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1175 .getColour(key).getRGB());
1177 setting.setDisplay(false);
1178 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1182 setting.setOrder(rorder);
1184 fs.addSetting(setting);
1185 settingsAdded.addElement(key);
1187 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys();
1188 Vector groupsAdded = new Vector();
1189 while (en.hasMoreElements())
1191 String grp = en.nextElement().toString();
1192 if (groupsAdded.contains(grp))
1196 Group g = new Group();
1198 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1199 .get(grp)).booleanValue());
1201 groupsAdded.addElement(grp);
1203 jms.setFeatureSettings(fs);
1207 if (av.hasHiddenColumns())
1209 if (av.getColumnSelection() == null
1210 || av.getColumnSelection().getHiddenColumns() == null)
1212 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1216 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1219 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1221 HiddenColumns hc = new HiddenColumns();
1222 hc.setStart(region[0]);
1223 hc.setEnd(region[1]);
1224 view.addHiddenColumns(hc);
1229 jms.addViewport(view);
1231 object.setJalviewModelSequence(jms);
1232 object.getVamsasModel().addSequenceSet(vamsasSet);
1234 if (jout != null && fileName != null)
1236 // We may not want to write the object to disk,
1237 // eg we can copy the alignViewport to a new view object
1238 // using save and then load
1241 JarEntry entry = new JarEntry(fileName);
1242 jout.putNextEntry(entry);
1243 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1245 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1247 marshaller.marshal(object);
1250 } catch (Exception ex)
1252 // TODO: raise error in GUI if marshalling failed.
1253 ex.printStackTrace();
1260 * External mapping between jalview objects and objects yielding a valid and
1261 * unique object ID string. This is null for normal Jalview project IO, but
1262 * non-null when a jalview project is being read or written as part of a
1265 IdentityHashMap jv2vobj = null;
1268 * Construct a unique ID for jvobj using either existing bindings or if none
1269 * exist, the result of the hashcode call for the object.
1272 * jalview data object
1273 * @return unique ID for referring to jvobj
1275 private String makeHashCode(Object jvobj, String altCode)
1277 if (jv2vobj != null)
1279 Object id = jv2vobj.get(jvobj);
1282 return id.toString();
1284 // check string ID mappings
1285 if (jvids2vobj != null && jvobj instanceof String)
1287 id = jvids2vobj.get(jvobj);
1291 return id.toString();
1293 // give up and warn that something has gone wrong
1294 warn("Cannot find ID for object in external mapping : " + jvobj);
1300 * return local jalview object mapped to ID, if it exists
1304 * @return null or object bound to idcode
1306 private Object retrieveExistingObj(String idcode)
1308 if (idcode != null && vobj2jv != null)
1310 return vobj2jv.get(idcode);
1316 * binding from ID strings from external mapping table to jalview data model
1319 private Hashtable vobj2jv;
1321 private Sequence createVamsasSequence(String id, SequenceI jds)
1323 return createVamsasSequence(true, id, jds, null);
1326 private Sequence createVamsasSequence(boolean recurse, String id,
1327 SequenceI jds, SequenceI parentseq)
1329 Sequence vamsasSeq = new Sequence();
1330 vamsasSeq.setId(id);
1331 vamsasSeq.setName(jds.getName());
1332 vamsasSeq.setSequence(jds.getSequenceAsString());
1333 vamsasSeq.setDescription(jds.getDescription());
1334 jalview.datamodel.DBRefEntry[] dbrefs = null;
1335 if (jds.getDatasetSequence() != null)
1337 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1338 if (jds.getDatasetSequence().getDBRef() != null)
1340 dbrefs = jds.getDatasetSequence().getDBRef();
1345 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1346 // dataset sequences only
1347 dbrefs = jds.getDBRef();
1351 for (int d = 0; d < dbrefs.length; d++)
1353 DBRef dbref = new DBRef();
1354 dbref.setSource(dbrefs[d].getSource());
1355 dbref.setVersion(dbrefs[d].getVersion());
1356 dbref.setAccessionId(dbrefs[d].getAccessionId());
1357 if (dbrefs[d].hasMap())
1359 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1361 dbref.setMapping(mp);
1363 vamsasSeq.addDBRef(dbref);
1369 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1370 SequenceI parentseq, SequenceI jds, boolean recurse)
1373 if (jmp.getMap() != null)
1377 jalview.util.MapList mlst = jmp.getMap();
1378 int r[] = mlst.getFromRanges();
1379 for (int s = 0; s < r.length; s += 2)
1381 MapListFrom mfrom = new MapListFrom();
1382 mfrom.setStart(r[s]);
1383 mfrom.setEnd(r[s + 1]);
1384 mp.addMapListFrom(mfrom);
1386 r = mlst.getToRanges();
1387 for (int s = 0; s < r.length; s += 2)
1389 MapListTo mto = new MapListTo();
1391 mto.setEnd(r[s + 1]);
1392 mp.addMapListTo(mto);
1394 mp.setMapFromUnit(mlst.getFromRatio());
1395 mp.setMapToUnit(mlst.getToRatio());
1396 if (jmp.getTo() != null)
1398 MappingChoice mpc = new MappingChoice();
1400 && (parentseq != jmp.getTo() || parentseq
1401 .getDatasetSequence() != jmp.getTo()))
1403 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1409 SequenceI ps = null;
1410 if (parentseq != jmp.getTo()
1411 && parentseq.getDatasetSequence() != jmp.getTo())
1413 // chaining dbref rather than a handshaking one
1414 jmpid = seqHash(ps = jmp.getTo());
1418 jmpid = seqHash(ps = parentseq);
1420 mpc.setDseqFor(jmpid);
1421 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1423 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1424 seqRefIds.put(mpc.getDseqFor(), ps);
1428 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1431 mp.setMappingChoice(mpc);
1437 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1438 Vector userColours, JalviewModelSequence jms)
1441 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1442 boolean newucs = false;
1443 if (!userColours.contains(ucs))
1445 userColours.add(ucs);
1448 id = "ucs" + userColours.indexOf(ucs);
1451 // actually create the scheme's entry in the XML model
1452 java.awt.Color[] colours = ucs.getColours();
1453 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1454 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1456 for (int i = 0; i < colours.length; i++)
1458 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1459 col.setName(ResidueProperties.aa[i]);
1460 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1461 jbucs.addColour(col);
1463 if (ucs.getLowerCaseColours() != null)
1465 colours = ucs.getLowerCaseColours();
1466 for (int i = 0; i < colours.length; i++)
1468 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1469 col.setName(ResidueProperties.aa[i].toLowerCase());
1470 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1471 jbucs.addColour(col);
1476 uc.setUserColourScheme(jbucs);
1477 jms.addUserColours(uc);
1483 jalview.schemes.UserColourScheme GetUserColourScheme(
1484 JalviewModelSequence jms, String id)
1486 UserColours[] uc = jms.getUserColours();
1487 UserColours colours = null;
1489 for (int i = 0; i < uc.length; i++)
1491 if (uc[i].getId().equals(id))
1499 java.awt.Color[] newColours = new java.awt.Color[24];
1501 for (int i = 0; i < 24; i++)
1503 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1504 .getUserColourScheme().getColour(i).getRGB(), 16));
1507 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1510 if (colours.getUserColourScheme().getColourCount() > 24)
1512 newColours = new java.awt.Color[23];
1513 for (int i = 0; i < 23; i++)
1515 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1516 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1518 ucs.setLowerCaseColours(newColours);
1525 * contains last error message (if any) encountered by XML loader.
1527 String errorMessage = null;
1530 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1531 * exceptions are raised during project XML parsing
1533 public boolean attemptversion1parse = true;
1536 * Load a jalview project archive from a jar file
1539 * - HTTP URL or filename
1541 public AlignFrame LoadJalviewAlign(final String file)
1544 jalview.gui.AlignFrame af = null;
1548 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1549 // Workaround is to make sure caller implements the JarInputStreamProvider
1551 // so we can re-open the jar input stream for each entry.
1553 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1554 af = LoadJalviewAlign(jprovider);
1555 } catch (MalformedURLException e)
1557 errorMessage = "Invalid URL format for '" + file + "'";
1563 private jarInputStreamProvider createjarInputStreamProvider(
1564 final String file) throws MalformedURLException
1567 errorMessage = null;
1568 uniqueSetSuffix = null;
1570 viewportsAdded = null;
1571 frefedSequence = null;
1573 if (file.startsWith("http://"))
1575 url = new URL(file);
1577 final URL _url = url;
1578 return new jarInputStreamProvider()
1581 public JarInputStream getJarInputStream() throws IOException
1585 return new JarInputStream(_url.openStream());
1589 return new JarInputStream(new FileInputStream(file));
1593 public String getFilename()
1601 * Recover jalview session from a jalview project archive. Caller may
1602 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1603 * themselves. Any null fields will be initialised with default values,
1604 * non-null fields are left alone.
1609 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1611 errorMessage = null;
1612 if (uniqueSetSuffix == null)
1614 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1616 if (seqRefIds == null)
1618 seqRefIds = new Hashtable();
1620 if (viewportsAdded == null)
1622 viewportsAdded = new Hashtable();
1624 if (frefedSequence == null)
1626 frefedSequence = new Vector();
1629 jalview.gui.AlignFrame af = null;
1630 Hashtable gatherToThisFrame = new Hashtable();
1631 final String file = jprovider.getFilename();
1634 JarInputStream jin = null;
1635 JarEntry jarentry = null;
1640 jin = jprovider.getJarInputStream();
1641 for (int i = 0; i < entryCount; i++)
1643 jarentry = jin.getNextJarEntry();
1646 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1648 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1649 JalviewModel object = new JalviewModel();
1651 Unmarshaller unmar = new Unmarshaller(object);
1652 unmar.setValidation(false);
1653 object = (JalviewModel) unmar.unmarshal(in);
1654 if (true) // !skipViewport(object))
1656 af = LoadFromObject(object, file, true, jprovider);
1657 if (af.viewport.gatherViewsHere)
1659 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1664 else if (jarentry != null)
1666 // Some other file here.
1669 } while (jarentry != null);
1670 resolveFrefedSequences();
1671 } catch (java.io.FileNotFoundException ex)
1673 ex.printStackTrace();
1674 errorMessage = "Couldn't locate Jalview XML file : " + file;
1675 System.err.println("Exception whilst loading jalview XML file : "
1677 } catch (java.net.UnknownHostException ex)
1679 ex.printStackTrace();
1680 errorMessage = "Couldn't locate Jalview XML file : " + file;
1681 System.err.println("Exception whilst loading jalview XML file : "
1683 } catch (Exception ex)
1685 System.err.println("Parsing as Jalview Version 2 file failed.");
1686 ex.printStackTrace(System.err);
1687 if (attemptversion1parse)
1689 // Is Version 1 Jar file?
1692 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1693 } catch (Exception ex2)
1695 System.err.println("Exception whilst loading as jalviewXMLV1:");
1696 ex2.printStackTrace();
1700 if (Desktop.instance != null)
1702 Desktop.instance.stopLoading();
1706 System.out.println("Successfully loaded archive file");
1709 ex.printStackTrace();
1711 System.err.println("Exception whilst loading jalview XML file : "
1713 } catch (OutOfMemoryError e)
1715 // Don't use the OOM Window here
1716 errorMessage = "Out of memory loading jalview XML file";
1717 System.err.println("Out of memory whilst loading jalview XML file");
1718 e.printStackTrace();
1721 if (Desktop.instance != null)
1723 Desktop.instance.stopLoading();
1726 Enumeration en = gatherToThisFrame.elements();
1727 while (en.hasMoreElements())
1729 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1731 if (errorMessage != null)
1739 * check errorMessage for a valid error message and raise an error box in the
1740 * GUI or write the current errorMessage to stderr and then clear the error
1743 protected void reportErrors()
1745 reportErrors(false);
1748 protected void reportErrors(final boolean saving)
1750 if (errorMessage != null)
1752 final String finalErrorMessage = errorMessage;
1755 javax.swing.SwingUtilities.invokeLater(new Runnable()
1759 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1760 finalErrorMessage, "Error "
1761 + (saving ? "saving" : "loading")
1762 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1768 System.err.println("Problem loading Jalview file: " + errorMessage);
1771 errorMessage = null;
1774 Hashtable alreadyLoadedPDB;
1777 * when set, local views will be updated from view stored in JalviewXML
1778 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1779 * sync if this is set to true.
1781 private boolean updateLocalViews = false;
1783 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1785 if (alreadyLoadedPDB == null)
1786 alreadyLoadedPDB = new Hashtable();
1788 if (alreadyLoadedPDB.containsKey(pdbId))
1789 return alreadyLoadedPDB.get(pdbId).toString();
1793 JarInputStream jin = jprovider.getJarInputStream();
1795 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1796 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1797 * FileInputStream(jprovider)); }
1800 JarEntry entry = null;
1803 entry = jin.getNextJarEntry();
1804 } while (entry != null && !entry.getName().equals(pdbId));
1807 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1808 File outFile = File.createTempFile("jalview_pdb", ".txt");
1809 outFile.deleteOnExit();
1810 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1813 while ((data = in.readLine()) != null)
1820 } catch (Exception foo)
1825 String t=outFile.getAbsolutePath();
1826 alreadyLoadedPDB.put(pdbId, t);
1831 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1833 } catch (Exception ex)
1835 ex.printStackTrace();
1841 private class JvAnnotRow
1843 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1850 * persisted version of annotation row from which to take vis properties
1852 public jalview.datamodel.AlignmentAnnotation template;
1855 * original position of the annotation row in the alignment
1861 * Load alignment frame from jalview XML DOM object
1866 * filename source string
1867 * @param loadTreesAndStructures
1868 * when false only create Viewport
1870 * data source provider
1871 * @return alignment frame created from view stored in DOM
1873 AlignFrame LoadFromObject(JalviewModel object, String file,
1874 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
1876 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1877 Sequence[] vamsasSeq = vamsasSet.getSequence();
1879 JalviewModelSequence jms = object.getJalviewModelSequence();
1881 Viewport view = jms.getViewport(0);
1882 // ////////////////////////////////
1885 Vector hiddenSeqs = null;
1886 jalview.datamodel.Sequence jseq;
1888 ArrayList tmpseqs = new ArrayList();
1890 boolean multipleView = false;
1892 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1893 int vi = 0; // counter in vamsasSeq array
1894 for (int i = 0; i < JSEQ.length; i++)
1896 String seqId = JSEQ[i].getId();
1898 if (seqRefIds.get(seqId) != null)
1900 tmpseqs.add((jalview.datamodel.Sequence) seqRefIds.get(seqId));
1901 multipleView = true;
1905 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
1906 vamsasSeq[vi].getSequence());
1907 jseq.setDescription(vamsasSeq[vi].getDescription());
1908 jseq.setStart(JSEQ[i].getStart());
1909 jseq.setEnd(JSEQ[i].getEnd());
1910 jseq.setVamsasId(uniqueSetSuffix + seqId);
1911 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
1916 if (JSEQ[i].getHidden())
1918 if (hiddenSeqs == null)
1920 hiddenSeqs = new Vector();
1923 hiddenSeqs.addElement((jalview.datamodel.Sequence) seqRefIds
1930 // Create the alignment object from the sequence set
1931 // ///////////////////////////////
1932 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
1935 tmpseqs.toArray(orderedSeqs);
1937 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
1940 // / Add the alignment properties
1941 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
1943 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
1944 al.setProperty(ssp.getKey(), ssp.getValue());
1948 // SequenceFeatures are added to the DatasetSequence,
1949 // so we must create or recover the dataset before loading features
1950 // ///////////////////////////////
1951 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
1953 // older jalview projects do not have a dataset id.
1954 al.setDataset(null);
1958 recoverDatasetFor(vamsasSet, al);
1960 // ///////////////////////////////
1962 Hashtable pdbloaded = new Hashtable();
1965 // load sequence features, database references and any associated PDB
1966 // structures for the alignment
1967 for (int i = 0; i < vamsasSeq.length; i++)
1969 if (JSEQ[i].getFeaturesCount() > 0)
1971 Features[] features = JSEQ[i].getFeatures();
1972 for (int f = 0; f < features.length; f++)
1974 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
1975 features[f].getType(), features[f].getDescription(),
1976 features[f].getStatus(), features[f].getBegin(),
1977 features[f].getEnd(), features[f].getFeatureGroup());
1979 sf.setScore(features[f].getScore());
1980 for (int od = 0; od < features[f].getOtherDataCount(); od++)
1982 OtherData keyValue = features[f].getOtherData(od);
1983 if (keyValue.getKey().startsWith("LINK"))
1985 sf.addLink(keyValue.getValue());
1989 sf.setValue(keyValue.getKey(), keyValue.getValue());
1994 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
1997 if (vamsasSeq[i].getDBRefCount() > 0)
1999 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2001 if (JSEQ[i].getPdbidsCount() > 0)
2003 Pdbids[] ids = JSEQ[i].getPdbids();
2004 for (int p = 0; p < ids.length; p++)
2006 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2007 entry.setId(ids[p].getId());
2008 entry.setType(ids[p].getType());
2009 if (ids[p].getFile() != null)
2011 if (!pdbloaded.containsKey(ids[p].getFile()))
2013 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2017 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2021 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2025 } // end !multipleview
2027 // ///////////////////////////////
2028 // LOAD SEQUENCE MAPPINGS
2030 if (vamsasSet.getAlcodonFrameCount() > 0)
2032 // TODO Potentially this should only be done once for all views of an
2034 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2035 for (int i = 0; i < alc.length; i++)
2037 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2038 alc[i].getAlcodonCount());
2039 if (alc[i].getAlcodonCount() > 0)
2041 Alcodon[] alcods = alc[i].getAlcodon();
2042 for (int p = 0; p < cf.codons.length; p++)
2044 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2045 && alcods[p].hasPos3())
2047 // translated codons require three valid positions
2048 cf.codons[p] = new int[3];
2049 cf.codons[p][0] = (int) alcods[p].getPos1();
2050 cf.codons[p][1] = (int) alcods[p].getPos2();
2051 cf.codons[p][2] = (int) alcods[p].getPos3();
2055 cf.codons[p] = null;
2059 if (alc[i].getAlcodMapCount() > 0)
2061 AlcodMap[] maps = alc[i].getAlcodMap();
2062 for (int m = 0; m < maps.length; m++)
2064 SequenceI dnaseq = (SequenceI) seqRefIds
2065 .get(maps[m].getDnasq());
2067 jalview.datamodel.Mapping mapping = null;
2068 // attach to dna sequence reference.
2069 if (maps[m].getMapping() != null)
2071 mapping = addMapping(maps[m].getMapping());
2075 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2080 frefedSequence.add(new Object[]
2081 { maps[m].getDnasq(), cf, mapping });
2085 al.addCodonFrame(cf);
2090 // ////////////////////////////////
2092 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2094 * store any annotations which forward reference a group's ID
2096 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2098 if (vamsasSet.getAnnotationCount() > 0)
2100 Annotation[] an = vamsasSet.getAnnotation();
2102 for (int i = 0; i < an.length; i++)
2105 * test if annotation is automatically calculated for this view only
2107 boolean autoForView = false;
2108 if (an[i].getLabel().equals("Quality")
2109 || an[i].getLabel().equals("Conservation")
2110 || an[i].getLabel().equals("Consensus"))
2112 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2114 if (!an[i].hasAutoCalculated())
2116 an[i].setAutoCalculated(true);
2120 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2122 // remove ID - we don't recover annotation from other views for
2123 // view-specific annotation
2127 // set visiblity for other annotation in this view
2128 if (an[i].getId() != null
2129 && annotationIds.containsKey(an[i].getId()))
2131 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2132 .get(an[i].getId());
2133 // in principle Visible should always be true for annotation displayed
2134 // in multiple views
2135 if (an[i].hasVisible())
2136 jda.visible = an[i].getVisible();
2138 al.addAnnotation(jda);
2142 // Construct new annotation from model.
2143 AnnotationElement[] ae = an[i].getAnnotationElement();
2144 jalview.datamodel.Annotation[] anot = null;
2146 if (!an[i].getScoreOnly())
2148 anot = new jalview.datamodel.Annotation[al.getWidth()];
2149 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2151 if (ae[aa].getPosition() >= anot.length)
2154 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2156 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2157 (ae[aa].getSecondaryStructure() == null || ae[aa]
2158 .getSecondaryStructure().length() == 0) ? ' '
2159 : ae[aa].getSecondaryStructure().charAt(0),
2163 // JBPNote: Consider verifying dataflow for IO of secondary
2164 // structure annotation read from Stockholm files
2165 // this was added to try to ensure that
2166 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2168 // anot[ae[aa].getPosition()].displayCharacter = "";
2170 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2171 ae[aa].getColour());
2174 jalview.datamodel.AlignmentAnnotation jaa = null;
2176 if (an[i].getGraph())
2178 float llim = 0, hlim = 0;
2179 // if (autoForView || an[i].isAutoCalculated()) {
2182 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2183 an[i].getDescription(), anot, llim, hlim,
2184 an[i].getGraphType());
2186 jaa.graphGroup = an[i].getGraphGroup();
2188 if (an[i].getThresholdLine() != null)
2190 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2191 .getThresholdLine().getValue(), an[i]
2192 .getThresholdLine().getLabel(), new java.awt.Color(
2193 an[i].getThresholdLine().getColour())));
2196 if (autoForView || an[i].isAutoCalculated())
2198 // Hardwire the symbol display line to ensure that labels for
2199 // histograms are displayed
2205 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2206 an[i].getDescription(), anot);
2210 // register new annotation
2211 if (an[i].getId() != null)
2213 annotationIds.put(an[i].getId(), jaa);
2214 jaa.annotationId = an[i].getId();
2216 // recover sequence association
2217 if (an[i].getSequenceRef() != null)
2219 if (al.findName(an[i].getSequenceRef()) != null)
2221 jaa.createSequenceMapping(
2222 al.findName(an[i].getSequenceRef()), 1, true);
2223 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
2228 // and make a note of any group association
2229 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2231 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2232 .get(an[i].getGroupRef());
2235 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2236 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2241 if (an[i].hasScore())
2243 jaa.setScore(an[i].getScore());
2245 if (an[i].hasVisible())
2246 jaa.visible = an[i].getVisible();
2248 if (an[i].hasCentreColLabels())
2249 jaa.centreColLabels = an[i].getCentreColLabels();
2251 if (an[i].hasScaleColLabels())
2253 jaa.scaleColLabel = an[i].getScaleColLabels();
2255 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2257 // newer files have an 'autoCalculated' flag and store calculation
2258 // state in viewport properties
2259 jaa.autoCalculated = true; // means annotation will be marked for
2260 // update at end of load.
2262 if (an[i].hasGraphHeight())
2264 jaa.graphHeight = an[i].getGraphHeight();
2266 if (jaa.autoCalculated)
2268 autoAlan.add(new JvAnnotRow(i, jaa));
2271 // if (!autoForView)
2273 // add autocalculated group annotation and any user created annotation
2275 al.addAnnotation(jaa);
2280 // ///////////////////////
2282 // Create alignment markup and styles for this view
2283 if (jms.getJGroupCount() > 0)
2285 JGroup[] groups = jms.getJGroup();
2287 for (int i = 0; i < groups.length; i++)
2289 ColourSchemeI cs = null;
2291 if (groups[i].getColour() != null)
2293 if (groups[i].getColour().startsWith("ucs"))
2295 cs = GetUserColourScheme(jms, groups[i].getColour());
2299 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2304 cs.setThreshold(groups[i].getPidThreshold(), true);
2308 Vector seqs = new Vector();
2310 for (int s = 0; s < groups[i].getSeqCount(); s++)
2312 String seqId = groups[i].getSeq(s) + "";
2313 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2318 seqs.addElement(ts);
2322 if (seqs.size() < 1)
2327 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2328 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2329 groups[i].getDisplayText(), groups[i].getColourText(),
2330 groups[i].getStart(), groups[i].getEnd());
2332 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2334 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2335 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2336 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2337 .isShowUnconserved() : false);
2338 sg.thresholdTextColour = groups[i].getTextColThreshold();
2339 if (groups[i].hasShowConsensusHistogram())
2341 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2344 if (groups[i].hasShowSequenceLogo())
2346 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2348 if (groups[i].hasIgnoreGapsinConsensus())
2350 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2352 if (groups[i].getConsThreshold() != 0)
2354 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2355 "All", ResidueProperties.propHash, 3,
2356 sg.getSequences(null), 0, sg.getWidth() - 1);
2358 c.verdict(false, 25);
2359 sg.cs.setConservation(c);
2362 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2364 // re-instate unique group/annotation row reference
2365 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2366 .get(groups[i].getId());
2369 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2372 if (jaa.autoCalculated)
2374 // match up and try to set group autocalc alignment row for this
2376 if (jaa.label.startsWith("Consensus for "))
2378 sg.setConsensus(jaa);
2380 // match up and try to set group autocalc alignment row for this
2382 if (jaa.label.startsWith("Conservation for "))
2384 sg.setConservationRow(jaa);
2395 // ///////////////////////////////
2398 // If we just load in the same jar file again, the sequenceSetId
2399 // will be the same, and we end up with multiple references
2400 // to the same sequenceSet. We must modify this id on load
2401 // so that each load of the file gives a unique id
2402 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2403 String viewId = (view.getId() == null ? null : view.getId()
2405 AlignFrame af = null;
2406 AlignViewport av = null;
2407 // now check to see if we really need to create a new viewport.
2408 if (multipleView && viewportsAdded.size() == 0)
2410 // We recovered an alignment for which a viewport already exists.
2411 // TODO: fix up any settings necessary for overlaying stored state onto
2412 // state recovered from another document. (may not be necessary).
2413 // we may need a binding from a viewport in memory to one recovered from
2415 // and then recover its containing af to allow the settings to be applied.
2416 // TODO: fix for vamsas demo
2418 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2420 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2421 if (seqsetobj != null)
2423 if (seqsetobj instanceof String)
2425 uniqueSeqSetId = (String) seqsetobj;
2427 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2433 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2438 AlignmentPanel ap = null;
2439 boolean isnewview = true;
2442 // Check to see if this alignment already has a view id == viewId
2443 jalview.gui.AlignmentPanel views[] = Desktop
2444 .getAlignmentPanels(uniqueSeqSetId);
2445 if (views != null && views.length > 0)
2447 for (int v = 0; v < views.length; v++)
2449 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2451 // recover the existing alignpanel, alignframe, viewport
2452 af = views[v].alignFrame;
2455 // TODO: could even skip resetting view settings if we don't want to
2456 // change the local settings from other jalview processes
2465 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2466 uniqueSeqSetId, viewId, autoAlan);
2471 // /////////////////////////////////////
2472 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2476 for (int t = 0; t < jms.getTreeCount(); t++)
2479 Tree tree = jms.getTree(t);
2481 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2484 tp = af.ShowNewickTree(
2485 new jalview.io.NewickFile(tree.getNewick()),
2486 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2487 tree.getXpos(), tree.getYpos());
2488 if (tree.getId() != null)
2490 // perhaps bind the tree id to something ?
2495 // update local tree attributes ?
2496 // TODO: should check if tp has been manipulated by user - if so its
2497 // settings shouldn't be modified
2498 tp.setTitle(tree.getTitle());
2499 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2500 .getWidth(), tree.getHeight()));
2501 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2504 tp.treeCanvas.av = av; // af.viewport;
2505 tp.treeCanvas.ap = ap; // af.alignPanel;
2510 warn("There was a problem recovering stored Newick tree: \n"
2511 + tree.getNewick());
2515 tp.fitToWindow.setState(tree.getFitToWindow());
2516 tp.fitToWindow_actionPerformed(null);
2518 if (tree.getFontName() != null)
2520 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2521 .getFontStyle(), tree.getFontSize()));
2525 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2526 .getFontStyle(), tree.getFontSize()));
2529 tp.showPlaceholders(tree.getMarkUnlinked());
2530 tp.showBootstrap(tree.getShowBootstrap());
2531 tp.showDistances(tree.getShowDistances());
2533 tp.treeCanvas.threshold = tree.getThreshold();
2535 if (tree.getCurrentTree())
2537 af.viewport.setCurrentTree(tp.getTree());
2541 } catch (Exception ex)
2543 ex.printStackTrace();
2547 // //LOAD STRUCTURES
2548 if (loadTreesAndStructures)
2550 // run through all PDB ids on the alignment, and collect mappings between
2551 // jmol view ids and all sequences referring to it
2552 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2554 for (int i = 0; i < JSEQ.length; i++)
2556 if (JSEQ[i].getPdbidsCount() > 0)
2558 Pdbids[] ids = JSEQ[i].getPdbids();
2559 for (int p = 0; p < ids.length; p++)
2561 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2563 // check to see if we haven't already created this structure view
2564 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2565 : ids[p].getStructureState(s).getViewId()
2567 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2568 // Originally : ids[p].getFile()
2569 // : TODO: verify external PDB file recovery still works in normal
2570 // jalview project load
2571 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2572 jpdb.setId(ids[p].getId());
2574 int x = ids[p].getStructureState(s).getXpos();
2575 int y = ids[p].getStructureState(s).getYpos();
2576 int width = ids[p].getStructureState(s).getWidth();
2577 int height = ids[p].getStructureState(s).getHeight();
2579 // Probably don't need to do this anymore...
2580 // Desktop.desktop.getComponentAt(x, y);
2581 // TODO: NOW: check that this recovers the PDB file correctly.
2582 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2583 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2584 .get(JSEQ[i].getId() + "");
2585 if (sviewid == null)
2587 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2590 if (!jmolViewIds.containsKey(sviewid))
2592 jmolViewIds.put(sviewid, new Object[]
2594 { x, y, width, height }, "",
2595 new Hashtable<String, Object[]>(), new boolean[]
2596 { false, false, true } });
2597 // Legacy pre-2.7 conversion JAL-823 :
2598 // do not assume any view has to be linked for colour by
2602 // assemble String[] { pdb files }, String[] { id for each
2603 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2604 // seqs_file 2}, boolean[] {
2605 // linkAlignPanel,superposeWithAlignpanel}} from hash
2606 Object[] jmoldat = (Object[]) jmolViewIds.get(sviewid);
2607 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2608 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2609 s).getAlignwithAlignPanel() : false;
2610 // never colour by linked panel if not specified
2611 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2612 .hasColourwithAlignPanel() ? ids[p]
2613 .getStructureState(s).getColourwithAlignPanel()
2615 // default for pre-2.7 projects is that Jmol colouring is enabled
2616 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2617 .hasColourByJmol() ? ids[p].getStructureState(s)
2618 .getColourByJmol() : true;
2620 if (((String) jmoldat[1]).length() < ids[p]
2621 .getStructureState(s).getContent().length())
2624 jmoldat[1] = ids[p].getStructureState(s).getContent();
2627 if (ids[p].getFile() != null)
2629 File mapkey=new File(ids[p].getFile());
2630 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2632 if (seqstrmaps == null)
2634 ((Hashtable) jmoldat[2]).put(
2636 seqstrmaps = new Object[]
2637 { pdbFile, ids[p].getId(), new Vector(),
2640 if (!((Vector) seqstrmaps[2]).contains(seq))
2642 ((Vector) seqstrmaps[2]).addElement(seq);
2643 // ((Vector)seqstrmaps[3]).addElement(n) :
2644 // in principle, chains
2645 // should be stored here : do we need to
2646 // TODO: store and recover seq/pdb_id :
2652 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");
2661 // Instantiate the associated Jmol views
2662 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2664 String sviewid = entry.getKey();
2665 Object[] svattrib = entry.getValue();
2666 int[] geom = (int[]) svattrib[0];
2667 String state = (String) svattrib[1];
2668 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2669 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2670 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2671 // collate the pdbfile -> sequence mappings from this view
2672 Vector<String> pdbfilenames = new Vector<String>();
2673 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2674 Vector<String> pdbids = new Vector<String>();
2676 // Search to see if we've already created this Jmol view
2677 AppJmol comp = null;
2678 JInternalFrame[] frames = null;
2683 frames = Desktop.desktop.getAllFrames();
2684 } catch (ArrayIndexOutOfBoundsException e)
2686 // occasional No such child exceptions are thrown here...
2691 } catch (Exception f)
2696 } while (frames == null);
2697 // search for any Jmol windows already open from other
2698 // alignment views that exactly match the stored structure state
2699 for (int f = 0; comp == null && f < frames.length; f++)
2701 if (frames[f] instanceof AppJmol)
2704 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2706 // post jalview 2.4 schema includes structure view id
2707 comp = (AppJmol) frames[f];
2709 else if (frames[f].getX() == x && frames[f].getY() == y
2710 && frames[f].getHeight() == height
2711 && frames[f].getWidth() == width)
2713 comp = (AppJmol) frames[f];
2720 // create a new Jmol window.
2721 // First parse the Jmol state to translate filenames loaded into the
2722 // view, and record the order in which files are shown in the Jmol
2723 // view, so we can add the sequence mappings in same order.
2724 StringBuffer newFileLoc = null;
2725 int cp = 0, ncp, ecp;
2726 while ((ncp = state.indexOf("load ", cp)) > -1)
2728 if (newFileLoc == null)
2730 newFileLoc = new StringBuffer();
2733 // look for next filename in load statement
2734 newFileLoc.append(state.substring(cp,
2735 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2736 String oldfilenam = state.substring(ncp,
2737 ecp = state.indexOf("\"", ncp));
2738 // recover the new mapping data for this old filename
2739 // have to normalize filename - since Jmol and jalview do filename
2740 // translation differently.
2741 Object[] filedat = oldFiles.get(new File(oldfilenam));
2742 newFileLoc.append(Platform.escapeString((String) filedat[0]));
2743 pdbfilenames.addElement((String) filedat[0]);
2744 pdbids.addElement((String) filedat[1]);
2745 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2746 .toArray(new SequenceI[0]));
2747 newFileLoc.append("\"");
2748 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2749 // look for next file statement.
2750 } while ((ncp=state.indexOf("/*file*/",cp))>-1);
2754 // just append rest of state
2755 newFileLoc.append(state.substring(cp));
2760 .print("Ignoring incomplete Jmol state for PDB ids: ");
2761 newFileLoc = new StringBuffer(state);
2762 newFileLoc.append("; load append ");
2763 for (File id : oldFiles.keySet())
2765 // add this and any other pdb files that should be present in
2767 Object[] filedat = oldFiles.get(id);
2769 newFileLoc.append(((String) filedat[0]));
2770 pdbfilenames.addElement((String) filedat[0]);
2771 pdbids.addElement((String) filedat[1]);
2772 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2773 .toArray(new SequenceI[0]));
2774 newFileLoc.append(" \"");
2775 newFileLoc.append((String) filedat[0]);
2776 newFileLoc.append("\"");
2779 newFileLoc.append(";");
2782 if (newFileLoc != null)
2784 int histbug = newFileLoc.indexOf("history = ");
2786 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2788 String val = (diff == -1) ? null : newFileLoc.substring(
2790 if (val != null && val.length() >= 4)
2792 if (val.contains("e"))
2794 if (val.trim().equals("true"))
2802 newFileLoc.replace(histbug, diff, val);
2805 // TODO: assemble String[] { pdb files }, String[] { id for each
2806 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2807 // seqs_file 2}} from hash
2808 final String[] pdbf = (String[]) pdbfilenames
2809 .toArray(new String[pdbfilenames.size()]), id = (String[]) pdbids
2810 .toArray(new String[pdbids.size()]);
2811 final SequenceI[][] sq = (SequenceI[][]) seqmaps
2812 .toArray(new SequenceI[seqmaps.size()][]);
2813 final String fileloc = newFileLoc.toString(), vid = sviewid;
2814 final AlignFrame alf = af;
2815 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2819 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2823 AppJmol sview = null;
2826 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2827 useinJmolsuperpos, usetoColourbyseq,
2828 jmolColouring, fileloc, rect, vid);
2829 } catch (OutOfMemoryError ex)
2831 new OOMWarning("restoring structure view for PDB id "
2832 + id, (OutOfMemoryError) ex.getCause());
2833 if (sview != null && sview.isVisible())
2835 sview.closeViewer();
2836 sview.setVisible(false);
2842 } catch (InvocationTargetException ex)
2844 warn("Unexpected error when opening Jmol view.", ex);
2846 } catch (InterruptedException e)
2848 // e.printStackTrace();
2854 // if (comp != null)
2856 // NOTE: if the jalview project is part of a shared session then
2857 // view synchronization should/could be done here.
2859 // add mapping for sequences in this view to an already open Jmol
2861 for (File id : oldFiles.keySet())
2863 // add this and any other pdb files that should be present in the
2865 Object[] filedat = oldFiles.get(id);
2866 String pdbFile = (String) filedat[0];
2867 SequenceI[] seq = (SequenceI[]) ((Vector<SequenceI>) filedat[2])
2868 .toArray(new SequenceI[0]);
2869 ((AppJmol) comp).jmb.ssm.setMapping(seq, null, pdbFile,
2870 jalview.io.AppletFormatAdapter.FILE);
2871 ((AppJmol) comp).jmb.addSequenceForStructFile(pdbFile, seq);
2873 // and add the AlignmentPanel's reference to the Jmol view
2874 ((AppJmol) comp).addAlignmentPanel(ap);
2875 if (useinJmolsuperpos)
2877 ((AppJmol) comp).useAlignmentPanelForSuperposition(ap);
2881 ((AppJmol) comp).excludeAlignmentPanelForSuperposition(ap);
2883 if (usetoColourbyseq)
2885 ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap,
2890 ((AppJmol) comp).excludeAlignmentPanelForColourbyseq(ap);
2896 // and finally return.
2900 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
2901 Alignment al, JalviewModelSequence jms, Viewport view,
2902 String uniqueSeqSetId, String viewId,
2903 ArrayList<JvAnnotRow> autoAlan)
2905 AlignFrame af = null;
2906 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
2907 uniqueSeqSetId, viewId);
2909 af.setFileName(file, "Jalview");
2911 for (int i = 0; i < JSEQ.length; i++)
2913 af.viewport.setSequenceColour(af.viewport.getAlignment().getSequenceAt(i),
2914 new java.awt.Color(JSEQ[i].getColour()));
2917 af.viewport.gatherViewsHere = view.getGatheredViews();
2919 if (view.getSequenceSetId() != null)
2921 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
2922 .get(uniqueSeqSetId);
2924 af.viewport.setSequenceSetId(uniqueSeqSetId);
2927 // propagate shared settings to this new view
2928 af.viewport.historyList = av.historyList;
2929 af.viewport.redoList = av.redoList;
2933 viewportsAdded.put(uniqueSeqSetId, af.viewport);
2935 // TODO: check if this method can be called repeatedly without
2936 // side-effects if alignpanel already registered.
2937 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
2939 // apply Hidden regions to view.
2940 if (hiddenSeqs != null)
2942 for (int s = 0; s < JSEQ.length; s++)
2944 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
2946 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
2949 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
2951 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
2954 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
2957 for (int s = 0; s < hiddenSeqs.size(); s++)
2959 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
2962 af.viewport.hideSequence(hseqs);
2965 // recover view properties and display parameters
2966 if (view.getViewName() != null)
2968 af.viewport.viewName = view.getViewName();
2969 af.setInitialTabVisible();
2971 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
2974 af.viewport.setShowAnnotation(view.getShowAnnotation());
2975 af.viewport.setAbovePIDThreshold(view.getPidSelected());
2977 af.viewport.setColourText(view.getShowColourText());
2979 af.viewport.setConservationSelected(view.getConservationSelected());
2980 af.viewport.setShowJVSuffix(view.getShowFullId());
2981 af.viewport.rightAlignIds = view.getRightAlignIds();
2982 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
2983 .getFontStyle(), view.getFontSize()));
2984 af.alignPanel.fontChanged();
2985 af.viewport.setRenderGaps(view.getRenderGaps());
2986 af.viewport.setWrapAlignment(view.getWrapAlignment());
2987 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
2988 af.viewport.setShowAnnotation(view.getShowAnnotation());
2989 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
2991 af.viewport.setShowBoxes(view.getShowBoxes());
2993 af.viewport.setShowText(view.getShowText());
2995 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
2996 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
2997 af.viewport.thresholdTextColour = view.getTextColThreshold();
2998 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
2999 .isShowUnconserved() : false);
3000 af.viewport.setStartRes(view.getStartRes());
3001 af.viewport.setStartSeq(view.getStartSeq());
3003 ColourSchemeI cs = null;
3004 // apply colourschemes
3005 if (view.getBgColour() != null)
3007 if (view.getBgColour().startsWith("ucs"))
3009 cs = GetUserColourScheme(jms, view.getBgColour());
3011 else if (view.getBgColour().startsWith("Annotation"))
3013 // int find annotation
3014 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3016 for (int i = 0; i < af.viewport.getAlignment()
3017 .getAlignmentAnnotation().length; i++)
3019 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3020 .equals(view.getAnnotationColours().getAnnotation()))
3022 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3023 .getThreshold() == null)
3025 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3026 .setThreshold(new jalview.datamodel.GraphLine(view
3027 .getAnnotationColours().getThreshold(),
3028 "Threshold", java.awt.Color.black)
3033 if (view.getAnnotationColours().getColourScheme()
3036 cs = new AnnotationColourGradient(
3037 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3038 new java.awt.Color(view.getAnnotationColours()
3039 .getMinColour()), new java.awt.Color(view
3040 .getAnnotationColours().getMaxColour()),
3041 view.getAnnotationColours().getAboveThreshold());
3043 else if (view.getAnnotationColours().getColourScheme()
3046 cs = new AnnotationColourGradient(
3047 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3048 GetUserColourScheme(jms, view
3049 .getAnnotationColours().getColourScheme()),
3050 view.getAnnotationColours().getAboveThreshold());
3054 cs = new AnnotationColourGradient(
3055 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3056 ColourSchemeProperty.getColour(al, view
3057 .getAnnotationColours().getColourScheme()),
3058 view.getAnnotationColours().getAboveThreshold());
3061 // Also use these settings for all the groups
3062 if (al.getGroups() != null)
3064 for (int g = 0; g < al.getGroups().size(); g++)
3066 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
3067 .getGroups().elementAt(g);
3076 * (view.getAnnotationColours().getColourScheme().equals("None"
3077 * )) { sg.cs = new AnnotationColourGradient(
3078 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3079 * java.awt.Color(view.getAnnotationColours().
3080 * getMinColour()), new
3081 * java.awt.Color(view.getAnnotationColours().
3083 * view.getAnnotationColours().getAboveThreshold()); } else
3086 sg.cs = new AnnotationColourGradient(
3087 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3088 sg.cs, view.getAnnotationColours()
3089 .getAboveThreshold());
3103 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3108 cs.setThreshold(view.getPidThreshold(), true);
3109 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3113 af.viewport.setGlobalColourScheme(cs);
3114 af.viewport.setColourAppliesToAllGroups(false);
3116 if (view.getConservationSelected() && cs != null)
3118 cs.setConservationInc(view.getConsThreshold());
3121 af.changeColour(cs);
3123 af.viewport.setColourAppliesToAllGroups(true);
3125 if (view.getShowSequenceFeatures())
3127 af.viewport.showSequenceFeatures = true;
3129 if (view.hasCentreColumnLabels())
3131 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3133 if (view.hasIgnoreGapsinConsensus())
3135 af.viewport.setIgnoreGapsConsensus(view
3136 .getIgnoreGapsinConsensus(), null);
3138 if (view.hasFollowHighlight())
3140 af.viewport.followHighlight = view.getFollowHighlight();
3142 if (view.hasFollowSelection())
3144 af.viewport.followSelection = view.getFollowSelection();
3146 if (view.hasShowConsensusHistogram())
3148 af.viewport.setShowConsensusHistogram(view
3149 .getShowConsensusHistogram());
3153 af.viewport.setShowConsensusHistogram(true);
3155 if (view.hasShowSequenceLogo())
3157 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3161 af.viewport.setShowSequenceLogo(false);
3163 if (view.hasShowDbRefTooltip())
3165 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3167 if (view.hasShowNPfeatureTooltip())
3169 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3171 if (view.hasShowGroupConsensus())
3173 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3177 af.viewport.setShowGroupConsensus(false);
3179 if (view.hasShowGroupConservation())
3181 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3185 af.viewport.setShowGroupConservation(false);
3188 // recover featre settings
3189 if (jms.getFeatureSettings() != null)
3191 af.viewport.featuresDisplayed = new Hashtable();
3192 String[] renderOrder = new String[jms.getFeatureSettings()
3193 .getSettingCount()];
3194 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3196 Setting setting = jms.getFeatureSettings().getSetting(fs);
3197 if (setting.hasMincolour())
3199 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3200 new java.awt.Color(setting.getMincolour()),
3201 new java.awt.Color(setting.getColour()),
3202 setting.getMin(), setting.getMax()) : new GraduatedColor(
3203 new java.awt.Color(setting.getMincolour()),
3204 new java.awt.Color(setting.getColour()), 0, 1);
3205 if (setting.hasThreshold())
3207 gc.setThresh(setting.getThreshold());
3208 gc.setThreshType(setting.getThreshstate());
3210 gc.setAutoScaled(true); // default
3211 if (setting.hasAutoScale())
3213 gc.setAutoScaled(setting.getAutoScale());
3215 if (setting.hasColourByLabel())
3217 gc.setColourByLabel(setting.getColourByLabel());
3219 // and put in the feature colour table.
3220 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3221 setting.getType(), gc);
3225 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3227 new java.awt.Color(setting.getColour()));
3229 renderOrder[fs] = setting.getType();
3230 if (setting.hasOrder())
3231 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3232 setting.getType(), setting.getOrder());
3234 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3236 fs / jms.getFeatureSettings().getSettingCount());
3237 if (setting.getDisplay())
3239 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3240 setting.getColour()));
3243 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3245 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3246 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3248 Group grp = jms.getFeatureSettings().getGroup(gs);
3249 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3253 if (view.getHiddenColumnsCount() > 0)
3255 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3257 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3258 .getHiddenColumns(c).getEnd() // +1
3263 af.setMenusFromViewport(af.viewport);
3264 // TODO: we don't need to do this if the viewport is aready visible.
3265 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3267 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3268 reorderAutoannotation(af, al, autoAlan);
3272 private void reorderAutoannotation(AlignFrame af, Alignment al,
3273 ArrayList<JvAnnotRow> autoAlan)
3275 // copy over visualization settings for autocalculated annotation in the
3277 if (al.getAlignmentAnnotation() != null)
3280 * Kludge for magic autoannotation names (see JAL-811)
3282 String[] magicNames = new String[]
3283 { "Consensus", "Quality", "Conservation" };
3284 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3285 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3286 for (String nm : magicNames)
3288 visan.put(nm, nullAnnot);
3290 for (JvAnnotRow auan : autoAlan)
3292 visan.put(auan.template.label, auan);
3294 int hSize = al.getAlignmentAnnotation().length;
3295 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3296 for (int h = 0; h < hSize; h++)
3298 jalview.datamodel.AlignmentAnnotation jalan = al
3299 .getAlignmentAnnotation()[h];
3300 if (jalan.autoCalculated)
3302 JvAnnotRow valan = visan.get(jalan.label);
3305 // delete the auto calculated row from the alignment
3306 al.deleteAnnotation(al.getAlignmentAnnotation()[h], false);
3309 if (valan != nullAnnot)
3311 if (jalan != valan.template)
3313 // newly created autoannotation row instance
3314 // so keep a reference to the visible annotation row
3315 // and copy over all relevant attributes
3316 if (valan.template.graphHeight >= 0)
3319 jalan.graphHeight = valan.template.graphHeight;
3321 jalan.visible = valan.template.visible;
3323 reorder.add(new JvAnnotRow(valan.order, jalan));
3328 int s = 0, srt[] = new int[reorder.size()];
3329 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3330 for (JvAnnotRow jvar : reorder)
3333 srt[s++] = jvar.order;
3336 jalview.util.QuickSort.sort(srt, rws);
3337 // and re-insert the annotation at its correct position
3338 for (JvAnnotRow jvar : rws)
3340 al.addAnnotation(jvar.template, jvar.order);
3342 af.alignPanel.adjustAnnotationHeight();
3346 Hashtable skipList = null;
3349 * TODO remove this method
3352 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3353 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3354 * throw new Error("Implementation Error. No skipList defined for this
3355 * Jalview2XML instance."); } return (AlignFrame)
3356 * skipList.get(view.getSequenceSetId()); }
3360 * Check if the Jalview view contained in object should be skipped or not.
3363 * @return true if view's sequenceSetId is a key in skipList
3365 private boolean skipViewport(JalviewModel object)
3367 if (skipList == null)
3372 if (skipList.containsKey(id = object.getJalviewModelSequence()
3373 .getViewport()[0].getSequenceSetId()))
3375 if (Cache.log != null && Cache.log.isDebugEnabled())
3377 Cache.log.debug("Skipping seuqence set id " + id);
3384 public void AddToSkipList(AlignFrame af)
3386 if (skipList == null)
3388 skipList = new Hashtable();
3390 skipList.put(af.getViewport().getSequenceSetId(), af);
3393 public void clearSkipList()
3395 if (skipList != null)
3402 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3404 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3405 Vector dseqs = null;
3408 // create a list of new dataset sequences
3409 dseqs = new Vector();
3411 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3413 Sequence vamsasSeq = vamsasSet.getSequence(i);
3414 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3416 // create a new dataset
3419 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3420 dseqs.copyInto(dsseqs);
3421 ds = new jalview.datamodel.Alignment(dsseqs);
3422 debug("Created new dataset " + vamsasSet.getDatasetId()
3423 + " for alignment " + System.identityHashCode(al));
3424 addDatasetRef(vamsasSet.getDatasetId(), ds);
3426 // set the dataset for the newly imported alignment.
3427 if (al.getDataset() == null)
3436 * sequence definition to create/merge dataset sequence for
3440 * vector to add new dataset sequence to
3442 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3443 AlignmentI ds, Vector dseqs)
3445 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3447 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3448 .get(vamsasSeq.getId());
3449 jalview.datamodel.SequenceI dsq = null;
3450 if (sq != null && sq.getDatasetSequence() != null)
3452 dsq = (jalview.datamodel.SequenceI) sq.getDatasetSequence();
3455 String sqid = vamsasSeq.getDsseqid();
3458 // need to create or add a new dataset sequence reference to this sequence
3461 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3466 // make a new dataset sequence
3467 dsq = sq.createDatasetSequence();
3470 // make up a new dataset reference for this sequence
3471 sqid = seqHash(dsq);
3473 dsq.setVamsasId(uniqueSetSuffix + sqid);
3474 seqRefIds.put(sqid, dsq);
3479 dseqs.addElement(dsq);
3484 ds.addSequence(dsq);
3490 { // make this dataset sequence sq's dataset sequence
3491 sq.setDatasetSequence(dsq);
3495 // TODO: refactor this as a merge dataset sequence function
3496 // now check that sq (the dataset sequence) sequence really is the union of
3497 // all references to it
3498 // boolean pre = sq.getStart() < dsq.getStart();
3499 // boolean post = sq.getEnd() > dsq.getEnd();
3503 StringBuffer sb = new StringBuffer();
3504 String newres = jalview.analysis.AlignSeq.extractGaps(
3505 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3506 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3507 && newres.length() > dsq.getLength())
3509 // Update with the longer sequence.
3513 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3514 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3515 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3516 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3518 dsq.setSequence(sb.toString());
3520 // TODO: merges will never happen if we 'know' we have the real dataset
3521 // sequence - this should be detected when id==dssid
3522 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3523 // + (pre ? "prepended" : "") + " "
3524 // + (post ? "appended" : ""));
3529 java.util.Hashtable datasetIds = null;
3531 java.util.IdentityHashMap dataset2Ids = null;
3533 private Alignment getDatasetFor(String datasetId)
3535 if (datasetIds == null)
3537 datasetIds = new Hashtable();
3540 if (datasetIds.containsKey(datasetId))
3542 return (Alignment) datasetIds.get(datasetId);
3547 private void addDatasetRef(String datasetId, Alignment dataset)
3549 if (datasetIds == null)
3551 datasetIds = new Hashtable();
3553 datasetIds.put(datasetId, dataset);
3557 * make a new dataset ID for this jalview dataset alignment
3562 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3564 if (dataset.getDataset() != null)
3566 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3568 String datasetId = makeHashCode(dataset, null);
3569 if (datasetId == null)
3571 // make a new datasetId and record it
3572 if (dataset2Ids == null)
3574 dataset2Ids = new IdentityHashMap();
3578 datasetId = (String) dataset2Ids.get(dataset);
3580 if (datasetId == null)
3582 datasetId = "ds" + dataset2Ids.size() + 1;
3583 dataset2Ids.put(dataset, datasetId);
3589 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3591 for (int d = 0; d < sequence.getDBRefCount(); d++)
3593 DBRef dr = sequence.getDBRef(d);
3594 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3595 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3596 .getVersion(), sequence.getDBRef(d).getAccessionId());
3597 if (dr.getMapping() != null)
3599 entry.setMap(addMapping(dr.getMapping()));
3601 datasetSequence.addDBRef(entry);
3605 private jalview.datamodel.Mapping addMapping(Mapping m)
3607 SequenceI dsto = null;
3608 // Mapping m = dr.getMapping();
3609 int fr[] = new int[m.getMapListFromCount() * 2];
3610 Enumeration f = m.enumerateMapListFrom();
3611 for (int _i = 0; f.hasMoreElements(); _i += 2)
3613 MapListFrom mf = (MapListFrom) f.nextElement();
3614 fr[_i] = mf.getStart();
3615 fr[_i + 1] = mf.getEnd();
3617 int fto[] = new int[m.getMapListToCount() * 2];
3618 f = m.enumerateMapListTo();
3619 for (int _i = 0; f.hasMoreElements(); _i += 2)
3621 MapListTo mf = (MapListTo) f.nextElement();
3622 fto[_i] = mf.getStart();
3623 fto[_i + 1] = mf.getEnd();
3625 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3626 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3627 if (m.getMappingChoice() != null)
3629 MappingChoice mc = m.getMappingChoice();
3630 if (mc.getDseqFor() != null)
3632 String dsfor = "" + mc.getDseqFor();
3633 if (seqRefIds.containsKey(dsfor))
3638 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3642 frefedSequence.add(new Object[]
3649 * local sequence definition
3651 Sequence ms = mc.getSequence();
3652 jalview.datamodel.Sequence djs = null;
3653 String sqid = ms.getDsseqid();
3654 if (sqid != null && sqid.length() > 0)
3657 * recover dataset sequence
3659 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3664 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3665 sqid = ((Object) ms).toString(); // make up a new hascode for
3666 // undefined dataset sequence hash
3667 // (unlikely to happen)
3673 * make a new dataset sequence and add it to refIds hash
3675 djs = new jalview.datamodel.Sequence(ms.getName(),
3677 djs.setStart(jmap.getMap().getToLowest());
3678 djs.setEnd(jmap.getMap().getToHighest());
3679 djs.setVamsasId(uniqueSetSuffix + sqid);
3681 seqRefIds.put(sqid, djs);
3684 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3693 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3694 boolean keepSeqRefs)
3697 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3703 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3707 uniqueSetSuffix = "";
3708 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3713 if (this.frefedSequence == null)
3715 frefedSequence = new Vector();
3718 viewportsAdded = new Hashtable();
3720 AlignFrame af = LoadFromObject(jm, null, false, null);
3721 af.alignPanels.clear();
3722 af.closeMenuItem_actionPerformed(true);
3725 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3726 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3727 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3728 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3729 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3732 return af.alignPanel;
3736 * flag indicating if hashtables should be cleared on finalization TODO this
3737 * flag may not be necessary
3739 private boolean _cleartables = true;
3741 private Hashtable jvids2vobj;
3746 * @see java.lang.Object#finalize()
3748 protected void finalize() throws Throwable
3750 // really make sure we have no buried refs left.
3755 this.seqRefIds = null;
3756 this.seqsToIds = null;
3760 private void warn(String msg)
3765 private void warn(String msg, Exception e)
3767 if (Cache.log != null)
3771 Cache.log.warn(msg, e);
3775 Cache.log.warn(msg);
3780 System.err.println("Warning: " + msg);
3783 e.printStackTrace();
3788 private void debug(String string)
3790 debug(string, null);
3793 private void debug(String msg, Exception e)
3795 if (Cache.log != null)
3799 Cache.log.debug(msg, e);
3803 Cache.log.debug(msg);
3808 System.err.println("Warning: " + msg);
3811 e.printStackTrace();
3817 * set the object to ID mapping tables used to write/recover objects and XML
3818 * ID strings for the jalview project. If external tables are provided then
3819 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3820 * object goes out of scope. - also populates the datasetIds hashtable with
3821 * alignment objects containing dataset sequences
3824 * Map from ID strings to jalview datamodel
3826 * Map from jalview datamodel to ID strings
3830 public void setObjectMappingTables(Hashtable vobj2jv,
3831 IdentityHashMap jv2vobj)
3833 this.jv2vobj = jv2vobj;
3834 this.vobj2jv = vobj2jv;
3835 Iterator ds = jv2vobj.keySet().iterator();
3837 while (ds.hasNext())
3839 Object jvobj = ds.next();
3840 id = jv2vobj.get(jvobj).toString();
3841 if (jvobj instanceof jalview.datamodel.Alignment)
3843 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
3845 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
3848 else if (jvobj instanceof jalview.datamodel.Sequence)
3850 // register sequence object so the XML parser can recover it.
3851 if (seqRefIds == null)
3853 seqRefIds = new Hashtable();
3855 if (seqsToIds == null)
3857 seqsToIds = new IdentityHashMap();
3859 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
3860 seqsToIds.put(jvobj, id);
3862 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
3864 if (annotationIds == null)
3866 annotationIds = new Hashtable();
3869 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
3870 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
3871 if (jvann.annotationId == null)
3873 jvann.annotationId = anid;
3875 if (!jvann.annotationId.equals(anid))
3877 // TODO verify that this is the correct behaviour
3878 this.warn("Overriding Annotation ID for " + anid
3879 + " from different id : " + jvann.annotationId);
3880 jvann.annotationId = anid;
3883 else if (jvobj instanceof String)
3885 if (jvids2vobj == null)
3887 jvids2vobj = new Hashtable();
3888 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
3892 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
3897 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
3898 * objects created from the project archive. If string is null (default for
3899 * construction) then suffix will be set automatically.
3903 public void setUniqueSetSuffix(String string)
3905 uniqueSetSuffix = string;
3910 * uses skipList2 as the skipList for skipping views on sequence sets
3911 * associated with keys in the skipList
3915 public void setSkipList(Hashtable skipList2)
3917 skipList = skipList2;